记一次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
打包成功,问题得到解决!