記一次maven打包失敗:Compilation failure
本篇文章要點如下:
一.maven打包報錯詳情
問題背景 :
B項目依賴於A項目,並且兩個項目都能在本地正常運行.
現在對A項目打包成功之後,對B項目進行進行打包,報錯,報錯信息如下:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project kafka-ysdw: Compilation failure
[ERROR] /E:/softWare/office/idea/yinsheng-work/kafka_etl/kafka-ysdw/src/main/java/Test.java:[1,41] 程序包com.ys.bigdata.etl.basic.constant不存在
其中,報錯中涉及到的包來自A項目.
使用mvn -e clean install命令,
查看詳細的報錯信息如下 :
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project kafka-ysdw: Compilation failure
[ERROR] /E:/softWare/office/idea/yinsheng-work/kafka_etl/kafka-ysdw/src/main/java/Test.java:[1,41] 程序包com.ys.bigdata.etl.basic.constant不存在
[ERROR]
[ERROR] -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project kafka-ysdw: Compilation failure
/E:/softWare/office/idea/yinsheng-work/kafka_etl/kafka-ysdw/src/main/java/Test.java:[1,41] 程序包com.ys.bigdata.etl.basic.constant不存在
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:213)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:154)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:146)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:305)
at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
at org.apache.maven.cli.MavenCli.execute (MavenCli.java:954)
at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:288)
at org.apache.maven.cli.MavenCli.main (MavenCli.java:192)
at sun.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke (Method.java:498)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:289)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:229)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:415)
at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:356)
at org.codehaus.classworlds.Launcher.main (Launcher.java:47)
錯誤其實非常簡單,就是B對A的引用找不到引發報錯~
因爲我們的maven使用的是公司的私倉,並且也曾在使用的過程中遇到過一些打包的問題.
所以,在沒有經過謹慎思考的情況下,我把問題定位到了沒有把依賴項目上傳到私倉
既然有了懷疑的目標,我們就嘗試着把A項目的jar包上傳到私倉
二.將本地jar包上傳到nexus
我這裏介紹兩種常用的將本地jar包上傳到nexus方式,
第一種是使用常用的方式上傳第三方jar包,
令一種方式是上傳snapshots類型的jar包
上傳普通的第三方jar包
上傳過程如下:
jar包查看方式如下圖所示 :
按照pom.xml文件裏面配置的項目的groupId和artifactId和版本號,既能查找到相應的依賴
例: 我項目的groupId爲:com.ys.bigtata.etl,artifactId爲:kafka_etl,那麼在nexus下面對應的jar包目錄結構如下:
引用依賴的時候使用下面的方式即可:
<dependency>
<groupId>com.ys.bigtata.etl</groupId>
<artifactId>kafka_etl_basic</artifactId>
<version>1.0</version>
</dependency>
上傳snapshots jar包
第二種方式專門針對SNAPSHOT類型的jar包,這種jar包通常是我們自己寫的
在需要上傳到私倉項目的pom.xml裏面,添加如下配置:
這裏的uri要按照實際的情況配置:
<distributionManagement>
<snapshotRepository>
<id>snapshots</id>
<url>http://10.213.32.58:8081/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
配置結束之後,執行:
mvn clean package deploy命令打包
採用這種打包方式之後,target下的目錄結構和普通的打包方式還是有比較大的區別的,如下所示:
上傳成功之後在nexus顯示的目錄結構如下:
將jar包上傳到nexus之後,我信心滿滿的去打包,依然報同樣的問題!
這個時候,我才確認和私倉半毛錢的關係都沒有(其實早就應該發現的,因爲maven打包的時候,是優先掃描本地倉庫,本地找不到,纔會去maven的配置文件settings.xml的配置去私倉裏面查找的),然而我本地明顯是有依賴的jar包的.
三.打包方式
使用springboot方式打包
經過上面的分析和嘗試,很名顯,應該是項目哪裏的配置出了問題,於是仔細檢查了一遍A項目的pom.xml,發現瞭如下配置:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!--<version>${spring.version}</version> -->
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
原來A項目是使用springboot的方式打包的,
用這種方式打包出來的目錄結構是這樣的:
可以看到,在jar包的根目錄下,有BOOT-INF和classes目錄,下面纔是真正的源碼,
難怪maven打包的時候會找不到呢!
使用maven方式打包
於是,修改配置文件pom.xml,修改爲用maven打包的方式,配置如下:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
從下圖中可以看到: 使用maven方式打成的jar包根目錄下就是我們寫的源碼!
接下來,重新嘗試對B項目進行打包,執行命令:
mvn clean install
打包成功,問題得到解決!