有没有办法从任意在当前JVM中运行的代码中找到用于启动当前JVM的主类的名称?
所谓任意,是指该代码不一定在主线程中运行,或者可能在main被调用之前就在主线程中运行(例如,用户提供的java.system.classloader中的代码,在main之前运行,因为它用于加载main)- 因此无法检查调用堆栈。
有没有办法从任意在当前JVM中运行的代码中找到用于启动当前JVM的主类的名称?
所谓任意,是指该代码不一定在主线程中运行,或者可能在main被调用之前就在主线程中运行(例如,用户提供的java.system.classloader中的代码,在main之前运行,因为它用于加载main)- 因此无法检查调用堆栈。
这是我能提供的最接近解决方案,你可以从这里开始。我不能保证它是真正可移植的,如果任何方法调用另一个类的主方法,它将无法工作。如果你找到更简洁的解决方案,请告诉我。
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;
}
}