Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Список загруженных в память классов, как получить? 
V
    Опции темы
powerOn
Дата 5.4.2006, 19:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 47
Всего: 159



Привет всем!
Сабж- Подскажите есть ли возможность и как это сделать.


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
jer1
Дата 5.4.2006, 21:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 123
Регистрация: 24.1.2005
Где: Харьков Украина

Репутация: 4
Всего: 5



может быть профайлер поможет ?
--------------------
:w!q
PM MAIL   Вверх
powerOn
Дата 6.4.2006, 08:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 47
Всего: 159



Мне программно надо, чтоб я сам в мог список получить.


--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
tux
Дата 6.4.2006, 08:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Летатель
***


Профиль
Группа: Участник Клуба
Сообщений: 1853
Регистрация: 10.2.2005
Где: msk.ru

Репутация: 31
Всего: 132



Посмотри спецификацию к пакету java.lang.instrument и интерфейс java.lang.instrument.Instrumentation в частности. Но это все доступно только начиная с JDK 5.0.
PM MAIL Skype GTalk Jabber YIM   Вверх
LSD
Дата 6.4.2006, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



В принципе у любого ClassLoader-ра есть поле classes, которое содержит список классов загруженных данным ClassLoader-ом. Оно приватное, но через рефлексию достать можно.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
Domestic Cat
Дата 6.4.2006, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5452
Регистрация: 3.5.2004
Где: Dallas, US

Репутация: 50
Всего: 172





--------------------

PM   Вверх
powerOn
Дата 6.4.2006, 19:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 47
Всего: 159



Спасибо tux за правильное направление.

Действительно, в пакете java.lang.instrument есть интерфейс Instrumentation, в котором среди прочих
объявлен метод Class[] getAllLoadedClasses(). Но! Его реализацию не так-то просто получить.
Как я выяснил из описания, реализацию интерфейса Instrumentation, можно получить лишь одним способом - написать агента. Агент - это класс ваш реализующий метод public static void premain(String agentArgs, Instrumentation inst); Этот класс будет загружен виртуальной машиной Java в память, во время старта программы, а потом будет вызван метод premain(), в который и будет передан объект реализующий интерфейс Instrumentation.
И так задача получения списка загруженных классов в память сводится к получению реализации интерфейса Instrumentation, которая в свою очередь предается только один раз и только в метод premain() агента. Для этого я предлагаю создать своего агента, и использовать его для получения ссылки на реализацию интерфейса Instrumentation.

И так, по шагам
1) Создаем агента, сохраняющего в открытом статическом поле ссылку на реализацию интерфейса
Instrumentation.
2) Подключаем агента к нашей программе.
3) Используем агента для для получения ссылки на реализацию интерфейса Instrumentation.

Шаг 1.
Чтобы создать агента нам надо написать класс реализующий метод public static void premain(String
agentArgs, Instrumentation inst); Вот как я его реализовал

Код

import java.lang.instrument.Instrumentation;
public class Agent {
    
    /** Creates a new instance of Agent */
    public Agent() {
    }
    public static Instrumentation instrumentation = null;
    public static void premain(String agentArgs, Instrumentation inst){
       System.out.println("agent is loaded!!!"); 
       instrumentation = inst;
    }
}


класс имеет поле public static Instrumentation instrumentation, которое будет служить нам "лазом" к
реализации интерфейса Instrumentation. Этот класс нужно скомпилировать и содрать в jar архив, и что самое важное манифест этого архива должен содержать ключ Premain-Class: ИмяКлассаАгента. В данном случае ключ выглядит так: Premain-Class: Agent Создайте jar архив с именем Agent.jar

Шаг 2.
Программа которая будет использовать наш класс в качестве агента, должна быть запущена с дополнительным ключом -javaagent:ПутьиИмяКАрхиваАгента.jar, если вы собрали агента к примеру в Agent.jar, то пометстите его в classpath Вашего основного проекта запустите программу с дополнительным ключом -javaagent:Agent.jar. Если все сделано правильно, то JVM подгрузит при старте агента и вызовет его метод premain(String agentArgs, Instrumentation inst).

Шаг 3
И так при хорошем стечении обстаятельств агент загружен в память и его метод premain() был успешно
вызван, а это значит что поле instrumentation хранит ссылку на реализацию интерфейса Instrumentation.
Получить её можно с помощью Reflection, как в следующем примере:

Код

import java.lang.instrument.Instrumentation;
import java.lang.reflect.Field;

public class Main {
    
