如何获取桌面应用程序运行的JAR的名称?

时间:2010-11-06 19:13:04

标签: java jar manifest manifest.mf

我创建了一个简单的库AppInfo,它提供了一种简单的方法来显示有关Java应用程序中正在运行的软件版本的有效自动更新信息,这与CI服务器的自动构建结合使用时非常有用。

在我的库中,有必要从JAR(在桌面应用程序的情况下)读取MANIFEST.MF,这是从(不是来自类路径上的任何其他应用程序)运行的最终应用程序。目前我使用的解决方案基于Sun的论坛(链接到不再有效)的想法:

String classContainer = classFromRightJar.getProtectionDomain().getCodeSource().getLocation().toString();
URL manifestUrl = new URL("jar:" + classContainer + "!/META-INF/MANIFEST.MF");

它通常可以工作,但它迫使桌面应用程序的开发人员创建另外的bean,该bean配置了一个位于特定JAR中的类的名称。

是否有一个更好的/通用的解决方案,它提供了来自JAR的名称/位置/ MANIFEST.MF,这是从桌面应用程序运行的?

感谢您的帮助 马尔钦

2 个答案:

答案 0 :(得分:2)

有一个系统属性“sun.java.command”,它包含jar名称或类名以及所有main()方法参数。所以对于调用

java -jar test.jar arg1 arg2

你会得到“test.jar arg1 arg2”和

java test.Test arg1 arg2

属性值为“test.Test arg1 arg2”。 正如该属性的名称所暗示的那样,它不是“官方的”(不必在非Sun / Oracle实现上工作)。我在Java 7上查了一下,不知道它何时推出。

答案 1 :(得分:0)

通过“强制桌面应用程序的开发人员创建其他bean ...”,您是否意味着您不希望他们根本不必引用任何应用程序的类名?如果是这样,那么可能没有任何100%可靠的方法,但一种方法可能是调用java.awt.Frame.getFrames()并检查JFrame的非java *子类。 E.g:

for (Frame frame in Frame.getFrames()) {
    if (frame.getClass().getPackage().getName().startsWith("java"))
        continue;
    URL manifestURL = frame.getClass().getResource("/META-INF/MANIFEST.MF");
    // do something with the manifest
}

如果应用程序没有自己子类化JFrame / Frame,那么这将会分解,因此您可能还需要遍历框架的子项以检查子项的子类。

另一种方法可能是获取Thread.getAllStackTraces()并遍历所有这些(特别是“主”线程),寻找启动应用程序的主类,然后获取该类的清单。

正如我所说,可能没有任何100%可靠的方法,因为应用程序可能不使用任何自定义子类,并且线程的堆栈可能混合使用不同的应用程序。