admin管理员组

文章数量:1618692

记一次maven打包失败:Compilation failure

本篇文章要点如下:

一.maven打包报错详情

二.将本地jar包上传到nexus

  • 上传普通的第三方jar包
  • 上传snapshots jar包

三.打包方式

  • 使用springboot方式打包
  • 使用maven方式打包
一.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文件里面配置的项目的groupIdartifactId和版本号,既能查找到相应的依赖
例: 我项目的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-INFclasses目录,下面才是真正的源码,
难怪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

打包成功,问题得到解决!

本文标签: mavenCompilationfailure