GraalVM构建Picocli项目成功却无法运行,参数不匹配错误求助
在M1芯片的Mac Monterey系统上,基于Java 11、GraalVM 22.3搭建Picocli的Hello World项目,使用Java命令运行完全正常:
java -cp "picocli-4.7.0.jar:FocusStackCLI.jar" FSCLI hello
但通过GraalVM构建本地镜像后,无论是否携带参数运行,都会报“Unmatched argument”错误。
相关代码与配置
Java主类代码
import picocli.CommandLine; import picocli.CommandLine.Command; import picocli.CommandLine.Parameters; @Command(name = "fscli", version = "fscli 1.0", mixinStandardHelpOptions = true) public class FSCLI implements Runnable{ @Parameters(paramLabel = "directory", description = "Directory containing images to focus stack") private String directory; @Override public void run(){ System.out.println(directory); } public static void main(String[] args) { int exitCode = new CommandLine(new FSCLI()).execute(args); System.exit(exitCode); } }
pom.xml配置
<?xml version="1.0" encoding="UTF-8"?> <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>org.example</groupId> <artifactId>FocusStackCLI</artifactId> <version>1.0-SNAPSHOT</version> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <!-- annotationProcessorPaths requires maven-compiler-plugin version 3.5 or higher --> <version>3.8.1</version> <configuration> <annotationProcessorPaths> <path> <groupId>info.picocli</groupId> <artifactId>picocli-codegen</artifactId> <version>4.7.0</version> </path> </annotationProcessorPaths> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>info.picocli</groupId> <artifactId>picocli</artifactId> <version>4.7.0</version> </dependency> </dependencies> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> </properties> </project>
构建本地镜像命令
native-image -cp picocli-4.6.3.jar -jar FocusStackCLI.jar
错误的运行命令
./FocuStackerCLI hello
./FocuStackerCLI FSCLI hello
错误信息
Unmatched argument at index 0: 'hello'
Usage: picocli.AutoComplete [-hV] [@...]
Generates a bash completion script for the specified command class.
[@...] One or more argument files containing options.
-h, --help Show this help message and exit.
-V, --version Print version information and exit.Exit Codes:
0 Successful program execution
1 Usage error: user input for the command was incorrect, e.g., the wrong
number of arguments, a bad flag, a bad syntax in a parameter, etc.
2 The specified command script exists (Specify--forceto overwrite).
3 The specified completion script exists (Specify--forceto overwrite).
4 An exception occurred while generating the completion script.System Properties:
Set the following system properties to control the exit code of this program:
"picocli.autocomplete.systemExitOnSuccess"
callSystem.exit(0)when execution completes normally."picocli.autocomplete.systemExitOnError"
callSystem.exit(ERROR_CODE)when an error occurs.If these system properties are not defined or have value "false", this program
completes without terminating the JVM.Example
java -cp "myapp.jar;picocli-4.6.3.jar"
picocli.AutoComplete my.pkg.MyClass
问题根源
- 依赖版本不匹配:pom.xml中使用的picocli版本是4.7.0,但构建native-image时指定的是4.6.3版本的jar包,版本不一致会导致兼容性问题。
- 主类未明确指定:native-image未找到正确的主类,误将picocli包中的
picocli.AutoComplete作为入口类执行,这也是错误信息显示AutoComplete用法的原因。 - 运行命令文件名拼写错误:构建的jar包名为
FocusStackCLI.jar,但运行时使用的是FocuStackerCLI(拼写错误:Focus→Focu,Stack→Stacker),导致执行的不是正确的本地镜像文件。
解决步骤
- 统一picocli版本:确保构建命令中使用的picocli jar包版本与pom.xml一致,改为4.7.0:
native-image -cp picocli-4.7.0.jar -jar FocusStackCLI.jar - 明确指定主类:在native-image命令中添加
--main-class参数指定你的主类FSCLI,避免native-image误选入口类:
或者,通过maven的native-image --main-class FSCLI -cp "picocli-4.7.0.jar:FocusStackCLI.jar"maven-jar-plugin配置jar包的MANIFEST.MF,添加Main-Class: FSCLI属性,这样native-image会自动识别主类:<build> <plugins> <!-- 保留原有的maven-compiler-plugin --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.3.0</version> <configuration> <archive> <manifest> <mainClass>FSCLI</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build> - 修正运行命令:确认native-image生成的可执行文件名称(默认与jar包名称一致,小写为
focusstackcli),使用正确的文件名运行:./focusstackcli hello
内容的提问来源于stack exchange,提问作者Stephen Swetonic

