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"'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.

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

редактировать

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

5 ответов

Спасибо Стефану - редактирование в конце вашего вопроса помогло мне "исправить" ту же проблему. Для всех, кто также это ударит - вот расширенный ответ. Вот что вам нужно, чтобы "исправить" вещи в вашей поме (пока Eclipse не исправит все правильно):

<!-- See https://stackru.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 банка подписана в то время как 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, Этот jar вытягивается, когда какая-то часть моего приложения (на самом деле что-то глубоко в 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.

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

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

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

Эта странная ситуация, кажется, все еще существует, в моем случае я не использую 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).

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

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

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

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам