SpringBoot解決jar包沖突的問題,簡(jiǎn)單有效
SpringBoot解決jar包沖突
今天SpringBoot項(xiàng)目打包發(fā)現(xiàn)一直在報(bào)錯(cuò)
包jar包沖突,找了好久才找到結(jié)果,期間遇到一片博客很討人厭,我這里想評(píng)論一下他(原因:我沒有博客園不能直接評(píng)論,所以這里寫一篇博客記錄一下,并提供正確的解決方案)
上圖:

說一下:首先,你給的方法很泛(不是煩沒打錯(cuò)字)只是市面上大多數(shù)可以解決的套路,
再者,你給的解決方案并沒有真正的解決問題。所以我留下一句話:不喜勿噴。
SpringBoot事實(shí)上是很好的,jar包沖突的時(shí)候,它是有提醒你了的,啟動(dòng)第一行就說了有多個(gè)類路徑j(luò)ar包存在:Class path contains multiple SLF4J bindings.
SpringBoot適合于小團(tuán)隊(duì)及個(gè)人開發(fā)。是比較方便的。
為什么我要寫這篇博客呢,因?yàn)槲铱吹絡(luò)ar沖突的真正原因后,很生氣,因?yàn)樵虿⒉灰欢ㄔ赟pringBoot 我這里查出的是騰訊云的cos-api也引入的了日志jar,所以導(dǎo)致沖突,這里是SpringBoot引入cos-api,你就說SpringBoot,如果SpringBoot是被被人引入的,你是不是也要說其他的工具不好呢???再者不好你為什么要用,要記錄???這只不過是想比較而言,技術(shù)沒有老舊,沒有好壞,只有喜歡,不喜歡,很多時(shí)候有些公司用的還是一二十年前的技術(shù),可能是有些原因不能更換,但是我相信,它能存在在這個(gè)世上并風(fēng)靡一時(shí),說明它一定有它的獨(dú)特之處。
接下來就是,
我查到的一個(gè)解決方案,可使用所有jar包沖突問題
以eclipse為例:
這樣的開發(fā)工具都會(huì)有一個(gè)功能:就是查詢jar包直接引入/jar包間接引入的功能

