Как использовать банку с Spring в качестве упакованной зависимости в другом проекте Spring с более высокой версией Spring?

Существует множество вопросов о том, как добавить один весенний проект в качестве зависимости в другой весенний проект. Но то, что я ищу, - это решение конкретной проблемы после того, как мы успешно ответили на часть «Как».

Скажем, у нас есть два многомодульных проекта maven на основе Spring. Проект-А и Проект-Б. Версия SpringFramework, используемая в Project-A, — 4.2.3. Некоторые модули из Project-A объединены и встроены в uber-jar с помощью шейд-плагина с НЕТ особой конфигурации. Это означает, что если я открою uber-jar, я смогу найти все зависимости (я думаю, даже транзитивные зависимости), упакованные в uber-jar. (Конечно, это может быть некрасиво, но я не могу изменить этот uber-jar. О рефакторинге и разбиении его на более мелкие потребляемые зависимости не может быть и речи по причинам x, y, z). Доступ к базовым ресурсам осуществляется через API, который предоставляет один из модулей в uber-jar. Так что я застрял с этим.

Теперь я хочу использовать этот uber-jar из проекта-A в качестве зависимости в проекте-B. Я использовал плагин установки и прикрепил установку этого uber-jar на этапе проверки.

Однако в Project-B я хочу использовать spring-data- jdbc. Итак, spring-data-jdbc — довольно новый проект, и, как описано здесь в справочном документе минимальная требуемая версия spring-framework — 5.2.6.RELEASE.

