【问题标题】:Adding JAR file as dependency to project without its related JARs将 JAR 文件作为依赖项添加到项目中,而无需其相关 JAR
【发布时间】:2019-06-04 23:30:04
【问题描述】:

我们有使用 Spring Framework 3.1.2 开发的文件 payment.jar。我们需要将它用作对版本为 Spring Framework 5.x 的新项目的依赖。

问题:当payment.jar 用作依赖项时,payment.jar 传递依赖项会添加到项目类路径中,因此会导致 Spring Framework 3Spring Framework 5 冲突>.

我尝试了解决方案:

  1. 大肥罐

create-an-executable-jar-with-dependencies-using-maven

没有成功,胖JAR,将Spring Framework 3添加到项目中。 (我做错了什么!)

  1. 新项目中不包括支付 Spring Framework 3.1.2 依赖

因为在payment.jar 中使用了spring-ibatis 实现,所以它不起作用。 Spring Framework新版本不支持ibatis。

错误:

引起:java.lang.ClassNotFoundException: org.springframework.orm.ibatis.support.SqlMapClientDaoSupport

我的要求: 我需要使用payment.jar(带有Spring Framework 3.1.2)作为对带有Spring Framework 5.x的新项目的依赖,而没有上述问题。

【问题讨论】:

  • 您能否提及您在各种情况下遇到的确切错误?似乎有两件相互矛盾的事情 A.-您想从 payment.jar B 中删除 spring 3 依赖项。- Payment.jar 不适用于 spring 3,因为 spring-ibatis 不适用于 spring 5。A & B 似乎跟我矛盾
  • 您能否发布您未找到异常的确切类?或者您可以发布完整的堆栈跟踪。
  • @dhroove 我发布了异常的原因。
  • 你可以尝试使用mybatis(ibatis进化)和thimybatis.org/spring
  • 我会远离诸如着色/组装依赖项之类的任何事情来解决版本冲突,并且还会为新应用程序使用 spring 3,因为单片应用程序可以更好地与单个版本的依赖项一起使用并发布应用程序。作为一项并行工作,我将升级付款以使用 spring 5。这是管理成本和时间的最佳策略。您必须升级以保持最新版本以解决以前版本中的所有旧安全漏洞,并且它可以更好地使您与新项目中可能需要的其他新功能保持一致。

标签: java spring maven maven-plugin executable-jar


【解决方案1】:

理想的解决方案是将所有内容更新到 Spring 5 或像其他人提到的那样将 payment.jar 单独部署为微服务。但这不是您问题的核心部分,也许您有一些不可避免的要求。正如@tomer-shahar 所说,解决方案是使用maven shade plugin

当您使用共享相同库但版本不同的开源库时,这种冲突经常发生。

maven shade 插件允许重命名/重新定位选择的包以避免版本之间的冲突。缺点是某些类会被复制(因此远非理想)。请参见下面的示例:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-shade-plugin</artifactId>
  <version>3.0.0</version>
  <executions>
    <execution>
      <phase>package</phase>
      <goals>
        <goal>shade</goal>
      </goals>
      <configuration>
        <finalName>spring321-payment-shaded</finalName>
        <relocations>
          <relocation>
            <pattern>spring.package</pattern>
            <shadedPattern>shaded.spring.package</shadedPattern>
          </relocation>
        </relocations>
        <artifactSet>
          <includes>
            <include>*:*</include>
          </includes>
        </artifactSet>
      </configuration>
    </execution>
  </executions>
</plugin>

然后将这个阴影库添加为 Spring 5 项目的依赖项,并完成所有重命名/重定位。我使用了这个有趣的article,其中所有细节都得到了完整的描述。

