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

Posted

技术标签:

【中文标题】从main()方法中获取可执行jar的名称[重复]【英文标题】:Get name of executable jar from within main() method [duplicate] 【发布时间】:2012-06-24 20:56:46 【问题描述】:

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

【问题讨论】:

试过***.com/questions/320542/… ? 我确实已经看到了那个链接,但它看起来也几乎是一个“黑客”。我不敢相信没有更直接的解决方案。此外,API 声明“getCodeSource()”可能返回 null,但没有详细说明在什么情况下,所以我自然想知道这是否是一种“故障安全”方法。 【参考方案1】:

给你:

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

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

【讨论】:

谢谢 - 这与@Charles 在 SO 链接中指出的相同。我上面提到的最大的担心是getCodeSource()的api表明它可以为空,但没有详细说明在什么条件下。 另一个问题是它没有考虑到类文件可能嵌套在档案中的事实。所以我仍然需要检查! 子字符串。就像我说的,Java 没有更好的解决方案似乎有点笨拙。 这主要是因为很少有理由知道您正在运行的 jar 文件的名称。功能应该(理想情况下)独立于名称。【参考方案2】:

在任何情况下,您都应该在调用 getPath() 之前添加一个 .toURI()。那是因为 java 的 URL 实现中的一些怪癖 - 有关详细信息,请参阅 how to encode URL to avoid special characters in java。

【讨论】:

以上是关于从main()方法中获取可执行jar的名称[重复]的主要内容,如果未能解决你的问题,请参考以下文章

JAVA如何在main()中取得当前jar的名字和路径?

将 Spring boot 项目打成可执行Jar包,及相关注意事项(main-class缺少 xsd重复打包依赖)

将 Spring boot 项目打成可执行Jar包,及相关注意事项(main-class缺少 xsd重复打包依赖)

将 Spring boot 项目打成可执行Jar包,及相关注意事项(main-class缺少 xsd重复打包依赖)

将 Spring boot 项目打成可执行Jar包,及相关注意事项(main-class缺少 xsd重复打包依赖)

将 Spring boot 项目打成可执行Jar包,及相关注意事项(main-class缺少 xsd重复打包依赖)