运行由maven构建的具有以下依赖项的项目时:
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.7.0</version>
</dependency>
我在运行时收到以下错误:
java.lang.SecurityException: class "javax.persistence.Cacheable"'s signer information does not match signer information of other classes in the same package
javax.persistence-2.2.0工件已签名并包含javax.persistence.Cacheable.class注释,而eclipselink-2.7.0工件未签名且包含相同的java类注释。
怎么解决这个问题?
编辑
用版本2.1.1替换javax.persistence artifact 2.2.0版修复了问题(这个没有签名),但我不确定这是正常情况。
谢谢Stéphane - 问题末尾的编辑帮助我“修复”了同样的问题。对于其他人来说也是如此 - 这是一个扩展的答案。这就是你需要“修复”pom中的东西(直到Eclipse正确修复):
<!-- See https://stackoverflow.com/q/45870753 -->
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.7.0</version>
<exclusions>
<exclusion>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>2.1.1</version>
</dependency>
这引入了eclipselink
,但排除了它试图引入的javax.persistence
依赖,并将其替换为没有签名问题的早期版本的javax.persistence
。
除此之外:javax.persistence
版本2.2.0
明确地被引入原始问题中显示的pom片段,尽管已经是eclipselink
的传递依赖。
总结 - eclipselink
工件依赖于javax.persistence
,并且都包含javax.persistence
包中的类。然而,javax.persistence
jar是签名而eclipselink
jar不是。因此,当从javax.persistence
jar中的eclipselink
包加载一个类时,Java运行时会抱怨它缺少签名与已经从javax.persistence
jar中的同一个包加载的类不匹配。
详细信息 - 如果我在条件java.util.concurrent.ConcurrentHashMap.putIfAbsent(K, V)
的"javax.persistence".equals(arg0)
中放置断点,那么我看到javax.persistence
映射到以下CodeSource
值:
(file:/Users/georgehawkins/.m2/repository/org/eclipse/persistence/javax.persistence/2.2.0/javax.persistence-2.2.0.jar [
[
Version: V3
Subject: CN="Eclipse Foundation, Inc.", OU=IT, O="Eclipse Foundation, Inc.", L=Ottawa, ST=Ontario, C=CA
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11
...
即javax.persistence-2.2.0.jar
由Eclipse Foundation签名,包含javax.persistence
包中的类。当我的应用程序的某些部分(实际上是Spring逻辑中的某些东西)试图加载javax.persistence.EntityManagerFactory
时,这个jar被拉入。
如果我然后在java.lang.ClassLoader.checkCerts(String, CodeSource)
线上的throw new SecurityException
中设置一个断点,那么当它传入CodeSource
时它会看到它击中了这一行:
(file:/Users/georgehawkins/.m2/repository/org/eclipse/persistence/eclipselink/2.7.0/eclipselink-2.7.0.jar <no signer certificates>)
即eclipselink-2.7.0.jar
也包含在javax.persistence
包中的类,但它是无符号的,因此发生冲突导致SecurityException
被抛出。当某些事情(也在Spring逻辑深处)试图加载javax.persistence.PersistenceUtil
时会发生这种情况。
如果我看看mvn dependency:tree
的输出,我看到这种不匹配似乎是由于eclipselink
本身 - 它正在拉动org.eclipse.persistence:javax.persistence:jar:2.2.0
本身。即它不是与其他一些依赖的冲突:
[INFO] | \- org.eclipse.persistence:eclipselink:jar:2.7.0:compile
[INFO] | +- org.eclipse.persistence:javax.persistence:jar:2.2.0:compile
[INFO] | +- org.eclipse.persistence:commonj.sdo:jar:2.1.1:compile
[INFO] | +- javax.validation:validation-api:jar:1.1.0.Final:compile
[INFO] | \- org.glassfish:javax.json:jar:1.0.4:compile
我现在已经在bugs.eclipse.org上记录了这个 - 请参阅bug 525457。
因为当只使用Tomcat并且这个线程经常与这个问题相关联时,我找不到这个问题的答案,我将在这里发布我的解决方案:
由于签名位于MANIFEST.MF中,您可以使用7zip或WinRAR更改.jar文件中的签名以打开它们,或者只是从.jar的META-INF文件中删除它们,然后将更改的文件导入IDE。
Signature-Mismatch-Problem的一个有用的线程就是这个帖子:Java SecurityException: signer information does not match
要解决此问题,请在maven pom文件中为EclipseLink 2.7.x添加正确的JPA 2.2兼容依赖项,如下所示:
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>2.7.1</version>
</dependency>
eclipselink.jar本身被设计为一体化的捆绑包,而不是osgi启用的jar包含eclipselink项目的所有部分(即sdo,oracle db特定的东西,dbws,nosql ..),能够在类路径上运行jpa api 2.0 - 至少在2.x版本中。在许多情况下,这不是必需的,可以使用适当的组件,例如org.eclipse.persistence.jpa,org.eclipse.persistence.oracle等。有关完整列表,请参阅ie:http://search.maven.org/#search%7Cga%7C1%7Corg.eclipse.persistence
我通过切换jar在类路径中出现的顺序来解决这个问题。就我而言,我正在使用Tomcat并且必须修改catalina.properties以在eclipselink之前放置javax。
奥宾娜的回答是正确的;我想,eclipselink 2.7.x存在问题 - 乔治表示。升级eclipselink时我遇到了类似的问题,但这只是错误的人工制品。最初描述的问题似乎是外部引用javax.persistence级别的结果 - 它绝对没有必要。
正确的maven配置可以在eclipselink wiki:https://wiki.eclipse.org/EclipseLink/Maven中找到
这种奇怪的情况似乎仍然存在,在我不使用Maven的情况下,只是试图让一个简单的JPA示例运行(如果你只需要几个小时来实现它就真的很令人沮丧)。
从1月份的2.7.4开始,如果您从类路径上的zip中放入eclipselink.jar和jakarta.persistence_2.2.2.jar,则会发生此错误。
最后的解决方案是改变类路径上的顺序:首先是jakarta-persistence,然后才是eclipselink-jar。因此,所有javax.persistence类都取自jakarta-jar而不是eclipselink-jar(如果包含在那里)。
所以我真的很想知道各种事情。
eclipselink软件包应该是一体机吗?但事实并非如此。包含一些javax.persistence类。其他不 - 在像EntityManager这样的JPA代码中使用的基本类。当然,与拉链中包含的jakarta-jar一起完成 - 但你可能不会在类路径上使用两个罐子和“错误”的顺序!我真的认为这是一个错误 - 或者至少在包中应该有一个巨大的暗示。
这里建议来自Maven的org.eclipse.persistence.jpa-2.7.4.jar是什么?它没有eclipselink.jar的问题,是的,不是这个错误信息。但是它似乎也没有包含Eclipselink JPA实现,至少运行它我得到错误,代码中引用的持久性单元不存在(与eclipselink.jar一样的persistence.xml)。
奇怪的情况。
我的项目正在开发JDK-8,但当我将它升级到openJDK-11时停止工作。我解决了它除了jpa-persistence
模块,并再次添加版本2.2
:
dependencies.create('org.eclipse.persistence:eclipselink:2.7.4') {
exclude module: "javax.persistence"
},
'javax.persistence:javax.persistence-api:2.2', //add it again, manually
'org.eclipse.persistence:org.eclipse.persistence.asm:2.7.4',
'org.eclipse.persistence:org.eclipse.persistence.antlr:2.7.4',
'org.eclipse.persistence:org.eclipse.persistence.moxy:2.7.4',
'org.eclipse.persistence:org.eclipse.persistence.core:2.7.4'
我也遇到了这个问题,我的情况有点不同,因为我没有使用Maven。但是,我在这里给出答案,因为它可能会让人们了解如何在自己的情况下处理这个问题。毕竟,标题是关于这种不匹配,一般来说,一个子案例是在使用Maven时。
我在NetBeans项目中使用eclipselink。最初,我将eclipselink jar文件(eclipselink-2.7.0.jar
)和所需的org.eclipse.persistence jar文件作为外部库放置到我的项目中。上面的Sergey和entreprenr的评论实际上是我解决问题的原因。我要做的是创建一个新的库(Tools-> Libraries-> New Library ...),它不包含eclipselink jar文件(即库中没有添加eclipselink-2.7.0.jar
),只有特定的org.eclipse.persistence项目所必需的jar文件,例如org.eclipse.persistence.antlr-2.7.0.jar
,org.eclipse.persistence.asm-2.7.0.jar
,org.eclipse.persistence.core-2.7.0.jar
,org.eclipse.persistence.jpa.modelgen.processor-2.7.0.jar
,org.eclipse.persistence.jpa-2.7.0.jar
等。然后我将这个库添加到我的项目中,异常消失了。
当然,我还必须用他们的2.7.0版本替换我服务器上的所有org.eclipse.persistence jar文件,并用它的2.2.0版本替换javax.persistence.jar
(我使用payara,因此它们位于<payara_home>\glassfish\modules
下)。
我在我的项目构建中使用gradle并解决OP的问题,我也有,我最后使用了以下工作设置。
dependencies {
testImplementation(group: 'org.eclipse.persistence', name: 'eclipselink', version: '2.7.4') {
exclude group: 'javax.validation', module: 'validation-api'
exclude group: 'org.eclipse.persistence', module: 'javax.persistence'
exclude group: 'org.eclipse.persistence', module: 'commonj.sdo'
exclude group: 'org.eclipse.persistence', module: 'jakarta.persistence'
}
testImplementation(group: 'org.eclipse.persistence', name: 'org.eclipse.persistence.jpa', version: '2.7.4') {
exclude group: 'org.eclipse.persistence', module: 'jakarta.persistence'
}
}
您可以使用您想要或需要的任何依赖类型,而不是“testImplementation”。
阅读谢尔盖的评论后,我通过使用以下方式改进了这一点:
dependencies {
testImplementation group: 'org.eclipse.persistence', name: 'org.eclipse.persistence.jpa', version: '2.7.4'
}
我认为最后一个是最好的解决方案。