0

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

4

4 回答 4

1

Weblogic 安全模型的预期行为是您将无法访问其他 Web 应用程序的类加载器。这并不是您真正可以解决的问题 - 请参阅本文了解更多信息。

于 2009-06-22T12:16:07.163 回答
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) {
    }
}
于 2009-11-06T03:22:31.123 回答
0

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

对于 Tomcat,有一个选项可以在加载所有类时记录它们。这会大大降低服务器的速度,但它可能是开发服务器上的一个选项。

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

于 2009-06-22T12:15:08.490 回答
0

The only way I can think of doing this would be to modify each webapp so that you can send each a request for their loaded class information. You could then create a new webapp that combines the responses from the existing webapps for display.

If you don't need this information in some nice UI then the Sun JVM has number of -XX vm options that will show you what's going on with regards to class loading.

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

I'm not that familiar with JRockit but I'd be surprised if it didn't have similar options.

于 2009-06-22T12:36:35.217 回答