复杂的Java命令行参数化

时间:2013-12-10 15:30:16

标签: java command-line-interface

我正在尝试找到最佳解决方案,使我的Java应用程序可以通过命令行进行配置。我面临的问题是我需要配置复杂的嵌套结构。

实施例

考虑以下结构(以大写字母开头的单词,缩进表示属性)

  • InterfaceOptimizer
    • AbstractProblem
      • 尺寸
    • populationSize
    • numberOfRuns

我需要从命令行中选择的第一件事是实现InterfaceOptimizer的类(例如java App -O SomeOptimizer)。接下来要选择的是AbstractProblem,它本身会采用另一个参数dimension(例如java App -O SomeOptimizer -- -P ConcreteProblem

这里的问题是某些参数是特定类的参数,并取决于首先给出的参数。 ConcreteProblem可能采用与OtherProblem不同的参数。

经过测试的库

我测试了args4jcommons-cli,但是在尝试做我需要的时候都失败了。

WEKA(一种流行的机器学习工具)似乎已经针对这个问题实现了a solution,但它基本上要求每个类实现它自己的CLI解析器(并且它们似乎存在一致性问题)。

这个问题有没有好的解决方案(现有的库?)?建议的模式是什么来解决这个问题?

3 个答案:

答案 0 :(得分:1)

我认为你可能只需编写选择正确类的代码。之后,您可以使用反射将值放入对象和/或验证命令行选项是否合适。注释会在这里帮助你,因为你可以使用它来帮助驱动反射引擎,以及生成文档,例如命令行帮助。

答案 1 :(得分:0)

只是一个想法,但这看起来很像将对象图反序列化给我。 Java具有内置的对象序列化/反序列化。例如。从XML文件构造一个对象:

FileInputStream is = new FileInputStream(new File("config.xml"));
XMLDecoder d = new XMLDecoder(is);
InterfaceOptimizer obj = (InterfaceOptimizer)d.readObject();

要获取初始配置文件(作为可手动更改的起点),可以通过编程方式创建对象,然后使用以下命令将其转储到XML文件:

FileOutputStream os = new FileOutputStream(new File("config.xml"));
XMLEncoder e = new XMLEncoder(os);
e.writeObject(myOptimizerObject);

然后,您必须只在命令行上传递配置文件。

答案 2 :(得分:0)

我不知道这个CLI是如何复杂的,除非我不完全理解。你想要

java X classname problem dimension population numberruns

现在,即使是部分

classname problem dimension

或只是

problem dimension

可以重复,很容易:

  • 首先,从最后获取人口和数量,并检查 为了有效性。
  • 检查剩下的参数是否是3的倍数(假设 可以重复classname problem dimension
  • 对于每个3元组的参数,解析并加载该类,检查是否 它接受给定的问题,并检查维度参数。一个 这样做的简单方法是只调用构造函数或一些 该类的初始化代码,如下所示:

代码(待完善):

try {
    IOptimizer io = (IOptimizer) Class.forName(args[n]).newInstance();
    io.init(args[n+1], args[n+2]);
}
catch (ClassNotFoundException ...) { ... }
catch (ClassCastException ...) { ... }
catch (InvalidArgumentException ...) { ... }

请注意,如果某些问题需要多个参数,您可以这样执行:

 java X classname problem3 a,b,c population numbers

然后你可以在init()方法中拆分维度参数。