【讨论】:

    【解决方案2】:

    最好的选择是手动升级。 即使您将使用 Spring 3 jar 执行此操作,在编译和运行时也会遇到很多问题。

    【讨论】:

      【解决方案3】:

      虽然我没有专门对 spring 进行此操作,但您尝试完成的一般概念称为着色。

      https://softwareengineering.stackexchange.com/questions/297276/what-is-a-shaded-java-dependency

      fat jar 不起作用的原因是因为所有 jar 都加载到了类路径中,并且为至少一个依赖项选择了错误的。

      您需要做的是更改依赖项和依赖 jar(在您的情况下为 spring 3 和 payment jar)中的包名称,因此您基本上会得到两对不重叠的依赖项。

      这在 maven 和类似工具中相对简单。有关详细信息,请参阅链接。

      【讨论】:

        【解决方案4】:

        你的愿望

        我需要使用 payment.jar(带有 Spring Framework 3.1.2)作为 使用 Spring Framework 5.x 对新项目的依赖没有问题 上面提到过。

        你做不到。因为依赖的版本不匹配。很多东西,很多版本的iBatis,Spring Framework,payment.jar等依赖之间是不向后兼容的。

        您必须手动升级它。

        【讨论】:

          【解决方案5】:

          我建议你在 Spring 5 和 MyBatis 中转换你的 jar。我认为就可维护性和兼容性而言,这是更好的解决方案。迁移到 iBatis 到 MyBatis 不是什么大问题,我认为。

          我有一个使用 Spring 5 和 My-Batis 3 的工作项目。我在配置它时遇到了一些问题,但最后我解决了一切。只需检查 POM 配置和 Spring 配置即可。

          POM 配置

          在以下代码行中,您可以阅读项目 pom(我为您的问题删除了文件中无用的部分)。

          <?xml version="1.0" encoding="UTF-8"?>
          <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
              <modelVersion>4.0.0</modelVersion>
              <groupId>it.dummy</groupId>
              <artifactId>dummy</artifactId>
              <packaging>war</packaging>
              <version>0.0.1-SNAPSHOT</version>
              <name>Dummy App</name>
              <url>http://maven.apache.org</url>
          
              <properties>
                  <java-source.version>1.8</java-source.version>
          
                  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
                  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
          
                  <maven.compiler.source>1.8</maven.compiler.source>
                  <maven.compiler.target>1.8</maven.compiler.target>
                  <maven.skip.tests>true</maven.skip.tests>
          
                  <servlet-api.version>3.1.0</servlet-api.version>
                  <spring.version>5.0.7.RELEASE</spring.version>
                  <swagger.version>2.9.2</swagger.version>
                  <jackson.version>2.9.6</jackson.version>
                  <mybatis-spring>1.3.2</mybatis-spring>
                  
                  <junit.version>4.12</junit.version>
                  <frontend-maven-plugin.version>1.4</frontend-maven-plugin.version>
          
                  <mapstruct.version>1.2.0.Final</mapstruct.version>
              </properties>
          
              <dependencies>
          
                  <!-- -->
                  <!-- https://mvnrepository.com/artifact/org.mapstruct/mapstruct -->
                  <!-- https://github.com/mapstruct/mapstruct -->
                  <dependency>
                      <groupId>org.mapstruct</groupId>
                      <artifactId>mapstruct-jdk8</artifactId>
                      <version>${mapstruct.version}</version>
                  </dependency>
          
                  <!-- cucumber -->
                  <!-- https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java -->
                  <dependency>
                      <groupId>org.seleniumhq.selenium</groupId>
                      <artifactId>selenium-java</artifactId>
                      <version>3.14.0</version>
                      <scope>test</scope>
                  </dependency>
          
                  <!-- https://mvnrepository.com/artifact/info.cukes/cucumber-java -->
                  <dependency>
                      <groupId>info.cukes</groupId>
                      <artifactId>cucumber-java</artifactId>
                      <version>1.2.5</version>
                      <scope>test</scope>
                  </dependency>
          
                  <!-- https://mvnrepository.com/artifact/info.cukes/cucumber-junit -->
                  <dependency>
                      <groupId>info.cukes</groupId>
                      <artifactId>cucumber-junit</artifactId>
                      <version>1.2.5</version>
                      <scope>test</scope>
                  </dependency>
          
          
                  <!-- test -->
                  <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
                  <dependency>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-test</artifactId>
                      <version>${spring.version}</version>
                      <scope>test</scope>
                  </dependency>
                  <!-- https://mvnrepository.com/artifact/junit/junit -->
                  <dependency>
                      <groupId>junit</groupId>
                      <artifactId>junit</artifactId>
                      <version>${junit.version}</version>
                      <scope>test</scope>
                  </dependency>
          
          
                  <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
                  <dependency>
                      <groupId>org.apache.commons</groupId>
                      <artifactId>commons-lang3</artifactId>
                      <version>3.8</version>
                  </dependency>
          
          
                  <!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
                  <dependency>
                      <groupId>javax.servlet</groupId>
                      <artifactId>javax.servlet-api</artifactId>
                      <version>${servlet-api.version}</version>
                      <scope>provided</scope>
                  </dependency>
          
                  <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-rest-core -->
                  <dependency>
                      <groupId>org.springframework.data</groupId>
                      <artifactId>spring-data-rest-core</artifactId>
                      <version>3.0.10.RELEASE</version>
                  </dependency>
          
          
                  <dependency>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-webmvc</artifactId>
                      <version>${spring.version}</version>
                      <exclusions>
                          <exclusion>
                              <artifactId>commons-logging</artifactId>
                              <groupId>commons-logging</groupId>
                          </exclusion>
                      </exclusions>
                  </dependency>
          
                  <!-- https://mvnrepository.com/artifact/org.springframework/spring-tx -->
                  <dependency>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-tx</artifactId>
                      <version>${spring.version}</version>
                  </dependency>
          
                  <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
                  <dependency>
                      <groupId>org.springframework</groupId>
                      <artifactId>spring-jdbc</artifactId>
                      <version>${spring.version}</version>
                  </dependency>
          
          
                  <!-- Spring Security Artifacts - START -->
                  <!-- http://mvnrepository.com/artifact/org.springframework.security/spring-security-web%20 -->
                  <dependency>
                      <groupId>org.springframework.security</groupId>
                      <artifactId>spring-security-web</artifactId>
                      <version>${spring.version}</version>
                  </dependency>
          
                  <!-- http://mvnrepository.com/artifact/org.springframework.security/spring-security-config%20 -->
                  <dependency>
                      <groupId>org.springframework.security</groupId>
                      <artifactId>spring-security-config</artifactId>
                      <version>${spring.version}</version>
                  </dependency>
                  <!-- Spring Security Artifacts - END -->
          
          
                  <!-- Swagger - BEGIN -->
                  <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
                  <dependency>
                      <groupId>io.springfox</groupId>
                      <artifactId>springfox-swagger-ui</artifactId>
                      <version>${swagger.version}</version>
                  </dependency>
          
                  <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
                  <dependency>
                      <groupId>io.springfox</groupId>
                      <artifactId>springfox-swagger2</artifactId>
                      <version>${swagger.version}</version>
                  </dependency>
          
          
                  <!-- Swagger - END -->
          
                  <!-- json -->
                  <dependency>
                      <groupId>com.fasterxml.jackson.dataformat</groupId>
                      <artifactId>jackson-dataformat-xml</artifactId>
                      <version>${jackson.version}</version>
                  </dependency>
          
                  <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
                  <dependency>
                      <groupId>com.fasterxml.jackson.core</groupId>
                      <artifactId>jackson-databind</artifactId>
                      <version>${jackson.version}</version>
                  </dependency>
          
                  <dependency>
                      <groupId>com.fasterxml.jackson.datatype</groupId>
                      <artifactId>jackson-datatype-jsr310</artifactId>
                      <version>${jackson.version}</version>
                  </dependency>
          
                  <!-- mybatis -->
                  <dependency>
                      <groupId>org.mybatis</groupId>
                      <artifactId>mybatis-spring</artifactId>
                      <version>${mybatis-spring}</version>
                  </dependency>
          
                  <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
                  <dependency>
                      <groupId>org.mybatis</groupId>
                      <artifactId>mybatis</artifactId>
                      <version>3.4.6</version>
                  </dependency>
          
          
                  <dependency>
                      <groupId>log4j</groupId>
                      <artifactId>log4j</artifactId>
                      <version>1.2.17</version>
                      <type>jar</type>
                  </dependency>
                  
                  <dependency>
                      <groupId>joda-time</groupId>
                      <artifactId>joda-time</artifactId>
                      <version>2.9</version>
                  </dependency>
                  
              </dependencies>
              
          </project>
          

          记得检查总是依赖关系树,以避免有不合时宜的 Spring jars。

          弹簧配置

          我有不同的 Spring 配置文件。我只附上有趣的。

          <?xml version="1.0" encoding="UTF-8"?>
          <beans xmlns="http://www.springframework.org/schema/beans"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
              xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
              xmlns:util="http://www.springframework.org/schema/util"
              xmlns:tx="http://www.springframework.org/schema/tx"
              xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                  http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd
                  http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
                  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
          
          
              <bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close">
                  <property name="URL" value="jdbc:oracle:thin:@xxx:yyy:zzz" />
                  <property name="user" value="aaa"/>
                  <property name="password" value="bbb"/>
                  <property name="connectionCachingEnabled" value="true" />
              </bean> 
          
              
              <bean id="transactionManagerNG" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                  <property name="dataSource" ref="dataSource" />
              </bean>
          
              <bean id="sqlSessionFactoryNG" class="org.mybatis.spring.SqlSessionFactoryBean" name="SqlSessionFactoryOrarioStandardDao">
                  <property name="dataSource" ref="dataSource" />
                  <!-- 1. Where is the xml for query's definitions -->
                  <property name="mapperLocations" value="classpath:com/dummy/persistence/dao/*.xml" />
                  
                  <!-- 2. My-batis configuration -->
                  <property name="configLocation" value="classpath:mybatis-config.xml"></property>
                  
                  <!-- 3. My-batis type alias package -->
                  <property name="typeAliasesPackage" value="com.dummy.persistence.model" />
              </bean>
              
              <!-- 4. needed to parse Java DAO interfaces -->
              <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
                  <property name="basePackage" value="it.insiel.sanita.farmacieng.persistence.dao" />     
                  <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryNG"/>
              </bean>
              
              <tx:annotation-driven/> 
          </beans>
          

          在上面的 Spring 文件中你会发现:

          • 我如何为 SQL 查询定义放置 XML 的位置(注释 1)
          • 我如何使用My-batis配置(评论2)
          • 我如何定义类型别名包(评论 3)
          • 我如何定义 DAO 接口

          最后但并非最不重要的是 My-batis 配置文件mybatis-config.xml,我放在 Spring 配置文件的同一文件夹中:

          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
          <!-- http://mybatis.org/dtd/ -->
          <configuration>
          
              <settings>
                  <setting name="logImpl" value="LOG4J"/>              
                  <setting name="cacheEnabled" value="true"/>
                  <setting name="defaultStatementTimeout" value="3000"/>
                  <setting name="mapUnderscoreToCamelCase" value="true"/>
                  
                  <setting name="jdbcTypeForNull" value="NULL" />                
              </settings>
              
          </configuration> 
          

          【讨论】:

            【解决方案6】:

            如果 Spring 版本像听起来那样不兼容,那么您可能必须重新编译 jar 或项目,以便它们使用相同版本的 Spring。

            如果这是不可能的(例如,如果您没有 jar 的来源),您可以将支付 jar 包装在一个微服务中,以便它在不同的进程中运行,并通过 XML-RPC 与它通信或 SOAP。

            【讨论】:

            • 感谢重播。我有源代码,但重新编译,迁移很昂贵,支付 jar 完美地完成了他的工作,我们只需要在 spring 5+ 的新项目中使用它就可以了。
            • 大概不同的类加载器就足够了。 (我没有接触过 Spring。)
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-07-28
            • 1970-01-01
            • 2019-09-03
            相关资源
            最近更新 更多