Поиск классов в JVM Runtime - PullRequest
       1

Поиск классов в JVM Runtime

1 голос
/ 03 февраля 2012

В любом случае можно найти все имена классов, которые расширяют определенный класс, используя информацию загрузчика классов?

Более подробное объяснение

У меня есть файл jar, который имеет 3 класса X (extends A), Y (extends A) и Z (extends B). Я поместил этот jar-файл в путь к классам и запустил JVM (вызывая метод main некоторого класса). Теперь из этого основного метода есть ли способ найти классы, которые являются подклассами A? то есть классы X и Y, поскольку они расширяют класс A.

Ответы [ 2 ]

0 голосов
/ 03 февраля 2012

просто ради полноты http://code.google.com/p/reflections/

других, упомянутых в связанном посте

0 голосов
/ 03 февраля 2012

К сожалению, нет простого способа сделать это.JVM не имеет информации о конкретном классе, пока он не будет загружен загрузчиком классов.Но чтобы загрузчик классов действительно загружал класс, вы должны знать имя класса.Проблема с курицей и яйцом.

Однако есть и другой, но немного более сложный способ.

  1. Чтобы определить, какие файлы .jar находятся в пути к классам при запуске приложения,Вы можете вызвать System.getProperty("java.class.path"), а затем разделить записи пути к классам вдоль символов File.separatorChar.Записи пути к классам могут быть многочисленными, подумайте о том, чтобы как-то их отфильтровать (ограничиваясь только определенным каталогом, исключая стандартные записи, например rt.jar и т.Вы можете открыть его с помощью экземпляра класса JarFile.Затем вы можете перебирать все записи (например, .class файлы) и по их внутреннему пути в файле JAR вы можете создать их полное имя класса.
  2. Имея имя класса в своей руке, вы можете позвонить Class.forName(), чтобы загрузить класс, и вы можете использовать отражение, чтобы получить суперклассы каждого класса, чтобы узнать, расширяет ли он ваш конкретный класс или нет.

Обратите внимание, что этот метод довольно ресурсоемкий, вы заставляете JVM загружать все классы из файла .jar (или нескольких файлов .jar), даже если вы их не используетепотом.Это приводит к бесполезному расходу памяти (пространство PermGen).

Существует несколько низкоуровневых библиотек, которые манипулируют байт-кодом Java и файлами классов (см. BCEL или ASM ).,Используя их, вы сможете определить суперкласс для класса, фактически не загружая его (класс), таким образом, этот способ быстрее и использует меньше памяти.

Ваш вопрос похож на работу серверов приложений JavaEE при развертываниивеб приложение.Чтобы выяснить, какие классы загружать и инициализировать, как, например, сервлеты HTTP, они должны проверить все классы в веб-архиве в поисках конкретной аннотации Java или суперкласса.Однако они, по крайней мере, знают, какой .war файл сканировать.Например, Apache Tomcat использует BCEL вместо механизма загрузки классов Java.

Если вы разрабатываете какой-то механизм динамической загрузки классов для своего приложения, то рассмотрите другие варианты проектирования, чтобы сузить число классов, в которые должен загружать загрузчик.найдите подходящий класс для загрузки: сообщая точное имя файла .jar вместо того, чтобы помещать его в путь к классам, используя некоторую метаинформацию в JAR (вы можете использовать вышеупомянутый JarFile для чтения записей из файла META-INF/manifest.mf) указать, какие классы искать и т. д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...