EclipseLink 2.7.0 и JPA API 2.2.0 - несоответствие подписи

При запуске проекта, созданного 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" 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 класс аннотации.

Как это можно зафиксировать?

Edit

Замена javax.persistence artifact версии 2.2.0 на версию 2.1.1 устраняет проблему (этот не подписан), но я не уверен, что это нормальная ситуация.

Ответ 1

Спасибо 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 version 2.2.0 явно втягивается в фрагмент pom, указанный в исходном вопросе, несмотря на то, что уже является транзитивной зависимостью eclipselink.

Описание

Сводка - артефакт eclipselink зависит от javax.persistence, и оба содержат классы, которые находятся в пакете javax.persistence. Однако флажок javax.persistence подписан, а eclipselink - нет. Таким образом, среда выполнения Java будет жаловаться при загрузке класса из пакета javax.persistence в банке eclipselink, что отсутствие подписи не соответствует классам, уже загруженным из одного пакета в банке javax.persistence.

Подробности - если я положил точку останова в 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.

Если затем поставить точку останова в 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 - см. ошибку 525457.

Ответ 2

Чтобы устранить эту проблему, установите правильную зависимость JPA 2.2 для EclipseLink 2.7.x в вашем файле maven mom, как:

<dependency>
    <groupId>org.eclipse.persistence</groupId>
    <artifactId>org.eclipse.persistence.jpa</artifactId>
    <version>2.7.1</version>
</dependency>

Ответ 3

eclipselink.jar как таковой разработан как пакет "все-в-одном", а не osgi enabled jar, содержащий весь проект partsof eclipselink (т.е. sdo, oracle db specific stuff, dbws, nosql..) с возможностью запуска с jpa api 2.0 на пути к классам - по крайней мере, в версиях 2.x. Во многих случаях это не требуется, и вместо этого можно использовать соответствующие компоненты, такие как org.eclipse.persistence.jpa, org.eclipse.persistence.oracle и т.д. Полный список см. В следующем виде: http://search.maven.org/#search%7Cga%7C1%7Corg.eclipse.persistence

Ответ 4

Я исправил это, переключив порядок, в котором банки появляются в пути к классам. В моем случае я использую Tomcat и должен был изменить свойства catalina.properties, чтобы поставить javax перед eclipselink.

Ответ 5

Ответ Обинны правильный; Я предполагаю, что возникла проблема с eclipselink 2.7.x, - указал Джордж. У меня была аналогичная проблема при обновлении eclipselink, но это были просто неправильные артефакты. Первоначально описанная проблема, по-видимому, является результатом внешнего ссылки на уровень javax.persistence - это определенно не обязательно.

Правильную конфигурацию maven можно найти в eclipselink wiki: https://wiki.eclipse.org/EclipseLink/Maven

Ответ 6

Эта странная ситуация, кажется, все еще существует, в моем случае я не использую Maven, просто пытаюсь запустить простой пример JPA (и это действительно расстраивает, если вам нужны часы, чтобы просто достичь этого).

В версии 2.7.4 от января эта ошибка возникает, если вы положили eclipselink.jar и jakarta.persistence_2.2.2.jar из zip файла на путь к классам.

В конце концов решение состояло в том, чтобы изменить порядок на пути к классам: сначала постоянство джакарты, а затем - банку затмения. Таким образом, все классы javax.persistence взяты из jakarta-jar, а не частично из eclipselink-jar (если он там есть).

Поэтому я действительно удивляюсь различным вещам.

Пакет eclipselink должен быть все-в-одном? Но это не так. Некоторые классы javax.persistence содержатся. Другие нет - базовые классы, которые будут использоваться в коде JPA, например EntityManager. Конечно, вместе с jakarta-jar, включенным в почтовый индекс, оно завершено - но вы не можете использовать две банки вместе с "неправильным" порядком на пути к классам !? Я действительно считаю это ошибкой - или, по крайней мере, тогда в пакете должен быть ОГРОМНЫЙ намек на это.

Что такое org.eclipse.persistence.jpa-2.7.4.jar от Maven, который предлагается здесь? У него нет проблем с eclipselink.jar, да, а не это сообщение об ошибке. Но тогда он также, похоже, просто не включает реализацию Eclipselink JPA, по крайней мере, работая с ним, я получил ошибку, что модуль постоянства, на который есть ссылка в коде, не существует (тот же файл persistence.xml, работающий с eclipselink.jar).

Странная ситуация.

Ответ 7

Мой проект работал на 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'

Ответ 8

Я также сталкиваюсь с этой проблемой, поскольку мой случай немного отличается от того, что я не использую Maven. Тем не менее, я помещаю здесь ответ, так как это может дать людям представление о том, как справиться с этим в их собственной ситуации. В конце концов, название относится к этому несоответствию, в общем, к одному подзабору при использовании Maven.

Я использую eclipselink в проекте NetBeans. Первоначально я размещал как файл eclipselink jar (eclipselink-2.7.0.jar), так и необходимые файлы jar org.eclipse.persistence в качестве внешних библиотек для моего проекта. Комментарии Сергея и entreprenr выше - это то, что на самом деле заставило меня решить мою проблему. Мне нужно было создать новую библиотеку (Tools-> Libraries-> New Library...), которая не содержит файл eclipselink-2.7.0.jar (например, eclipselink-2.7.0.jar не добавляется в библиотеку), только конкретные файлы jar org.eclipse.persistence, необходимые для проекта, например 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 и т.д. Затем я добавил эту библиотеку к своему проект, и исключение исчезло.

Конечно, мне также пришлось заменить все файлы jar org.eclipse.persistence на моем сервере с их версией 2.7.0, а также заменить javax.persistence.jar на версию 2.2.0 (я использую payara, поэтому они находятся под <payara_home>\glassfish\modules).

Ответ 9

Я использую 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'
}

Я думаю, что последнее является лучшим решением.

Ответ 10

Поскольку я не мог найти ответ на эту проблему, когда использовал только Tomcat, и эта тема часто связана с этой проблемой, я собираюсь опубликовать свое решение здесь:

Поскольку подпись находится в файле MANIFEST.MF, вы можете изменить подписи в файлах .jar с помощью 7zip или WinRAR, чтобы открыть их, или просто удалить их из файлов META-INF обоих файлов .jar, а затем импортировать измененные файлы в вашу среду IDE.

Полезным потоком для проблемы Signature-Mismatch-Problem является этот поток: Java SecurityException: информация подписавшего не совпадает