    /** Creates a new instance of Main */
    public Main() {
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            
            Field f = Class.forName("Agent").getField("instrumentation");
            Instrumentation i = (Instrumentation) f.get(null);
            Class c[] = i.getAllLoadedClasses();
            System.out.println("test Ints : " + c[0].getName());
            
        } catch (Exception ex) {
            ex.printStackTrace();
        } 
    }
}


Здесь с помощью Reflection мы получим данные статического поля, которое как известно одно для всех
классов. Приведем это значение к типу Instrumentation и получим то, что так хотели... :-)

P.S. не знаю, потянет ли это описание на заметку для FAQ, господа модераторы Вам решать.... smile




--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
LSD
Дата 6.4.2006, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(MoonCat @ 6.4.2006, 20:43 Найти цитируемый пост)
P.S. не знаю, потянет ли это описание на заметку для FAQ, господа модераторы Вам решать....

Подойдет, подойдет smile
Спасибо за статью.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
jer1
Дата 7.4.2006, 12:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 123
Регистрация: 24.1.2005
Где: Харьков Украина

Репутация: 4
Всего: 5



Цитата(MoonCat @ 6.4.2006, 19:43)
public class Main {
   
    /** Creates a new instance of Main */
    public Main() {
    }
   
    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {
        try {
           
            Field f = Class.forName("Agent").getField("instrumentation");
            Instrumentation i = (Instrumentation) f.get(null);
            Class c[] = i.getAllLoadedClasses();
            System.out.println("test Ints : " + c[0].getName());
           
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
[/code]

Здесь с помощью Reflection мы получим данные статического поля, которое как известно одно для всех
классов. Приведем это значение к типу Instrumentation и получим то, что так хотели... :-)

всё замечательно, только вот зачем рефлекшн, можно просто
Код

    Instrumentation i = Agent.instrumentation;

--------------------
:w!q
PM MAIL   Вверх
powerOn
Дата 7.4.2006, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 47
Всего: 159



Цитата

всё замечательно, только вот зачем рефлекшн, можно просто
    Instrumentation i = Agent.instrumentation;


Серьезно? smile У меня так не компилируется....
Код

C:\Programs\JAVA\JavaApplication1\src\javaapplication1\Main.java:29: cannot find symbol
symbol  : variable Agent
location: class javaapplication1.Main
            Instrumentation i = Agent.instrumentation;
1 error



--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
jer1
Дата 8.4.2006, 09:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 123
Регистрация: 24.1.2005
Где: Харьков Украина

Репутация: 4
Всего: 5



чудеса :-), у тебя ж файлы в одном пакете (дефолтном), поэтому
просто перейди в директорию где лежит Main.java и Agent.java
и выполни javac *.java

если у тебя корневая директория другая то её надо будет указать в
classpath
javac -cp <директория где лежит скомпилированный код Agent.java> Main.java



--------------------
:w!q
PM MAIL   Вверх
powerOn
Дата 8.4.2006, 21:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


software saboteur
****


Профиль
Группа: Участник
Сообщений: 4367
Регистрация: 7.10.2005

Репутация: 47
Всего: 159



Цитата

чудеса :-), у тебя ж файлы в одном пакете (дефолтном), поэтому
просто перейди в директорию где лежит Main.java и Agent.java
и выполни javac *.java

если у тебя корневая директория другая то её надо будет указать в
classpath
javac -cp <директория где лежит скомпилированный код Agent.java> Main.java



jer1, агент и Main класс хоть и находятся в пакете с одним дефолтовым именем, но разрабатываются в разных проектах. По крайней мере в моём примере. На выходе получается 2 jar архива, для агента и для программы. Далее настраивается манифест для агента (добавляем Premain-Class: Agent), а главную программу запускаем с ключом -javaagent:Agent.jar. Т.е. агент и основная программа разрабатываются отдельно и находтся в разных jar архивах.



--------------------
user posted image нет времени думать - нужно писать КОД!

PM MAIL   Вверх
jer1
Дата 10.4.2006, 13:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 123
Регистрация: 24.1.2005
Где: Харьков Украина

Репутация: 4
Всего: 5



после того как файлы скомпилятся ложи их в разные пакеты как тебе надо, главное чтобы во время работы программы они были доступны (в твоём случае Agent.jar загружается путём -javaagent:Agent.jar ), т.е. Agent.jar - это обычная библиотека, такая же как и apache commons-io.jar, например.





--------------------
:w!q
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0570 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.