【问题标题】:Maven shade executable uber jar NoClassDefFoundErrorMaven 阴影可执行 uber jar NoClassDefFoundError
【发布时间】:2015-11-08 12:00:46
【问题描述】:

我正在使用 maven shade 插件创建一个可执行的 uber jar,它依赖于本地系统 jar (mobile-dock-support.jar) 中的一些类,我希望它在打包阶段包含这些类,所以我像这样配置阴影插件

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.4.2</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <transformers>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <mainClass>uk.xxx.mobiledock.PCSyncApplication</mainClass>
                    </transformer>
                </transformers>
            </configuration>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>uk.xxx</groupId>
            <artifactId>mobile-dock-support</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>system</scope>
            <systemPath>${project.build.directory}/../src/main/libs/mobile-dock-support.jar</systemPath>
        </dependency>
    </dependencies>
</plugin>

它似乎可以很好地打包 jar,但是当我使用 java -jar xxx.jar 运行 jar 时,它给了我以下信息

java.lang.NoClassDefFoundError: uk/xxx/mobiledock/MobileDockException
        at java.lang.Class.getDeclaredMethods0(Native Method)
        at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
        at java.lang.Class.privateGetMethodRecursive(Unknown Source)
        at java.lang.Class.getMethod0(Unknown Source)
        at java.lang.Class.getMethod(Unknown Source)
        at sun.launcher.LauncherHelper.validateMainClass(Unknown Source)
        at sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
Caused by: java.lang.ClassNotFoundException: uk.xxx.mobiledock.MobileDockException
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 7 more
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main"

我还设置了 exec maven 插件,运行 mvn exec:java -Dexec.mainClass=uk.xxx.mobiledock.PCSyncApplication 会按预期运行程序。

这里是如何设置 exec maven 插件

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>exec-maven-plugin</artifactId>
    <version>1.4.0</version>
    <executions>
        <execution>
            <goals>
                <goal>java</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <includePluginDependencies>true</includePluginDependencies>
        <mainClass>uk.xxx.mobiledock.PCSyncApplication</mainClass>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>uk.xxx</groupId>
            <artifactId>mobile-dock-support</artifactId>
            <version>0.0.1-SNAPSHOT</version>
            <scope>system</scope>
            <systemPath>${project.build.directory}/../src/main/libs/mobile-dock-support.jar</systemPath>
        </dependency>
    </dependencies>
</plugin>

【问题讨论】:

  • 应该避免系统范围的依赖关系导致问题,如您所见......部署到存储库管理器中,就是这样......

标签: java maven maven-shade-plugin exec-maven-plugin


【解决方案1】:

好的,那么问题似乎是 shade 插件没有将系统依赖项复制到 uber jar。有几种“正确”的方法可以解决这个问题

  1. 使用mvn install将依赖项安装到本地maven存储库

  2. 使用存储库管理器,例如 Nexus

但是,如果您像我一样没有上述两个选项,因为它是一个协作项目,并且没有像 Nexus 这样的选项,那么这就是我为使其正常工作所做的工作

使用 maven 依赖插件将任何系统依赖复制到相对于打包的 jar 的某个位置,例如。

<plugin>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>copy-dependencies</goal>
            </goals>
            <configuration>
                <outputDirectory>${project.build.directory}/lib</outputDirectory>
                <includeArtifactIds>mobile-dock-support</includeArtifactIds>
            </configuration>
        </execution>
    </executions>
</plugin>

将复制的 jar 添加为 uber jar 清单文件中的类路径的一部分,例如。

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>2.4.2</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
            <configuration>
                <transformers>
                    <transformer
                        implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                        <manifestEntries>
                            <Main-Class>uk.xxx.mobiledock.PCSyncApplication</Main-Class>
                            <Class-Path>lib/mobile-dock-support-${mobile-dock-support.version}.jar</Class-Path>
                        </manifestEntries>
                    </transformer>
                </transformers>
            </configuration>
        </execution>
    </executions>
</plugin>

【讨论】:

    猜你喜欢
    • 2019-01-26
    • 1970-01-01
    • 2021-05-01
    • 1970-01-01
    • 2011-05-29
    • 2022-01-03
    • 2015-10-26
    • 2019-07-09
    • 1970-01-01
    相关资源
    最近更新 更多