jar冲突场景:
- 不同版本间的弱依赖,不同组件依赖同一个jar的不同版本,<exclusion> 其中一个版本即可, 一般发生在一些向下兼容的类库中,通常情况下可以解决问题.
- 不同版本间的强依赖关系,不同组件强依赖与两同一个jar的不同版本,由于版本跨度过大,导致高版本的jar并不兼容低版本中的方法,不能通过<exclusion> 来解决冲突.
对于第一种情况,毋庸置疑由于不同版本间兼容排除其它保留一个即可.对第二种情况而言就不乐观了,首先冲突是由于两不同版本的jar包名相同,类名,方法名,参数都有可能存在冲突,对于JVM而言在同一个类加载器下是容不下两个包名,类名都相同的对象存在的.由此可见此类型的jar冲突确实比较麻烦.
针对于第二种jar冲突的场景给出两种思考:
- 使用多个类加载器,而由此极大的增加了程序的复杂性,几乎可以考虑放弃了.
- 退而求其次,两者不兼容是由于存在类的全路径冲突的情况,可以考虑将改变其中一个jar的包结构,这样即解决了两jar不会存在包+类名冲突的情况.
第一种方案PASS掉,对于第二种思考,在修改包名的同时,要完成对所有依赖于当前jar中所有类文件的引用纠正!!!!!!,否则修改无效.可幸的是这个过程可以借助MAVEN 插件来完成 apache maven shade plugin
shade 简介:作用于mavan 生命周期,支持依赖关系解析,包重命名,依赖打包等特性.
案例: ES2.2.0 & Hbase1.1.2对 Guava的依赖,ES依赖于Guava 18.0,Hbase 依赖于Guava12.0 对于需要ES&Hbase 整合的项目中两者不兼容,现使用maven shade 插件对ES 依赖的Guava 进行包重新名,直接打入到独立Jar中(ES+相关可能的冲突jar).
新建Mavan项目 independent_es_jar
添加依赖:
<dependencies>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>shield</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
</dependencies>
添加插件依赖:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>com.google.guava</pattern>
<shadedPattern>my.elasticsearch.guava</shadedPattern>
</relocation>
<relocation>
<pattern>org.joda</pattern>
<shadedPattern>my.elasticsearch.joda</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.common</pattern>
<shadedPattern>my.elasticsearch.common</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.thirdparty</pattern>
<shadedPattern>my.elasticsearch.thirdparty</shadedPattern>
</relocation>
</relocations>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer" />
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
添加插件仓库:
<repositories>
<repository>
<id>elasticsearch-releases</id>
<url>http://maven.elasticsearch.org/releases</url>
<releases>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
打包insall 本地仓库过远程仓库,冲突项目中对ES的引入替换为引入当前包即可.
核心配置解释
<relocation>
<pattern>com.google.guava</pattern>
<shadedPattern>my.elasticsearch.guava</shadedPattern>
</relocation>
迁移 com.google.guava 包下的所有类到 my.elasticsearch.guava 包下,且纠正所有对com.google.guava的引用.
主意事项:
项目中引入独立jar后需要显示的排除对ES的引入,独立jar中以包含ES的class,
由于Mavan的传递依赖性,如果项目以工程的方式引用独立jar 可能会出现不能正确访问某些类的情况,此为eclipse 表现的假象,不影响实际的编译,当然可以去掉对工程的依赖,使得项目直接依赖于jar即可解决.
附件
pom.xml
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>independent_es_jar</groupId>
<artifactId>com.ehualu.itsbg</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>ES独立Jar</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<elasticsearch.version>2.2.0</elasticsearch.version>
</properties>
<dependencies>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
<dependency>
<groupId>org.elasticsearch.plugin</groupId>
<artifactId>shield</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<relocations>
<relocation>
<pattern>com.google.guava</pattern>
<shadedPattern>my.elasticsearch.guava</shadedPattern>
</relocation>
<relocation>
<pattern>org.joda</pattern>
<shadedPattern>my.elasticsearch.joda</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.common</pattern>
<shadedPattern>my.elasticsearch.common</shadedPattern>
</relocation>
<relocation>
<pattern>com.google.thirdparty</pattern>
<shadedPattern>my.elasticsearch.thirdparty</shadedPattern>
</relocation>
</relocations>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer" />
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>elasticsearch-releases</id>
<url>http://maven.elasticsearch.org/releases</url>
<releases>
<enabled>true</enabled>
<updatePolicy>daily</updatePolicy>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>