如何获取运行桌面应用程序的 JAR 的名称?
我创建了简单的库 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在特定的 JAR 中。
是否有更好/通用的解决方案,可以提供 JAR 的名称/位置/MANIFEST.MF,该 JAR 是桌面应用程序运行的?
感谢您的帮助
马尔辛
I have created simple library AppInfo providing an easy way to show always valid, automatic updated information about a version of running software in Java applications, which is especially useful in conjunction with automatic builds from CI server.
In my library it is necessary to read MANIFEST.MF from JAR (in case of a desktop application) which is the end application run from (not from any other on a classpath). Currently I use a solution based on an idea taken form Sun's forum (which link to is not working anymore):
String classContainer = classFromRightJar.getProtectionDomain().getCodeSource().getLocation().toString();
URL manifestUrl = new URL("jar:" + classContainer + "!/META-INF/MANIFEST.MF");
and it generally works, but it forces developer of a desktop application to create additional bean configured with a name of a class which is located in specific JAR.
Is there a better/generic solution which gives a name/location/MANIFEST.MF of/from JAR which is a desktop application run from?
Thanks for your help
Marcin
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有一个系统属性“sun.java.command”,其中包含 jar 名称或类名称以及所有 main() 方法参数。因此,对于调用,
您将获得“test.jar arg1 arg2”,而
属性值将是“test.Test arg1 arg2”。
正如该属性的名称所暗示的那样,它不是“官方的”(不必在非 Sun/Oracle 实现上工作)。我查了一下Java 7,不知道什么时候推出的。
There's a system property "sun.java.command" that contains either the jar name or the class name plus all the main() method arguments. So for invocation
you'd get "test.jar arg1 arg2" and for
the property value would be "test.Test arg1 arg2".
As the property's name would suggest, it's not "official" (does not have to work on non-Sun/Oracle implementations). I checked it on Java 7, don't know when it was introduced.
“强制桌面应用程序的开发人员创建额外的 bean...”您的意思是您不希望他们根本不需要引用任何应用程序的类名吗?如果是这样,那么可能没有任何 100% 可靠的方法来做到这一点,但一种方法可能是调用 java.awt.Frame.getFrames() 并检查 JFrame 的非 java* 子类。例如:
如果应用程序没有对 JFrame/Frame 本身进行子类化,这将会失败,因此您可能还想遍历框架的子级来检查子级的子类。
另一种方法可能是获取 Thread.getAllStackTraces() 并遍历所有线程(尤其是“主”线程),查找启动应用程序的主类,然后获取该类的清单。
不过,正如我所说,可能没有 100% 可靠的方法来做到这一点,因为应用程序可能不使用任何自定义子类,并且线程的堆栈可能混合有不同的应用程序。
By "forces developer of a desktop application to create additional bean..." do you mean that you don't want them to ever have to reference any of their application's class names at all? If so, then there probably isn't any 100% reliably way of doing it, but one approach could be to call java.awt.Frame.getFrames() and check for non-java* subclasses of JFrame. E.g.:
This will break down if the application doesn't subclass the JFrame/Frame themselves, so you might also want to walk through the children of the frame to check for subclasses of the children as well.
Another approach might be to grab Thread.getAllStackTraces() and walk through all of them (especially the "main" thread) looking for the main class that started the application, and then grab the manifest for that class.
As I say, though, there probably isn't any 100% reliable way to do it, since the application may not use any custom subclasses and the stacks for the threads might have a mixture of different applications.