Переносимый способ найти имя основного класса из кода Java

2

Можно ли найти имя основного класса, используемого для запуска текущей JVM, из произвольного кода, запущенного в этой JVM?

Произвольным я имею в виду, что код не обязательно работает в основном потоке или может выполняться в основном потоке до того, как main даже был вызван (например, код в поставляемом пользователем java.system.classloader, который выполняется до основного, поскольку он используется для загрузки основного), поэтому проверка стека вызовов невозможна.

  • 0
    В JVM основной метод основного класса вызывается первым. (см. также java.sun.com/docs/books/jls/third_edition/html/… ) Итак, что вы имеете в виду «может быть запущен в главном потоке до того, как main будет даже вызван». Я думаю, что эта фраза упоминает "статический инициализатор" или "Thread # run ()".
  • 0
    @cocoatomo: я что-то упустил. Показывает ли эта ссылка решение вопроса оригинального автора? Если это произойдет, хотя я рассмотрел это, я как-то пропустил.
Показать ещё 2 комментария
Теги:

1 ответ

8
Лучший ответ

Это самое близкое, что я могу получить, и вы можете взять его здесь. Я не могу гарантировать, что он действительно портативен, и он не будет работать, если какой-либо метод вызывает основной метод другого класса. Сообщите мне, если вы найдете больше чистый раствор

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 (см. Мои комментарии, добавленные к вопросу о загрузчиках классов).
  • 0
    В любом случае, принять это, потому что это правильно, и я могу использовать это, если я хочу отложить работу, которую мне нужно сделать, на основе основного класса.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню