从 main() 方法中获取可执行 jar 的名称

我创建了一个可执行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;
    }
}

答案 1

给你:

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

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


答案 2

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


推荐