39

我创建了一个可执行 jar 并使用 commons-cli 让用户能够在启动客户端时指定命令行参数。一切正常。但是,当我打印 jar 的使用说明时,我想显示以下内容:

usage: java -jar myprog.jar <options> <file>
--help Display the help message
--debug Enable debugging
....

使用 commons-cli 可以轻松打印所有选项。但是,“使用”行是头疼的。我似乎无法找到从传递给应用程序的 args[] 中获取“myprog.jar”名称的方法。

有什么简单的方法可以做到这一点吗?我可以使用一种非常复杂的方法从我的类的类加载器中进行回溯,并确定它是否包含在一个 jar 中,但这对于应该是一个非常简单的问题来说似乎是一个相当丑陋的答案。

private String getPath(Class cls) {
    String cn = cls.getName();
    String rn = cn.replace('.', '/') + ".class";
    String path =
            getClass().getClassLoader().getResource(rn).getPath();
    int ix = path.indexOf("!");
    if(ix >= 0) {
        return path.substring(0, ix);
    } else {
        return path;
    }
}
4

2 回答 2

61

干得好:

new java.io.File(SomeClassInYourJar.class.getProtectionDomain()
  .getCodeSource()
  .getLocation()
  .getPath())
.getName()

编辑:我看到您对 getSourceCode API 的评论。好吧,这可能是您在 Java 中可以做到的最好的事情。关于getCodeSource()返回null,我认为它主要发生在java.lang.*源位置“隐藏”的类和其他特殊类上。不过应该为您自己的课程工作。

于 2012-06-22T15:35:31.870 回答
2

在任何情况下,您都应该在调用 getPath() 之前添加一个 .toURI()。那是因为 java 的 URL 实现中的一些怪癖 - 有关详细信息,请参阅如何对 URL 进行编码以避免 java中的特殊字符。

于 2014-03-10T09:59:57.893 回答