Поэтому, когда я добавил uber-jar в качестве зависимости, хотя я мог выполнить успешную чистую установку maven, я столкнулся с некоторыми NoSuchMethodException вроде этого: java.lang.nosuchmethoderror:org.springframework.util.reflectionutils.accessibleconstructor(ljava/lang/class;[ljava/lang/class;) когда артефакт был развернут в tomcat 8.5

Что похоже на проблему, описанную в этом вопросе. Поэтому, используя плагин зависимостей maven, я просмотрел дерево зависимостей Project-B, но не увидел в списке весеннюю версию 4.2.3. В uber-jar не было указано никаких транзитивных зависимостей.

Я даже просмотрел путь к классам сборки для разных целей и все же смог найти только весеннюю версию 5.2.6.RELEASE из Project-B. Однако совершенно очевидно, что во время развертывания я использую только spring-farmework 4.2.3 из uber-jar. Поскольку метод, который невозможно найти, доступен только начиная с версии Spring 5.0, как описано в java-doc здесь

Обновление весенней версии Project-A невозможно (опять же по причинам x, y, z). Я пытался исключить все зависимости из uber-jar при добавлении uber-jar в качестве зависимости, но это не помогло.

Вопросы:

  1. Можем ли мы указать проекту-B использовать зависимость spring-framework (5.2.6.RELEASE) своего проекта и не использовать зависимость из uber-jar, позволяя классам из проекта-A (в uber jar) использовать spring-framework упаковано в убер-банку?
  2. Неудобно даже задавать вопрос выше, потому что я думаю, что знаю, что обе версии добавляются в путь к классу. И во время развертывания контейнер подбирает первое, что он видит, вызывающее эту проблему. Это правильно?
  3. Как в модели, которую я описал (например, создание uber-jar), работает управление зависимостями? Это означает, что, поскольку я вижу все зависимости, упакованные в uber-jar, когда я использую этот uber-jar в качестве зависимости, все ли упакованные зависимости (jars) также добавляются в путь к классам потребляющих проектов?
  4. Я (maven) устанавливаю uber-jar при сборке проекта-b на этапе проверки, а затем компилирую проект-b, что вызывает проблему?
  5. Если это запутанная ситуация, могу ли я получить рекомендацию по альтернативе spring-data-jdbc? так что я могу полностью отказаться от идеи использования более высокой весенней версии в проекте-b. Мне не нужны все функции Java Persistence API, такие как отложенная загрузка, кэширование и все такое. Я просто хочу использовать шаблон репозитория, чтобы легко выполнять некоторые операции CRUD с простым управлением транзакциями, поэтому я выбрал spring-data-jdbc.

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

Обновление: Таким образом, дерево зависимостей будет выглядеть следующим образом:

  • Project-A, дерево зависимостей модуля Uber-Jar
org.railomaya.uberJarModule:uberJar:jar:2.0
[INFO] +- org.railomaya:OtherModule_1:jar:2.0
[INFO] \- org.railomaya:OtherModule_2:jar:1.0:compile
[INFO] +- org.railomaya:otherModule_3:jar:1.0-SNAPSHOT:compile
[INFO] |  +- org.springframework:spring-jms:jar:4.2.3.RELEASE:compile
[INFO] |  |  +- org.springframework:spring-messaging:jar:4.2.3.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-tx:jar:4.2.3.RELEASE:compile
[INFO] |  \- org.apache.activemq:activemq-spring:jar:5.13.2:compile
[INFO] +- org.springframework:spring-context-support:jar:4.2.3.RELEASE:compile
[INFO] |  +- org.springframework:spring-beans:jar:4.2.3.RELEASE:compile
[INFO] |  +- org.springframework:spring-context:jar:4.2.3.RELEASE:compile
[INFO] |  |  +- org.springframework:spring-aop:jar:4.2.3.RELEASE:compile
[INFO] |  |  |  \- aopalliance:aopalliance:jar:1.0:compile
[INFO] |  |  \- org.springframework:spring-expression:jar:4.2.3.RELEASE:compile
[INFO] |  \- org.springframework:spring-core:jar:4.2.3.RELEASE:compile
[INFO] |     \- commons-logging:commons-logging:jar:1.2:compile
[INFO] +- org.springframework.boot:spring-boot-starter:jar:1.5.1.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot:jar:1.5.1.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-autoconfigure:jar:1.5.1.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-logging:jar:1.5.1.RELEASE:compile
[INFO] |  |  +- ch.qos.logback:logback-classic:jar:1.1.9:compile
[INFO] |  |  |  \- ch.qos.logback:logback-core:jar:1.1.9:compile
[INFO] |  |  +- org.slf4j:jcl-over-slf4j:jar:1.7.22:compile
[INFO] |  |  +- org.slf4j:jul-to-slf4j:jar:1.7.22:compile
[INFO] |  |  \- org.slf4j:log4j-over-slf4j:jar:1.7.22:compile
[INFO] |  \- org.yaml:snakeyaml:jar:1.17:runtime
[INFO] +- org.springframework:spring-test:jar:4.2.3.RELEASE:test
[INFO] +- javax.servlet:servlet-api:jar:2.5:compile
[INFO] +- org.apache.commons:commons-lang3:jar:3.3.1:compile
[INFO] +- commons-io:commons-io:jar:2.4:compile

Дерево зависимостей Project-B, где указанный выше uber-jar используется в качестве зависимости:

org.railomaya:project-B:war:2.0-SNAPSHOT
[INFO] +- org.railomaya.uberJarModule:uberJar:jar:2.0:compile
[INFO] +- org.apache.commons:commons-dbcp2:jar:2.0.1:compile
[INFO] |  \- commons-logging:commons-logging:jar:1.1.3:compile
[INFO] +- org.apache.commons:commons-pool2:jar:2.2:compile
[INFO] +- org.apache.logging.log4j:log4j-api:jar:2.1:compile
[INFO] +- org.apache.logging.log4j:log4j-core:jar:2.1:compile
[INFO] +- org.apache.logging.log4j:log4j-web:jar:2.1:compile
[INFO] +- javax.mail:mail:jar:1.4.5:compile
[INFO] |  \- javax.activation:activation:jar:1.1:compile
[INFO] +- javax.servlet:servlet-api:jar:2.5:provided
[INFO] +- mysql:mysql-connector-java:jar:5.1.26:compile
[INFO] +- org.quartz-scheduler:quartz:jar:2.2.1:compile
[INFO] |  +- c3p0:c3p0:jar:0.9.1.1:compile
[INFO] |  \- org.slf4j:slf4j-api:jar:1.6.6:compile
[INFO] +- org.springframework:spring-beans:jar:5.2.6.RELEASE:compile
[INFO] +- org.springframework:spring-context:jar:5.2.6.RELEASE:compile
[INFO] |  \- org.springframework:spring-aop:jar:5.2.6.RELEASE:compile
[INFO] +- org.springframework:spring-context-support:jar:5.2.6.RELEASE:compile
[INFO] +- org.springframework:spring-core:jar:5.2.6.RELEASE:compile
[INFO] |  \- org.springframework:spring-jcl:jar:5.2.6.RELEASE:compile
[INFO] +- org.springframework:spring-expression:jar:5.2.6.RELEASE:compile
[INFO] +- org.springframework:spring-jdbc:jar:5.2.6.RELEASE:compile
[INFO] +- org.springframework:spring-test:jar:5.2.6.RELEASE:test
[INFO] +- org.springframework:spring-tx:jar:5.2.6.RELEASE:compile
[INFO] +- org.springframework:spring-web:jar:5.2.6.RELEASE:compile
[INFO] \- org.springframework:spring-webmvc:jar:5.2.6.RELEASE:compile

person railomaya    schedule 03.05.2020    source источник
comment
Нет, ты не можешь. поскольку один раз в банке проекта b всегда будет иметь приоритет. Так что, если вы не разорвете эту банку, вы мало что сможете с этим поделать.   -  person M. Deinum    schedule 03.05.2020
comment
@ M.Deinum ... поскольку файлы в банке проекта b всегда будут иметь приоритет ... - Проблема в том, что этого не происходит. Хотя это то, чего я желаю, но происходит противоположное. Я обновил вопрос макетом дерева зависимостей. Вы можете видеть, что проект-A имеет зависимости от spring-4.2.3. В то время как проект-B имеет зависимости от spring-5.2.6. Однако во время выполнения загружаются классы Spring 4.2.3.   -  person railomaya    schedule 03.05.2020
comment
Как уже говорилось, uberjar (который, как я думал, был Project B) будет иметь приоритет из-за включенных банок (заштрихованная uber-jar). Кроме того, если это сработает, все сломается, поскольку по какой-то причине это зависит от этой версии, поэтому либо ваш Spirng Data JDBC сломается (из-за использования более старой версии Spring), либо ваш проект A сломается из-за слишком новой версии Spring. В любом случае вы находитесь в для езды.   -  person M. Deinum    schedule 04.05.2020


Ответы (1)


Можем ли мы указать проекту-B использовать зависимость spring-framework (5.2.6.RELEASE) своего проекта и не использовать зависимость из uber-jar, позволяя классам из проекта-A (в uber jar) использовать spring-framework упаковано в убер-банку?

Не легко. Смотри ниже.

Кажется, я знаю, что обе версии добавляются в путь к классам. И во время развертывания контейнер подбирает первое, что он видит, вызывающее эту проблему. Это правильно?

Да.

когда я использую этот uber-jar в качестве зависимости, все ли упакованные зависимости (jars) также добавляются в путь к классам потребляющих проектов?

Да.

Я (maven) устанавливаю uber-jar при сборке проекта-b на этапе проверки, а затем компилирую проект-b, что вызывает проблему?

Да.

Если это запутанная ситуация, могу ли я получить рекомендацию по альтернативе spring-data-jdbc?

Вы всегда можете использовать Springs JdbcTemplate и самостоятельно реализовать свои репозитории, используя его. Вы даже можете подумать о моделировании агрегатов, как это делает Spring Data JDBC.

Вернемся к первому вопросу:

Во-первых, давайте проясним, что нет никакой гарантии, что Project A будет работать с более новой версией Spring, но давайте предположим, что это так.

Что вам нужно, так это разобрать ueber-jar, т.е. удалить все, что не является самим проектом A, и установить это в свой репозиторий maven, а затем зависеть от этого, а также от правильной версии (TM) Spring и все другие зависимости.

person Jens Schauder    schedule 03.05.2020
comment
Спасибо. Я думаю, что разбивать Project-A на части - это немного не в тему. Это похоже на гигантский монолит, который я унаследовал, и на какое-то время я застрял в нем. Но да, по крайней мере, когда я, наконец, доберусь до последней версии Spring Framework, я знаю, что это должно произойти. - person railomaya; 03.05.2020
comment
Я думаю, может быть, я мог бы использовать Hibernate ORM в качестве зависимости в Project-B для управления доступом к данным? В основном я пытаюсь избежать написания всего стандартного кода для сопоставления строк, а также использования необработанных запросов sql (насколько это возможно). Таким образом, все операции с базой данных, выполняемые проектом B, могут выполняться через спящий режим, и я по-прежнему могу использовать uber-jar для связи с другим приложением через предоставляемые им интерфейсы. - person railomaya; 04.05.2020