You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

jpackage打包的Windows Java应用无法找到Jar包中的类

jpackage打包后运行报错NoClassDefFoundError,但直接Java命令正常的问题

问题现象

用jpackage打包Java应用后,目录结构和配置文件看似正常,但运行生成的EazyCNC.exe时出现以下错误:

C:\Users\nyholku>eazycnc-build\bundle\EazyCNC\EazyCNC.exe
[0.004s][warning][gc] -XX:+PrintGC is deprecated. Will use -Xlog:gc instead.
[0.017s][info   ][gc] Using G1
Error: Unable to initialize main class eazycnc.Main
Caused by: java.lang.NoClassDefFoundError: purejavahidapi/InputReportListener

但直接使用Java命令运行却正常:

C:\Users\nyholku\eazycnc-build\bundle\EazyCNC>java -cp app/* eazycnc.Main

打包后的目录结构

根目录:

19.11.2023  15.49    <DIR>          app
19.11.2023  15.49           562 688 EazyCNC.exe
19.11.2023  15.49    <DIR>          runtime
               1 File(s)        562 688 bytes
               4 Dir(s)  417 389 883 392 bytes free

app目录内容:

Directory of C:\Users\nyholku\eazycnc-build\bundle\EazyCNC\app
 
19.11.2023  15.49    <DIR>          .
19.11.2023  15.49    <DIR>          ..
19.11.2023  15.49               262 .jpackage.xml
19.11.2023  15.49           385 091 commons-lang3-3.2.1.jar
19.11.2023  15.49               653 EazyCNC.cfg
19.11.2023  15.49         3 421 155 EazyCNC.jar
19.11.2023  15.49             4 928 humble-video-all-0.3.0.jar
19.11.2023  15.49         1 509 440 jna-5.6.0.jar
19.11.2023  15.49         2 735 878 jna-platform-5.6.0.jar
19.11.2023  15.49        11 712 967 jogamp-fat.jar
19.11.2023  15.49            65 966 json-20200518.jar
19.11.2023  15.49           195 713 miglayout-3.7.jar
19.11.2023  15.49           199 631 purejavacomm-1.0.1.x.jar
19.11.2023  15.49           118 138 purejavahidapi-0.0.13.jar
19.11.2023  15.49           127 628 vecmath.jar
              13 File(s)     20 477 450 bytes
               2 Dir(s)  417 401 921 536 bytes free

生成的配置文件EazyCNC.cfg

[Application]
app.mainjar=$APPDIR\EazyCNC.jar
app.classpath=$APPDIR\commons-lang3-3.2.1.jar
app.classpath=$APPDIR\humble-video-all-0.3.0.jar
app.classpath=$APPDIR\jna-5.6.0.jar
app.classpath=$APPDIR\jna-platform-5.6.0.jar
app.classpath=$APPDIR\jogamp-fat.jar
app.classpath=$APPDIR\json-20200518.jar
app.classpath=$APPDIR\miglayout-3.7.jar
app.classpath=$APPDIR\purejavacomm-1.0.1.x.jar
app.classpath=$APPDIR\purejavahidapi-0.0.13.jar
app.classpath=$APPDIR\vecmath.jar
 
[JavaOptions]
java-options=-Djpackage.app-version=1.0
java-options=-Xmx1024m
java-options=-XX:+UseG1GC
java-options=-XX:MaxGCPauseMillis=50
java-options=-XX:+PrintGC

Ant构建配置

jpackage相关target:

<target name="jpackage-windows" if="is_windows" depends="init">
    <exec executable="${jpackage}" dir=".">
        <arg value="--win-console" />
        <arg value="--type" />
        <arg value="app-image" />
        <arg value="--verbose" />
        <arg value="--dest" />
        <arg value="${bundle-dir}/" />
        <arg value="--name" />
        <arg value="EazyCNC" />
        <arg value="--main-jar" />
        <arg value="EazyCNC.jar" />
        <arg value="--java-options" />
        <arg value="-Xmx1024m -XX:+UseG1GC -XX:MaxGCPauseMillis=50 -XX:+PrintGC" />
        <arg value="--resource-dir" />
        <arg value="${resource-dir}" />
        <arg value="--input" />
        <arg value="${jpackage-input-dir}" />
        <arg value="--runtime-image" />
        <arg value="${java-runtime-dir}" />
        <arg value="--temp" />
        <arg value="${build-dir}/wix-tempfiles" />
    </exec>
</target>

部分构建变量:

<property name="app-image-type" value="exe" />
<property name="jdk-loc" value="C:\Program Files\Java\jdk-11" />
<property name="jpackage" value="C:\Program Files\Java\jdk-21\bin\jpackage.exe" />
<property name="jlink" value="C:\Program Files\Java\jdk-11\bin\jlink.exe" />
<property name="targetos" value="windows" />
<property name="pathsep" value=";" />
<property name="resource-dir" value="package-resources/windows" />

Ant输出的其他变量:

[echo] os.name           : Windows 10
[echo] jdk-loc           : C:\Program Files\Java\jdk-11
[echo] fxant-loc         : ${fxant-loc}
[echo] basedir           : C:\Users\nyholku\eazycnc-project
[echo] build-dir         : C:\Users\nyholku/eazycnc-build
[echo] lib-dir           : ./lib
[echo] src-dir           : ./src
[echo] dist-dir          : ./downloads
[echo] temp-dir          : C:\Users\nyholku/eazycnc-build/temp-dir
[echo] classes-dir       : C:\Users\nyholku/eazycnc-build/classes
[echo] eazycnc_version   : 2.0.39
[echo] jpackage-input-dir: C:\Users\nyholku/eazycnc-build/jlink-input

问题原因

问题出在EazyCNC.cfg的classpath配置上:Windows下的ini格式配置文件中,重复的键(这里是app.classpath)会被后续条目覆盖,最终生效的classpath只有最后一行的$APPDIR\vecmath.jar,导致其他依赖包(包括purejavahidapi-0.0.13.jar)不在类路径中,从而抛出NoClassDefFoundError。

而直接用java -cp app/*命令时,Windows的命令行shell会将app/*通配符展开为所有jar文件,类路径包含了所有依赖,因此可以正常运行。

另外,使用JDK21的jpackage搭配JDK11的运行时镜像,可能在自动生成classpath配置时出现了格式兼容问题,导致生成了多个重复的app.classpath条目,而非合并为单个分号分隔的条目。

解决方案

方案1:手动修改配置文件

编辑app/EazyCNC.cfg,将所有app.classpath行合并为一行,用分号分隔所有jar路径:

[Application]
app.mainjar=$APPDIR\EazyCNC.jar
app.classpath=$APPDIR\commons-lang3-3.2.1.jar;$APPDIR\humble-video-all-0.3.0.jar;$APPDIR\jna-5.6.0.jar;$APPDIR\jna-platform-5.6.0.jar;$APPDIR\jogamp-fat.jar;$APPDIR\json-20200518.jar;$APPDIR\miglayout-3.7.jar;$APPDIR\purejavacomm-1.0.1.x.jar;$APPDIR\purejavahidapi-0.0.13.jar;$APPDIR\vecmath.jar

修改后重新运行EazyCNC.exe即可。

方案2:在Ant构建中显式指定classpath

修改Ant的jpackage执行配置,添加--classpath参数,将所有依赖jar用分号拼接后传入,避免依赖jpackage自动生成classpath:

<target name="jpackage-windows" if="is_windows" depends="init">
    <exec executable="${jpackage}" dir=".">
        <arg value="--win-console" />
        <arg value="--type" />
        <arg value="app-image" />
        <arg value="--verbose" />
        <arg value="--dest" />
        <arg value="${bundle-dir}/" />
        <arg value="--name" />
        <arg value="EazyCNC" />
        <arg value="--main-jar" />
        <arg value="EazyCNC.jar" />
        <!-- 新增classpath参数 -->
        <arg value="--classpath" />
        <arg value="commons-lang3-3.2.1.jar;humble-video-all-0.3.0.jar;jna-5.6.0.jar;jna-platform-5.6.0.jar;jogamp-fat.jar;json-20200518.jar;miglayout-3.7.jar;purejavacomm-1.0.1.x.jar;purejavahidapi-0.0.13.jar;vecmath.jar" />
        <arg value="--java-options" />
        <arg value="-Xmx1024m -XX:+UseG1GC -XX:MaxGCPauseMillis=50 -XX:+PrintGC" />
        <arg value="--resource-dir" />
        <arg value="${resource-dir}" />
        <arg value="--input" />
        <arg value="${jpackage-input-dir}" />
        <arg value="--runtime-image" />
        <arg value="${java-runtime-dir}" />
        <arg value="--temp" />
        <arg value="${build-dir}/wix-tempfiles" />
    </exec>
</target>

重新执行Ant构建,生成的配置文件会自动包含正确的合并后classpath。


内容的提问来源于stack exchange,提问作者nyholku

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 06:18:11