3

Is there any way to find the name of the main class used to launch the current JVM, from arbitrary code running in that JVM?

By arbitrary, I mean that the code is not necessarily running in the main thread, or may be running in the main thread before main has even been called (e.g., code in a user-supplied java.system.classloader, which runs before main since it's used to load main) - so examining the call stack is not possible.

4
  • On a JVM, the main method of the main class is called first. (see also java.sun.com/docs/books/jls/third_edition/html/…) So, what do you mean "may be running in the main thread before main has even been called". I think this phrase mention "static initializer" or "Thread#run()". Commented Nov 26, 2011 at 0:53
  • @cocoatomo: I'm missing something. Does that link show the solution to the original poster's question? If it does, although I reviewed it, I missed it somehow. Commented Nov 26, 2011 at 0:56
  • @Hovercraft Full Of Eels: Sorry, I mistook pushing a return key before I had completed my comment. I want to understand BeeOnRope's intent, so I am going to make sure of conditions BeeOnRope hope to meet. Commented Nov 26, 2011 at 1:05
  • Well the JLS may say that, but it's not true in practice. The main class has to be loaded by a ClassLoader, and that ClassLoader is itself an object, whose class must be loaded before main. Typical classloader implementations, like URLClassLoader will use plenty of other classes in their implementation, which will also be loaded before main. This is easy to see if you write your own classloader and install it as the system classloader by specifying the java.system.class.loader property. Commented Nov 27, 2011 at 6:33

1 Answer 1

8

This is the closest I can get and you can take it from here.I can not guarantee that it is truly portable and it will not work if any method is invoking main method of another class.Let me know if you find more clean solution

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;
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, I was aware of this method, but unfortunately it doesn't work for me since it also needs to work before the class containing main is loaded (see my comments added to the question on classloaders).
Accepting this anyway because it does the right thing and I can use it if I'm willing to defer the work I need to do based on the main class.
BTW, if you wanted to avoid more false positives, I think you could look at the class that called main and verify that it's a the expected JDK specific class - although that would introduce a dependence on a specific JDK or JDKs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.