如何获取JVM加载的所有包名称的列表

时间:2009-06-22 11:55:18

标签: java weblogic classloader

我需要获取JVM加载的所有Java包的名称。这是为了显示类似于IDE中的包浏览器。我可以通过访问ClassLoader类的受保护的“packages”字段来获取当前类加载器及其祖先的包列表。但我无法获得其他webapps加载的软件包,因为他们有自己的类加载器。我正在Weblogic服务器上测试它

4 个答案:

答案 0 :(得分:1)

Weblogic安全模型的预期行为是您无法访问其他Web应用程序的类加载器。这不是您能够解决的问题 - 有关详细信息,请参阅this article

答案 1 :(得分:0)

您需要使用getParent()遍历类加载器树,查找扩展ClassLoader的所有类,查找所有当前实例(调试API应该在这里提供帮助)。但由于安全策略(Web应用程序不允许彼此查看),这可能不适用于Web服务器。

对于Tomcat,可以选择在加载时记录所有类。这会使服务器变慢,但它可能是开发服务器上的一个选项。

那就是说,我很好奇为什么你需要那个。最简单的解决方案是列出您的应用带来的所有JAR文件jar tvf并删除路径的最后一部分(类文件)。

答案 2 :(得分:0)

我能想到这样做的唯一方法是修改每个webapp,以便您可以发送每个请求以获取其加载的类信息。然后,您可以创建一个新的Web应用程序,它结合了现有Web应用程序的响应以供显示。

如果您在一些不错的用户界面中不需要这些信息,那么Sun JVM有多个-XX vm选项,可以显示有关类加载的内容。

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

我对JRockit并不熟悉,但如果它没有类似的选择我会感到惊讶。

答案 3 :(得分:0)

好的,我设法让这个工作在Weblogic上。我的目标是在给定WebLogic服务器上部署的所有应用程序中获取Java包名称。为什么?我有我的理由:)

首先,您必须掌握所有已部署应用的ear,war或jar文件位置。为此,我们从WebLogic获取AppDeployment MBean并进行迭代,如下所示。

    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或爆炸文件夹的路径,并将其传递给PackageFinder类的findPakages方法,该方法完成所有工作。

 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) {
    }
}