spring boot jar冲突问题集锦
本文主要总结下spring boot项目搭建过程中,冲突解决的一些小经验
1、日志jar包冲突:
1.1、日志主要是spring boot自带spring-boot-starter-logging的排除,一是要用log4j2,二是xdcs不排除这个也会有冲突。(隐秘程度:低;重要程度:高)
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
1.2、引的日志jar颇多,可能会有别的jar里也带了冲突的class,但是不影响启动,属于可排可不排。可能会导致测试环境起不来。(隐秘程度:低;重要程度:高)
//这是举个例子
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/xmly/.m2/repository/org/apache/logging/log4j/log4j-slf4j-impl/2.11.2/log4j-slf4j-impl-2.11.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/xmly/.m2/repository/org/slf4j/slf4j-log4j12/1.7.5/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
//这是启动时对应的报错,经检验,这个不影响启动
2、本地ok,测试环境失败之mainstay
发测试时,出现过mainstay的yml解析失败的问题,maven helper排jar包并未显示有冲突,tree搜索mainstay,发现了一些猫腻。passport-sso-api(0.0.14-M3,下面用到的也是这个版本)这个jar包里包含了这个mainstay的jar,最终导致了解析失败。后续登录验证可以接下网关鉴权等方式,这个jar冲突应该就不会出现了。(隐秘程度:高;重要程度:中)
<exclusion>
<artifactId>mainstay-rpc-thrift</artifactId>
<groupId>com.ximalaya.mainstay</groupId>
</exclusion>
3、本地ok,测试环境失败之servlet
发测试时,出现过servlet2和spring boot内置tomcat class重名冲突的问题,一般主要passport-sso-api和xdcs默认会带这个,排掉即可(隐秘程度:中;重要程度:高)
<exclusion>
<artifactId>servlet-api</artifactId>
<groupId>javax.servlet</groupId>
</exclusion>
4、本地ok,测试环境失败之tomcat
发测试时,也出现过passport-sso-api这个jar包里包含的spring-instrument-tomcat和spring boot内置tomcat冲突,排掉即可。后续登录验证可以接下网关鉴权等方式,这个jar冲突应该就不会出现了。(隐秘程度:高;重要程度:中)
<exclusion>
<artifactId>spring-instrument-tomcat</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
5、本地ok,测试环境失败之spring asm
测试环境出现过passport-sso-api里spring asm与spring-boot-test-start冲突的情况,排掉排掉。passport-sso-api这个jar包含的jar比较多,后面建议用注解或者网关鉴权来做登录控制。(隐秘程度:高;重要程度:中)
<exclusion>
<artifactId>spring-asm</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
6、万恶的测试环境字节码验证失败
之前发过一个前项目改造的spring boot项目就出现过,当时不以为意,让jvm参数加了-noverify就没管,后来发现很多项目都有这个问题,开始排查。之前看过jdk和aspectj有冲突的例子,就开始tree里搜aspectj,发现spring-boot-start-aop里引入了1.9.4版本的aspectjweaver,但是当时因为maven helper提示它冲突,就把它排了,后重新排掉所有1.7版本的aspectj,引入1.9.4版本的,解决。(隐秘程度:高;重要程度:高)
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
<exclusion>
<artifactId>*</artifactId>
<groupId>org.aspectj</groupId>
</exclusion>
7.日志不能正常输出问题
排除,日志桥接混乱,后台配置的日志格式不支持了
<exclusion> <artifactId>slf4j-log4j12</artifactId> <groupId>org.slf4j</groupId> </exclusion>
Configuration: status: info Properties: Property: - name: log.level.console value: info - name: log.path value: /var/XXX/weXXX - name: project.name value: weXXX - name: log.pattern value: "%-d{yyyy-MM-dd HH:mm:ss SS} [%c]-[%p] %m%n" Appenders: Console: name: CONSOLE target: SYSTEM_OUT PatternLayout: pattern: ${log.pattern} RollingRandomAccessFile: - name: APP_FILE fileName: ${log.path}/${project.name}.log filePattern: "${log.path}/${project.name}-%d{yyyy-MM-dd}.log" PatternLayout: pattern: ${log.pattern} Filters: ThresholdFilter: - level: info onMatch: ACCEPT onMismatch: DENY Policies: TimeBasedTriggeringPolicy: modulate: true interval: 1 DefaultRolloverStrategy: max: 30 Loggers: Root: level: info AppenderRef: - ref: CONSOLE - ref: APP_FILE Logger: - name: app level: info additivity: false AppenderRef: - ref: CONSOLE - ref: APP_FILE
8.本地打包正常,测试或者线上环境打包失败,查看wrap.log日志,本地配置文件使用线上,打包测试;
spring-boot-maven-plugin插件放在靠后位置,不然打包失败;
<profile> <id>uat</id> <properties> <profileActive>UatXXX</profileActive> </properties> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>appassembler-maven-plugin</artifactId> <version>2.0.0</version> <configuration> <configurationDirectory>conf</configurationDirectory> <repositoryLayout>flat</repositoryLayout> <useWildcardClassPath>true</useWildcardClassPath> <daemons> <daemon> <id>${project.artifactId}</id> <mainClass>com.XXXX.Application</mainClass> <commandLineArguments> <commandLineArgument>--spring.profiles.active=${profileActive} </commandLineArgument> </commandLineArguments> <platforms> <platform>jsw</platform> </platforms> <jvmSettings> <!-- 启动内存配置 --> <initialMemorySize>2048M</initialMemorySize> <maxMemorySize>2048M</maxMemorySize> <maxStackSize>128</maxStackSize> <systemProperties> <systemProperty>application.root=.</systemProperty> <systemProperty>spring.application.name=${project.artifactId} </systemProperty> <systemProperty>spring.config.location=./conf/${profileActive}/ </systemProperty> </systemProperties> <extraArguments> <extraArgument>-XX:MetaspaceSize=256M</extraArgument> <extraArgument>-XX:MaxMetaspaceSize=256M</extraArgument> <extraArgument>-XX:+UseG1GC</extraArgument> <extraArgument>-XX:-OmitStackTraceInFastThrow</extraArgument> <extraArgument>-XX:MaxGCPauseMillis=100</extraArgument> <extraArgument>-XX:+ParallelRefProcEnabled</extraArgument> <extraArgument>-XX:+HeapDumpOnOutOfMemoryError</extraArgument> <extraArgument>-XX:+PrintCommandLineFlags</extraArgument> <extraArgument>-XX:+PrintGCDetails</extraArgument> <extraArgument>-XX:+PrintGCDateStamps</extraArgument> <extraArgument>-verbose:class</extraArgument> <extraArgument>-XX:+PrintClassHistogramBeforeFullGC</extraArgument> <extraArgument>-XX:+PrintClassHistogramAfterFullGC</extraArgument> <extraArgument>-XX:+PrintTenuringDistribution</extraArgument> <extraArgument>-XX:+PrintHeapAtGC</extraArgument> <extraArgument>-XX:+PrintGCApplicationStoppedTime</extraArgument> <extraArgument>-XX:+PrintGCApplicationConcurrentTime</extraArgument> <extraArgument>-Xloggc:/var/log/${project.artifactId}/gc-%t</extraArgument> <extraArgument>-XX:+UseGCLogFileRotation</extraArgument> <extraArgument>-XX:GCLogFileSize=10M</extraArgument> <extraArgument>-XX:NumberOfGCLogFiles=10</extraArgument> <extraArgument>-javaagent:/opt/jars/aspectjweaver-1.8.9.jar</extraArgument> </extraArguments> </jvmSettings> <generatorConfigurations> <generatorConfiguration> <generator>jsw</generator> <includes> <include>linux-x86-64</include> <include>macosx-universal-64</include> </includes> <configuration> <property> <name>configuration.directory.in.classpath.first</name> <value>conf</value> </property> <property> <name>wrapper.ping.timeout</name> <value>60</value> </property> <property> <name>set.default.REPO_DIR</name> <value>lib</value> </property> <property> <name>wrapper.logfile</name> <value>/var/XXXX/${project.artifactId}/wrapper.YYYYMMDD.log</value> </property> <property> <name>wrapper.logfile.rollmode</name> <value>DATE</value> </property> <property> <name>wrapper.logfile.maxfiles</name> <value>10</value> </property> <property> <name>wrapper.pidfile</name> <value>/var/XXXX//${project.artifactId}</value> </property> <property> <name>wrapper.java.command</name> <value>/usr/local/jdk8/bin/java</value> </property> <property> <name>wrapper.disable_restarts</name> <value>TRUE</value> </property> <property> <name>wrapper.jvm_exit.timeout</name> <value>5</value> </property> <property> <name>wrapper.shutdown.timeout</name> <value>5</value> </property> <property> <name>wrapper.cpu.timeout</name> <value>0</value> </property> </configuration> </generatorConfiguration> </generatorConfigurations> </daemon> </daemons> </configuration> <executions> <execution> <id>generate-jsw</id> <phase>package</phase> <goals> <goal>generate-daemons</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <configuration> <descriptors> <descriptor>src/main/assembly/assembly.xml</descriptor> </descriptors> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring.boot.version}</version> <executions> <execution> <goals> <goal>build-info</goal> </goals> <configuration> <additionalProperties> <encoding.source>UTF-8</encoding.source> <encoding.reporting>UTF-8</encoding.reporting> <java.source>${java.version}</java.source> <java.target>${java.version}</java.target> </additionalProperties> </configuration> </execution> </executions> </plugin> </plugins> </build> </profile>
tips:
1、不要太相信maven helper提示的jar冲突,具体还是要具体分析
2、有些jar冲突网上容易查到,有些基本查不到,可以先去tree搜个短名看看,看看有没有相似的jar,再去查是否真的会有冲突
3、有些是class冲突,找到对应的jar排掉即可,尽量别排spring自带的,容易出现兼容性问题
4、启动时,我已经将一些不必须的autoConfigure排掉了,真要用到,记得放出来,平时用不到的尽量排掉,这样就不会去加载了,不然很多都是默认加载的。