首页 > 解决方案 > 使用 SNAPSHOT 依赖项时,Maven 找不到类定义

问题描述

我正在为使用 Pi4j 的 RaspberryPi 构建应用程序。在我遇到需要将 Pi4j 版本从 1.1 更改为 1.2-SNAPSHOT 之前,它运行良好。我NoCassDefFoundException只在使用 SNAPSHOT 时得到。

我正在使用一些插件来分隔我的 jar 和所有存储在lib/*目录中的库。maven-dependency-plugin做这项工作

maven-jar-plugin将带有库的目录链接到我的 jar

maven-antrun-plugin复制我的 jar 并且只在mvn install

我的pom.xml文件(剥离了很多)

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Rpi</groupId>
<artifactId>Rpi</artifactId>
<version>0.0.1-SNAPSHOT</version>

<properties>
    <!--<pi4j.version>1.2-SNAPSHOT</pi4j.version>-->
    <pi4j.version>1.1</pi4j.version>
</properties>

<dependencies>
    <dependency>
        <groupId>com.pi4j</groupId>
        <artifactId>pi4j-core</artifactId>
        <version>${pi4j.version}</version>
    </dependency>
    (...)
</dependencies>

<repositories>
    <repository>
        <id>oss-snapshots-repo</id>
        <name>Sonatype OSS Maven Repository</name>
        <url>https://oss.sonatype.org/content/groups/public</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
    </repository>
</repositories>

<build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.6.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <executions>
                <execution>
                    <id>copy-dependencies</id>
                    <phase>prepare-package</phase>
                    <goals>
                        <goal>copy-dependencies</goal>
                    </goals>
                    <configuration>
                        <outputDirectory>${project.build.directory}/lib</outputDirectory>
                        <overWriteReleases>true</overWriteReleases>
                        <overWriteSnapshots>true</overWriteSnapshots>
                        <overWriteIfNewer>true</overWriteIfNewer>
                    </configuration>
                </execution>
            </executions>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>${pi.main.class}</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-antrun-plugin</artifactId>
            <version>1.8</version>
            <executions>
                <execution>
                    <phase>install</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                    <configuration>
                        <tasks>
                            <scp
                                    file="${project.build.directory}/${project.build.finalName}.jar"
                                    todir="${pi.user}:${pi.password}@${pi.host}:${pi.deployDirectory}"
                                    port="${pi.port}" trust="true" verbose="false" failonerror="false">
                            </scp>

                            <!-- copy dependencies, only new or modified-->
                            <scp todir="${pi.user}:${pi.password}@${pi.host}:${pi.deployDirectory}/lib"
                                 port="${pi.port}" trust="true" verbose="false" failonerror="false">
                                <fileset dir="${project.build.directory}/lib">
                                    <modified>
                                        <param name="cache.cachefile" value="localdev.cache"/>
                                    </modified>
                                </fileset>
                            </scp>

                        </tasks>
                    </configuration>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.apache.ant</groupId>
                    <artifactId>ant-jsch</artifactId>
                    <version>1.9.6</version>
                </dependency>
            </dependencies>
        </plugin>
        (...)
    </plugins>
</build>

一切看起来都很好之后mvn install,我的 jar 就在它应该在的位置,所有依赖项都被复制,我运行我的 jarjava -jar Rpi-0.0.1-SNAPSHOT.jar并运行它,直到 aNoClassDefFoundError被提出。

问题是当我只使用 Pi4j 1.2-SNAPSHOT 时。当我使用 1.1 版时,它工作正常(嗯,崩溃,这就是我必须切换到 1.2-SNAPSHOT 的原因)。如果我在 pom.xml 中使用 1.1 版,并且在mvn install重命名lib\pi4j-core-1.2-SNAPSHOT.jarlib\pi4j-core-1.1.jar一切都按预期运行后,使用 1.2 版不会崩溃...

标签: mavennoclassdeffounderror

解决方案


Maven-jar-plugin在我的 jar 类路径中更改了 SNAPSHOT 依赖项的名称。为了解决这个问题,我必须添加<useUniqueVersions>false</useUniqueVersions>到插件清单中,所以现在看起来像这样

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <addClasspath>true</addClasspath>
                        <classpathPrefix>lib/</classpathPrefix>
                        <mainClass>${pi.main.class}</mainClass>
                        <useUniqueVersions>false</useUniqueVersions>
                    </manifest>
                </archive>
            </configuration>
        </plugin>

并且工作正常


推荐阅读