Apache Commons CLI DefaultParser NoSuchMethod错误

9

当我尝试创建 DefaultParser 实例时,我遇到了一个 Exception in thread "main" java.lang.NoSuchMethodError: org.apache.commons.cli.Options.hasShortOption(Ljava/lang/String;)Z 的异常。

我的代码:

    Options options = new Options();
    // option for day offset
    options.addOption(new Option("d", "day", true, "Day offset. -d 7 will 
    request for last weeks data"));
    //options.addOption("d", "day", true, "Day offset. -d 7 will request for last weeks data");

    CommandLineParser parser = new DefaultParser();
    CommandLine cmd = parser.parse(options, args);

堆栈跟踪:

Exception in thread "main" java.lang.NoSuchMethodError: org.apache.commons.cli.Options.hasShortOption(Ljava/lang/String;)Z
    at org.apache.commons.cli.DefaultParser.handleShortAndLongOption(DefaultParser.java:491)
    at org.apache.commons.cli.DefaultParser.handleToken(DefaultParser.java:243)
    at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:120)
    at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:76)
    at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:60)
    at domain.Main.main(Main.java:60)

第60行是这样的:

    CommandLine cmd = parser.parse(options, args);

我只是遵循官方Apache文档-https://commons.apache.org/proper/commons-cli/usage.html

是的,库可以在jar包中找到。

尝试运行了几个组合,但它们都没有真正起作用。好处是我得到了一个不同的错误。有点不同。

堆栈跟踪#2

Exception in thread "main" java.lang.NoSuchMethodError: org.apache.commons.cli.Options.getMatchingOptions(Ljava/lang/String;)Ljava/util/List;
    at org.apache.commons.cli.DefaultParser.handleLongOptionWithoutEqual(DefaultParser.java:404)
    at org.apache.commons.cli.DefaultParser.handleLongOption(DefaultParser.java:384)
    at org.apache.commons.cli.DefaultParser.handleToken(DefaultParser.java:239)
    at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:120)
    at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:76)
    at org.apache.commons.cli.DefaultParser.parse(DefaultParser.java:60)
    at domain.Main.main(Main.java:61)

你使用的是哪个版本? - mcacorner
Apache CLI 版本为 1.4 @mcacorner - anon
1
你是类路径污染的受害者。 - rkosegi
1
@ZdeněkDavid:从mvn dependency:tree开始 - 检查其输出并查找重复依赖项。 - rkosegi
2
在你的主方法中,尝试输出以下命令的结果:org.apache.commons.cli.Options.class.getProtectionDomain().getCodeSource().getLocation().toURI()org.apache.commons.cli.DefaultParser.class.getProtectionDomain().getCodeSource().getLocation().toURI()。它们都应该输出相同的文件,但可能不在你的设置中。你可以通过查看 System.getProperty("java.class.path") 的输出来进一步调查你的类路径。如果你正在使用maven或gradle,mvn dependency:treegradle dependencies 将为你提供更多的见解。 - dpr
显示剩余2条评论
2个回答

2
那就是说,avro-tools-1.8.2.jar自带了一个commons-cli的版本,与您想要使用的版本冲突。根据avro-tools-1.8.2.jar的META-INF\DEPENDENCIES文件,它似乎是版本1.2。基本上您有三个选择:
1. 使用与avro-tools-1.8.2.jar使用的相同版本的commons-cli。即commons-cli-1.2 2. 确保您的commons-cli版本在avro-tools-1.8.2.jar之前出现在类路径中。 3. 重新考虑使用avro-tools并删除依赖项(如果确实不需要)。
如果您确实需要avro-tools,则第一种选项可能是正确的方法。第二个选项可能会首先解决问题,但由于将使用冲突的1.4版本的commons-cli,可能会破坏avro-tools的功能。如果您确实不需要avro-tools(不是指avro而是特定的tools jar),我建议删除avro-tools依赖项。avro-tools似乎不适合作为依赖项被拉取,而是更像是一个独立的应用程序。它捆绑了一堆外部库,这些库都可能在您这边引起版本冲突。

0

我使用了Apache Commons CLI 1.4测试了您的代码,它运行良好。

编辑:

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.DefaultParser;


public class Main {
    public static void main(String[] args) throws ParseException {
        Options options = new Options();
        // option for day offset
        options.addOption(new Option("d", "day", true, "Day offset. -d 7 will request for last weeks data"));
        // options.addOption("d", "day", true, "Day offset. -d 7 will request for last
        // weeks data");

        CommandLineParser parser = new DefaultParser();

        CommandLine cmd = parser.parse(options, args);
        System.out.println(cmd.getParsedOptionValue("day"));


    }
}

我已经使用以下参数运行它: --date 123 和 -d 123
它会打印出 123。
如果错误仍然存在,请复制并粘贴上面的代码,并检查它是否适用于您。

args变量作为参数从主方法public static void main(String[] args)传递。Apache CLI版本为1.4。 - anon
是的,我知道它来自主方法,但你传递给示例的参数是什么? - Martín Zaragoza
你正在创建的选项对象告诉程序它期望这样的输入: --day 值 或者 -d 值 - Martín Zaragoza
1
尝试运行以下命令:java -jar kafka-client-1.0-SNAPSHOT-export.jar -d=1java -jar kafka-client-1.0-SNAPSHOT-export.jar -d 1java -jar kafka-client-1.0-SNAPSHOT-export.jar -d "1" - anon
最终我放弃了,选择了另一个解决方案。仍然好奇为什么它在我的机器上不起作用。 - anon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接