GraalVM构建Windows可执行文件时ClassNotFoundException问题排查
GitHub Actions上Liberica NIK生成的Windows可执行文件找不到主类,但本地正常
我在GitHub Actions上构建Java 8项目,流程是先打包成包含依赖的独立Jar包,再通过Liberica NIK生成Windows可执行文件。本地使用相同版本Liberica NIK构建的exe可正常运行,但GitHub Actions生成的exe运行时抛出以下异常:
Error: Could not find or load main class de.teatime08.Main
Caused by: java.lang.ClassNotFoundException: de.teatime08.Main
用于生成exe的Jar包本身能正常运行,我尝试调整GraalVM及maven-assembly-plugin的多种配置仍未解决问题,当前配置如下:
pom.xml中maven-assembly-plugin配置
<plugin> <artifactId>maven-assembly-plugin</artifactId> <version>3.7.1</version> <executions> <execution> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <appendAssemblyId>false</appendAssemblyId> <archive> <manifest> <!--<addClasspath>true</addClasspath>--> <!--<classpathPrefix>lib/</classpathPrefix>--> <mainClass>de.teatime08.Main</mainClass> </manifest> </archive> </configuration> </plugin>
GitHub Workflow关键部分
name: GraalVM SimpleInternetMonitor builds on: [push, pull_request] jobs: build: name: SimpleInternetMonitor on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: matrix: os: [windows-latest] steps: - uses: actions/checkout@v4 # Setup the GraalVM with liberica, to avoid executing UI triggers - uses: graalvm/setup-graalvm@v1 with: java-version: '21' distribution: 'liberica' # distribution: 'graalvm-community' java-package: 'jdk+fx' github-token: ${{ secrets.GITHUB_TOKEN }} native-image-job-reports: 'true' cache: 'maven' # Execute the build script - name: Build run: | .\buildNative_from_Windows.ps1 - name: Upload Java Executable file uses: actions/upload-artifact@v4 with: name: SimpleInternetMonitor.jar path: target\SimpleInternetMonitor.jar - name: Upload Executable uses: actions/upload-artifact@v4 with: name: SimpleInternetMonitor.exe path: target-native\SimpleInternetMonitor.exe
构建脚本(buildNative_from_Windows.ps1)
mvn -B -ntp clean install compile -Pnative package "-Djava.awt.headless=false" "-Dmaven.tests.skip=true" "-Dorg.slf4j.simpleLogger.defaultLogLevel=WARN" echo "Creating target-native dir" New-Item -ItemType Directory -Force -Path target-native echo "Starting Native Build on Windows." native-image ` -g -O0 ` "-Djava.awt.headless=false" ` --link-at-build-time ` --enable-http ` --enable-https ` "-H:+UnlockExperimentalVMOptions" ` "-H:ResourceConfigurationFiles=native-resources-configuration.json" ` -jar .\target\SimpleInternetMonitor.jar ` .\target-native\SimpleInternetMonitor
已尝试的解决方案
- 切换Liberica与GraalVM社区版
- 修改pom.xml中的
<addClasspath>和<classpathPrefix>配置 - 调整Maven构建命令(使用-Pnative或native:compile)
- 尝试使用JDK 8编译(未成功)
- 在native-image命令中添加--no-fallback等参数
- 排查GitHub分支提交中的其他尝试记录
更新:问题已解决
推测问题根源是GitHub Actions环境中生成的镜像默认进入了回退模式,没有以原生方式运行,而是依赖系统安装的JRE。在native-image命令中添加--no-fallback参数强制禁用回退模式后,生成的exe可正常运行。
内容的提问来源于stack exchange,提问作者TeaTiMe08
相关产品推荐
相关产品推荐

