Maven 打包踩坑之ClassNotFoundException 與 NoClassDefFoundError
問題:
spark streaming程序在本地運行正常,上傳至服務器運行時出現如下錯誤:
Caused by: java.lang.ClassNotFoundException: AAA
Caused by: java.lang.NoClassDefFoundError: AAA
Caused by: java.lang.reflect.InvocationTargetException
java.lang.IllegalArgumentException: Unable to create serializer "com.esotericsoftware.kryo.serializers.FieldSerializer" for class:com.xxx.yyy.BBB
其中AAA爲ClassLoader找不到的jar包名稱,BBB爲具體調用AAAjar包的項目文件。
分析:
對應依賴未打入項目jar包中,經過檢查發現和maven 打包插件有關係,自己平常打包會用到兩種插件:
maven-jar-plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
maven-jar-plugin會生成如下形式的兩種jar包:
origin爲原始jar包,不含其他依賴,下面的爲包含pom中依賴的jar包,如果運行環境中未提供自己pom中的其他依賴,使用original
maven-assembly-plugin
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<appendAssemblyId>true</appendAssemblyId>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
前者爲原始jar包,類似於maven-jar打包裏面的origin-jar,後者with-dependencies爲包含pom中費provided依賴的jar包,如果線上環境未提供這些依賴,就得使用with-dependencies的jar包
解決:
使用 maven-assembly-plugin 上傳了原始jar包,而生產環境中沒有AAA,所以BBB中調用顯示no class found,改爲上傳with-dependicies包後,程序正常運行