Как получить список всех имен пакетов, загруженных JVM - PullRequest
0 голосов
/ 22 июня 2009

Мне нужно получить имена всех пакетов Java, загруженных JVM. Это должно отобразить браузер пакетов, подобный тем, которые есть в IDE. Я могу получить список пакетов текущего загрузчика классов и его предков, открыв защищенное поле «пакеты» класса ClassLoader. Но я не могу загрузить пакеты другими веб-приложениями, так как они имеют свои собственные загрузчики классов. Я тестирую это на сервере Weblogic

Ответы [ 4 ]

1 голос
/ 22 июня 2009

Ожидаемое поведение модели безопасности Weblogic состоит в том, что у вас не будет доступа к загрузчикам классов других веб-приложений. Это не то, что вы сможете обойти - см. эту статью для получения дополнительной информации.

0 голосов
/ 06 ноября 2009

Хорошо, мне удалось заставить это работать на Weblogic. Опять же, моей целью было получить имена пакетов java во всех приложениях, развернутых на данном сервере WebLogic. Зачем? У меня были свои причины:)

Сначала вы должны получить доступ ко всем файлам для ушей, войны или банок всех развернутых приложений. Для этого мы получаем из приложения WebLogic MBeans AppDeployment и выполняем итерацию, как показано ниже.

    Set<ObjectName> set = utils.getConfigMBeansByType("AppDeployment");
    for (ObjectName objectName : set) {
        String name = objectName.getKeyProperty("Name");            

        if (!appCache.contains(name)) {
            //System.out.println("Config bean: " + objectName);
            Object path = utils.getPropertyValue(objectName,
                    "AbsoluteSourcePath");
            //System.out.println("Path: " + path);
            if(path != null){
                PackageFinder finder = new PackageFinder();
                packages.addAll(finder.findPackages(path.toString()));
            }
            appCache.add(name);
        }
    }

В приведенном выше коде мы получаем путь к папке war, ear, jar или разобранной папке и передаем ее в метод findPakages класса PackageFinder, который выполняет всю работу.

 public Set<String> findPackages(String path){
    File file = new File(path);
    if(file.exists() && file.isFile()){
        InputStream in = null;
        try {
            in = new BufferedInputStream(new FileInputStream(file));
            if(path.toLowerCase().endsWith(".war")){
                processWar(in);
            }else if(path.toLowerCase().endsWith(".ear")){
                processEar(in);
            }/*
    Rest of the method body removed, I guess you get the idea 
    */              
    return packageNames;

}


public void processJar(InputStream in){
    ZipInputStream zin = null;
    try {
        zin = new ZipInputStream(in);
        ZipEntry entry;
        while((entry = zin.getNextEntry()) != null){
            if(entry.getName().endsWith(".class")){
                addPackage(entry.getName());
            }
        }
    } catch (Exception e) {
    }
}
0 голосов
/ 22 июня 2009

Единственный способ сделать это - изменить каждое веб-приложение, чтобы вы могли отправить каждому запрос на информацию о загруженном классе. Затем вы можете создать новое веб-приложение, которое объединит ответы от существующих веб-приложений для отображения.

Если вам не нужна эта информация в каком-то хорошем пользовательском интерфейсе, то у Sun JVM есть несколько опций -XX vm, которые покажут вам, что происходит с загрузкой классов.

http://java.sun.com/javase/technologies/hotspot/vmoptions.jsp

Я не очень знаком с JRockit, но я был бы удивлен, если бы у него не было подобных вариантов.

0 голосов
/ 22 июня 2009

Вам нужно пройтись по дереву загрузчиков классов с помощью getParent(), найти все классы, расширяющие ClassLoader, найти все текущие экземпляры (API отладки должен помочь здесь) Но это, вероятно, не будет работать для веб-серверов из-за политики безопасности (веб-приложениям запрещено смотреть друг на друга).

Для Tomcat есть возможность регистрировать все классы по мере их загрузки. Это сильно замедляет работу сервера, но это может быть вариантом на сервере разработки.

Тем не менее, мне довольно любопытно, зачем вам это нужно. Наиболее простым решением было бы перечислить все файлы JAR, которые приносит ваше приложение, с jar tvf и удалить последнюю часть пути (файл класса).

...