5

我正在尝试使用 Apache Commons CLI 库来解析 Eclipse 项目中的命令行选项,大致遵循其使用场景中的示例

我将该commons-cli-1.3.1文件夹添加到libEclipse 项目根目录中的文件夹中。

我将此添加到我的导入中:

import org.apache.commons.cli.*;

这是我最重要的main

    Options options = new Options();
    CommandLineParser parser = new DefaultParser();
    CommandLine cmd = null;
    try {
        cmd = parser.parse( options, args);
    } catch ( ParseException e1 ) {
        System.err.println( "Unable to parse command-line options: "+e1.getMessage() );
        e1.printStackTrace();
    }

它编译没有错误,但是当它运行parser.parse调用时会产生这个错误:

Exception in thread "main" java.lang.IllegalAccessError: tried to access method org.apache.commons.cli.Options.getOptionGroups()Ljava/util/Collection; from class org.apache.commons.cli.DefaultParser

此时我没有使用任何类加载器。

这个错误是什么意思?如何解决错误并解析参数?

4

2 回答 2

6

这很可能是依赖问题。

当您再次编译代码的一个版本的库(在您的情况下为 1.3.1)然后在类路径中使用该库的旧版本运行时,就会发生这种情况。

今天,当我依赖于 commons-cli-1.3.1 时,我遇到了这个问题,但是我的类路径中有 commons-cli-1.2(因为我使用 yarn jar 来启动我的应用程序)

你应该怎么做?

  1. 您可以按照上面的建议尝试降级到 1.2(这对我有帮助)
  2. 查看您的类路径并搜索另一个版本的 commons-cli

您的异常消息的真正含义是什么? 这意味着某些代码在运行时会尝试调用它无权调用的某些方法。例如,这可能是试图调用私有方法。通常这是在编译期间捕获的。

但是,例如,如果您的代码尝试调用某个在 1.3.1 中为公共但在 1.2 中为私有的函数。如果您再次编译 1.3.1 但尝试在类路径中使用 1.2 启动,您将收到这种错误。

希望很清楚。

于 2016-01-20T22:57:44.463 回答
0

我正在使用 commons-cli 来处理我的游戏OpenPatrician的命令行参数。基本上它分为三个部分。允许的命令行参数的定义:

Options opts = new Options();
opts.addOption(HELP_OPTION, "help", false, "Display help");
opts.addOption(OptionBuilder.withLongOpt(VERSION_OPTION)
        .withDescription("Version of this application")
        .create());
opts.addOption(FULLSCREEN_MODE, "fullscreen", false, "fullscreen mode");
opts.addOption(OptionBuilder.withArgName(WINDOWED_MODE)
        .withLongOpt("windowed")
        .hasOptionalArgs(1)
        .withArgName("widthxheight")
        .withDescription("Windowed mode with optional definition of window size like: 1280x780")
        .create());
opts.addOption(GAME_LOCALE, "lang", true, "Specify the locale to use");
opts.addOption(CLIENT_OPTION, "client", false, "Start application in client mode. Currently unused. Either client or server must be specified");
opts.addOption(SERVER_OPTION, "server", false, "Start application in server mode. Currently unused. Either client or server must be specified");

提供包含所有可能参数的帮助消息:

public void printHelp(Options options) {
    HelpFormatter formatter = new HelpFormatter();
    formatter.printHelp( "OpenPatrician", options );
}

当然还有参数的解析:

public CommandLine parseCommandLine(Options options, String[] args) {
    try {
        // parse the command line arguments
        CommandLineParser parser = new PosixParser();
        return parser.parse( options, args );
    }
    catch( ParseException exp ) {
        printHelp(options);
        throw new IllegalArgumentException("Parsing of command line arguments failed", exp);
    }
}

请注意,我在这里使用的是 PosixPaser,而不是默认的解析器。所以这可能有不同的行为。

于 2015-10-04T14:28:59.677 回答