2011-11-26 127 views
2

主类的名字有没有办法找到用来启动当前JVM的主类的名称,从在JVM上运行任意代码?由于任意,我的意思是代码不一定在主线程中运行,或者可能在main被调用之前在主线程中运行(例如,用户提供的java.system.classloader中的代码,它在main之前运行,因为它用于加载main) - 因此检查调用堆栈是不可能的。移植的方式找到Java代码

+0

在JVM上,首先调用主类的主要方法。 (也http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.1见)那么,你是什么意思“可以在主线程中运行的主要甚至被称为前” 。我认为这个短语提到“静态初始化程序”或“线程#运行()”。 – cocoatomo

+0

@cocoatomo:我错过了一些东西。该链接是否显示解决原始海报问题的解决方案?如果是这样,虽然我回顾了一下,但我错过了它。 –

+0

@Hovercraft全鳗鱼:对不起,我错把推回车键我已经完成了我的意见了。我想了解BeeOnRope的意图,所以我要确保的条件BeeOnRope希望见面。 – cocoatomo

回答

8

这是最接近我可以,你可以把它从这儿过得也不能保证它是真正便携的,如果任何方法调用的另一种主要方法是行不通class.Let我知道如果你发现更干净的解决方案

import java.util.Map.Entry; 

public class TestMain { 

    /** 
    * @param args 
    * @throws ClassNotFoundException 
    */ 
    public static void main(String[] args) throws ClassNotFoundException { 
     System.out.println(findMainClass()); 
    } 

    public static String findMainClass() throws ClassNotFoundException{ 
     for (Entry<Thread, StackTraceElement[]> entry : Thread.getAllStackTraces().entrySet()) { 
      Thread thread = entry.getKey(); 
      if (thread.getThreadGroup() != null && thread.getThreadGroup().getName().equals("main")) { 
       for (StackTraceElement stackTraceElement : entry.getValue()) { 
        if (stackTraceElement.getMethodName().equals("main")) { 

         try { 
          Class<?> c = Class.forName(stackTraceElement.getClassName()); 
          Class[] argTypes = new Class[] { String[].class }; 
          //This will throw NoSuchMethodException in case of fake main methods 
          c.getDeclaredMethod("main", argTypes); 
          return stackTraceElement.getClassName(); 
         } catch (NoSuchMethodException e) { 
          e.printStackTrace(); 
         } 
        } 
       } 
      } 
     } 
     return null; 
    } 
} 
+0

谢谢,我知道这种方法,但不幸的是它不适用于我,因为它还需要在包含main的类加载之前工作(请参阅我的评论添加到类加载器的问题)。 – BeeOnRope

+0

无论如何都要接受这个问题,因为它确实是对的,如果我愿意推迟基于主类的工作,我可以使用它。 – BeeOnRope

+0

顺便说一句,如果你想避免更多的误报,我想你可以看看调用main的类,并验证它是一个期望的JDK特定类 - 尽管这会引入对特定JDK或JDK的依赖。 – BeeOnRope