如果你不知道你使用的工具怎么找到這個(gè)查找頁面:百度搜索:eclipse 看引入jar 包的聯(lián)系(idea同理)
說實(shí)話idea的更清晰一些,它是圖形化界面
找到?jīng)_突的jar包,去除沖突的包即可
代碼如下:
<dependency> <groupId>com.qcloud</groupId> <artifactId>cos_api</artifactId> <version>5.5.3</version> <exclusions> <!-- <exclusion> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> </exclusion> --> <exclusion> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </exclusion> </exclusions> </dependency>
聲明:我只是對(duì)SpirngBoot報(bào)不平,沒有對(duì)任何人做人身攻擊。不喜勿噴
spring boot jar沖突問題集錦
總結(jié)下spring boot項(xiàng)目搭建過程中,沖突解決的一些小經(jīng)驗(yàn)
1、日志jar包沖突
1.1、日志主要是spring boot自帶spring-boot-starter-logging的排除
一是要用log4j2,二是xdcs不排除這個(gè)也會(huì)有沖突。(隱秘程度:低;重要程度:高)
<exclusion> <artifactId>spring-boot-starter-logging</artifactId> <groupId>org.springframework.boot</groupId> </exclusion>
1.2、引的日志jar頗多
可能會(huì)有別的jar里也帶了沖突的class,但是不影響啟動(dòng),屬于可排可不排??赡軙?huì)導(dǎo)致測(cè)試環(huán)境起不來。(隱秘程度:低;重要程度:高)
//這是舉個(gè)例子 <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] //這是啟動(dòng)時(shí)對(duì)應(yīng)的報(bào)錯(cuò),經(jīng)檢驗(yàn),這個(gè)不影響啟動(dòng)
2、本地ok,測(cè)試環(huán)境失敗之mainstay
發(fā)測(cè)試時(shí),出現(xiàn)過mainstay的yml解析失敗的問題,maven helper排jar包并未顯示有沖突,tree搜索mainstay,發(fā)現(xiàn)了一些貓膩。passport-sso-api(0.0.14-M3,下面用到的也是這個(gè)版本)這個(gè)jar包里包含了這個(gè)mainstay的jar,最終導(dǎo)致了解析失敗。后續(xù)登錄驗(yàn)證可以接下網(wǎng)關(guān)鑒權(quán)等方式,這個(gè)jar沖突應(yīng)該就不會(huì)出現(xiàn)了。(隱秘程度:高;重要程度:中)
<exclusion> <artifactId>mainstay-rpc-thrift</artifactId> <groupId>com.ximalaya.mainstay</groupId> </exclusion>
3、本地ok,測(cè)試環(huán)境失敗之servlet
發(fā)測(cè)試時(shí),出現(xiàn)過servlet2和spring boot內(nèi)置tomcat class重名沖突的問題,一般主要passport-sso-api和xdcs默認(rèn)會(huì)帶這個(gè),排掉即可(隱秘程度:中;重要程度:高)
<exclusion> <artifactId>servlet-api</artifactId> <groupId>javax.servlet</groupId> </exclusion>
4、本地ok,測(cè)試環(huán)境失敗之tomcat
發(fā)測(cè)試時(shí),也出現(xiàn)過passport-sso-api這個(gè)jar包里包含的spring-instrument-tomcat和spring boot內(nèi)置tomcat沖突,排掉即可。后續(xù)登錄驗(yàn)證可以接下網(wǎng)關(guān)鑒權(quán)等方式,這個(gè)jar沖突應(yīng)該就不會(huì)出現(xiàn)了。(隱秘程度:高;重要程度:中)
<exclusion> <artifactId>spring-instrument-tomcat</artifactId> <groupId>org.springframework</groupId> </exclusion>
5、本地ok,測(cè)試環(huán)境失敗之spring asm
測(cè)試環(huán)境出現(xiàn)過passport-sso-api里spring asm與spring-boot-test-start沖突的情況,排掉排掉。passport-sso-api這個(gè)jar包含的jar比較多,后面建議用注解或者網(wǎng)關(guān)鑒權(quán)來做登錄控制。(隱秘程度:高;重要程度:中)
<exclusion> <artifactId>spring-asm</artifactId> <groupId>org.springframework</groupId> </exclusion>
6、萬惡的測(cè)試環(huán)境字節(jié)碼驗(yàn)證失敗
之前發(fā)過一個(gè)前項(xiàng)目改造的spring boot項(xiàng)目就出現(xiàn)過,當(dāng)時(shí)不以為意,讓jvm參數(shù)加了-noverify就沒管,后來發(fā)現(xiàn)很多項(xiàng)目都有這個(gè)問題,開始排查。之前看過jdk和aspectj有沖突的例子,就開始tree里搜a(bǔ)spectj,發(fā)現(xiàn)spring-boot-start-aop里引入了1.9.4版本的aspectjweaver,但是當(dāng)時(shí)因?yàn)閙aven 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、日志不能正常輸出問題
排除,日志橋接混亂,后臺(tái)配置的日志格式不支持了
<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、本地打包正常
測(cè)試或者線上環(huán)境打包失敗,查看wrap.log日志,本地配置文件使用線上,打包測(cè)試;
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>
<!-- 啟動(dòng)內(nèi)存配置 -->
<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沖突網(wǎng)上容易查到,有些基本查不到,可以先去tree搜個(gè)短名看看,看看有沒有相似的jar,再去查是否真的會(huì)有沖突
3、有些是class沖突,找到對(duì)應(yīng)的jar排掉即可,盡量別排spring自帶的,容易出現(xiàn)兼容性問題
4、啟動(dòng)時(shí),我已經(jīng)將一些不必須的autoConfigure排掉了,真要用到,記得放出來,平時(shí)用不到的盡量排掉,這樣就不會(huì)去加載了,不然很多都是默認(rèn)加載的。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
詳解Java面向?qū)ο笾鄳B(tài)的原理與實(shí)現(xiàn)
多態(tài)是指不同的子類在繼承父類后分別都重寫覆蓋了父類的方法,即父類同一個(gè)方法,在繼承的子類中表現(xiàn)出不同的形式。本文將詳解多態(tài)的原理與實(shí)現(xiàn),感興趣的可以學(xué)習(xí)一下2022-05-05
詳解SpringBoot中的統(tǒng)一功能處理的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了SpringBoot如何實(shí)現(xiàn)統(tǒng)一功能處理,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定借鑒價(jià)值,需要的可以參考一下2023-01-01
用html css javascript打造自己的RIA圖文教程
用html&css&javascript打造自己的RIA之一,包括了配置等2009-07-07

