【问题标题】:Detect main class检测主类
【发布时间】:2010-05-20 08:10:58
【问题描述】:

我可以检测我的应用程序的主类吗?一个,要么在命令行上给出,要么从命令行给出的 jar 中加载?

如果这不可能,为什么不呢?

编辑:也许我不清楚。我知道我的应用程序总是可以有很多入口点,但是当应用程序运行时,只有一个入口点用于启动当前的 JVM。这是我需要知道的。

【问题讨论】:

标签: java


【解决方案1】:

首先,一个应用程序可以有几个入口点。它只是一个包含名为 main 且参数类型为 String[] 的公共静态方法的类。

所以,简短的回答,,一组类可能有几个可能的入口点。

如果你想列出一个应用程序的所有入口点,你只需要遍历类并寻找这样的 main 方法。

如果你创建一个"runnable jar-file",Manifest 文件中会有一个类似的条目

Main-Class: MyPackage.MyClass

它指定了应用程序的主类。

【讨论】:

  • 全部正确,但我需要正在运行的程序的当前实例在程序运行时启动的方式。
  • @Daniel:在这种情况下,他的简短回答适用。
  • @R. Bemrose:对不起,我不明白。他的简短回答指出,一组类可能有多个入口点。这是对的。但我要求的不是所有可能的入口点,而是用于启动当前应用程序实例的入口点。
  • 考虑下面的二类程序:class Test1 { public static void main(String[] args) { new Thread(new SomuRunnable()).start(); } } class Test2 { public static void main(String[] args) { new Thread(new SomuRunnable()).start(); } } 没有办法知道调用了两个主方法中的哪一个来启动这个程序(除非你修改主方法来记住哪个之一)。
  • 啊,有趣的工具。我不知道!事实证明,jps 连接到 HotSpot VM(即 Suns 拥有的虚拟机)并进行一些检测。也就是说,它很可能与特定的 vm 相关联,因此可能仍然没有独立于平台的解决方案。 (我不确定 jps 命令是如何实现的。)
【解决方案2】:

一种可能性是使用线程的堆栈跟踪并查找启动类。但是,这只有在跟踪位于初始主线程上时才有效。

Throwable t = new Throwable();
StackTraceElement[] elems = t.getStackTrace();
String initClass = elems[elems.length - 1].getClassName();
String initMethod = elems[elems.length - 1].getMethodName();

这也将帮助您了解这有多么困难。最初的主线程甚至不必再运行了。您甚至可以尝试将此检查直接放在其中一个类的 main 静态方法中,但仍然无法正常工作。可以通过反射从另一个类执行 main 方法,并且启动方法本身可能已经在启动线程以外的线程上运行。

对于 Swing 应用程序,标准习惯用法是让启动的主线程在激活第一个表单后终止。因此,在这些情况下,您可以确定主类和启动线程不再运行。

【讨论】:

  • 是的,你解释了为什么你的方法不能解决我的问题。
【解决方案3】:

您可以获得堆栈跟踪,例如

StackTraceElement[] stack = new Throwable().getStackTrace();

在命令行应用程序中,最后一个元素将是主类:

System.out.println(stack[stack.length - 1].getClassName());

servlet、applet 或其他插件更复杂(您必须遍历堆栈,寻找与当前线程具有相同ClassLoader 的类。)

【讨论】:

  • 当您提交您的答案时,我正在输入类似的答案。但是,在大多数情况下,这不会很好地工作(请参阅我的回答)。
  • 这不适用于任何使用多线程的应用程序(例如,我们的每个 GUI 应用程序、Tomcat 服务器应用程序等)
  • 第一行中的错字,因为它返回一个数组。正如@Daniel 指出的那样,这可以解决完全不同的方法。
  • 修复了数组部分。不过,您对多线程问题是正确的。
【解决方案4】:

这很干净:从命令行传入类名作为程序参数。从那里,您可以使用反射等实例化它。

java foo.bar.MyMainClass foo.bar.MyMainClass

【讨论】:

    猜你喜欢
    • 2017-09-23
    • 1970-01-01
    • 2019-09-24
    • 2018-02-21
    • 1970-01-01
    • 2014-01-13
    • 2012-06-24
    • 2019-11-10
    • 1970-01-01
    相关资源
    最近更新 更多