标签: classloader

任何查看类加载器树图片的工具?

假设我正在调试Java EE应用服务器内部署的应用程序的一些奇怪的类加载问题.由于某种原因,我看起来在两个类加载器(2个不同的EAR类加载器)的类路径上有重复的jar,并且这些类加载器的名称空间中的类需要精心设计.

所以问题是:是否存在可以显示类加载器树的图像(图片)以及每个类加载器的存储库的任何工具?当然,显示一张图片并不重要,如果它可能是某种动态用户界面(例如Windows资源管理器树折叠/展开),我会非常高兴.

UPD:我正在使用JBoss 5.1.

谢谢

java jboss classloader

9
推荐指数
1
解决办法
2076
查看次数

使用调用它们的webapp的配置来获取tomcat/shared/lib中的jar

我正在寻找将我们的tomcat实例从5.5.27升级到6.0.32,并且在shared/lib目录中从jars进行日志记录时遇到了一些问题(我在tomcat 6中重新创建了这个目录).

我们有一个jar文件,我们在构建过程中创建了一个jar文件,其中包含一些公共代码,而在tomcat 5下,它存在于shared/lib下.当我们从这个jar文件中的代码编写日志语句时,它们被写入当时调用jar的Web应用程序的日志文件中.我们的每个webapps在其WEB-INF/lib目录中都有一个log4j.properites和log4j.jar,在shared/lib中也有一个log4j.jar,但没有log4j/properties.

我们使用log4j并获取对日志的引用,如下所示:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;    
public class MyClass {
    private final static Log CLASS_LOG = LogFactory.getLog(MyClass.class);
}
Run Code Online (Sandbox Code Playgroud)

但是当我将我们的jar,webapps,log4.properties和log4j.jars完全相同的配置移动到tomcat 6中时,来自我们常见jar的日志记录语句就转到catalina.log.

我已经做了相当多的阅读(包括http://www.mulesoft.com/tomcat-classpath,以及tomcat网站上的类加载器和日志记录文档),大多数时候我无法弄清楚它是如何工作的在tomcat 5做了!(我没有设置它,这是我继承的东西,直到现在'只是工作').

有没有人尝试将共享库中的日志转换为webapp日志文件?我认为将共享jar放在每个webapp的WEB-INF/lib目录中会对此进行排序,但后来我最终得到了同样东西的许多副本.

java logging tomcat shared-libraries classloader

9
推荐指数
1
解决办法
2457
查看次数

scala classloaders混乱

请考虑以下测试程序(使用scala 2.9.0.1)

object test
{
  def main(args:Array[String]) = {
    println(ClassLoader.getSystemClassLoader.getResource("toto"))
    println(this.getClass.getClassLoader.getResource("toto"))
    println(classOf[Object].getClassLoader)
  }
}
Run Code Online (Sandbox Code Playgroud)

我编译它并使用包含文件"toto"的"-cp/tmp"运行它,我得到以下输出:

null
file:/tmp/toto
null
Run Code Online (Sandbox Code Playgroud)

=>系统类加载器不包含类路径

=> Object类没有类加载器!

我在那里遗漏了什么,或者它是scala中的(大)错误?!

谢谢,阿琼

scala classloader

9
推荐指数
1
解决办法
6316
查看次数

PathMatchingResourcePatternResolver(spring)用法

我正在使用 :

PathMatchingResourcePatternResolver rr = new ...;
rr.getResources("classpath*:**/*.class")
Run Code Online (Sandbox Code Playgroud)

从目录和jar组成的类路径中获取所有类.该调用仅返回目录中的类; JAR文件被忽略.以下调用从JAR返回类:

rr.getResources("classpath*:org/**/*.class")
Run Code Online (Sandbox Code Playgroud)

是否可以在不知道基本包名的情况下获取所有类?

java spring classpath classloader

9
推荐指数
1
解决办法
6359
查看次数

由于类加载器的ClassCastException?

在使用类加载器时,我遇到以下异常:

Exception in thread "main" java.lang.ClassCastException: xxx.Singleton cannot be cast to xxx.Singleton
Run Code Online (Sandbox Code Playgroud)

这是否意味着类加载器中的实例不能转换为另一个类加载器的类?

检查我的代码,我可以通过类加载器实现3个单例,即使是""安全性.

public static void main(String[] args) throws Exception {
        URL basePath = new URL("file:/myMavenPath/target/classes/");

    Object instance = getClassInstance(Singleton.class);
    System.out.println(instance);
    //
    Object instance2 = getClassInstance(
            new URLClassLoader( new URL[]{basePath} , null )
                    .loadClass("my.Singleton")
    );
    System.out.println(instance2);
    //
    Object instance3 = getClassInstance(
            new URLClassLoader( new URL[]{basePath} , null )
                    .loadClass("my.Singleton")
    );
    System.out.println(instance3);

    // Only the 1st cast is ok
    Singleton testCast1 = (Singleton) instance;
    System.out.println("1st cast ok");
    Singleton testCast2 = …
Run Code Online (Sandbox Code Playgroud)

java jvm scjp classloader

9
推荐指数
1
解决办法
8254
查看次数

使用自定义类加载器配置org.apache.log4j.ConsoleAppender

我有一个java类,它在启动时基于javassist类加载器创建一个自定义类加载器,然后运行真正的程序类.我收到以下错误:

log4j:ERROR A "org.apache.log4j.ConsoleAppender" object is not assignable to a        
"org.apache.log4j.Appender" variable.
log4j:ERROR The class "org.apache.log4j.Appender" was loaded by 
log4j:ERROR [javassist.Loader@6f97b10a] whereas object of type 
log4j:ERROR "org.apache.log4j.ConsoleAppender" was loaded by 
[java.net.URLClassLoader@5b414a8d].
log4j:ERROR Could not instantiate appender named "stdout".
Run Code Online (Sandbox Code Playgroud)

问题与以下事实有关:一个对象由原始类加载器创建,而另一个对象由自定义类加载器创建.
有没有办法解决这个错误?

先谢谢,
Avner

java log4j classloader javassist

9
推荐指数
1
解决办法
1万
查看次数

如何选择Classloader?

动机

假设我们有一个类加载层次结构,如下所示:

 Bootstrap
     |
  System
     |
  Custom
Run Code Online (Sandbox Code Playgroud)

假设CustomClassloader用于加载类com.example.SomeClass.它检查System类加载器是否可以加载它,再次检查Bootstrap类加载器是否可以加载它.既然两者都不能,com.example.SomeClass则由Customclassloader加载.

任何com.example.SomeClass依赖的类都是一样的.我相信我理解这个过程.

我不明白为什么Custom会尝试首先加载com.example.SomeClass.如何在Java应用程序中选择当前的类加载器?

java classloader

9
推荐指数
1
解决办法
1595
查看次数

类加载器如何在清单类路径中加载类引用?

我使用maven来构建一个带有外部类路径添加的jar,使用addClasspath.

当我使用java -jar artifact.jar它运行该jar时,可以从该主jar和libs目录中的所有jar加载类.

但是,如果我问系统属性java.class.path,它将只列出主jar.如果我向系统类加载器询问其urls(ClassLoader.getSystemClassLoader().getURLs()),它也只会返回主jar.如果我问一些库中包含的任何类的类加载器,它将返回系统类加载器.

系统类加载器如何加载这些类?

它必须对这些库有一些了解才能从这些库中加载类.有没有办法要求它提供这种"扩展"类路径?

java jar classpath classloader

9
推荐指数
2
解决办法
2995
查看次数

在Java中使用3个类加载器的原因是什么?

Java有3个类加载器:

  • 自举,
  • 扩展和
  • 系统

他们有一个角色; 从不同的包加载类.

但是为什么Java有3个不同的类加载器而不是只有一个,因为一个类加载器可以加载所有必需的类?

java classloader

9
推荐指数
1
解决办法
1514
查看次数

Java/Groovy - GroovyClassLoader中的内存泄漏

我正在加载大量的Groovy(2.4.6)脚本并在我的Java 8应用程序中使用GroovyScriptEngineImpl运行它们,一段时间后我遇到了问题.

您需要了解一些事项:

  • GroovyScriptEngineImpl每次运行脚本时我都必须重新创建一个新的
  • GroovyClassLoader每次运行脚本时我都必须重新创建一个新的

我需要这样做,以便在一个单独的"环境"中隔离每个脚本:我在类加载器中为一些脚本加载一些外部JAR,我不希望其他脚本能够使用这些脚本中的类JAR在被执行时.

我的问题来自这样一个事实:对于我运行的每个脚本,GroovyClassLoader它将创建一个新ScriptXXXX类并加载它,但永远不会卸载它.

这导致加载的类数量无限增加,并且内存最终被完全填充.

我尝试了大量的各种解决方案,但似乎都没有效果:

  • 添加-XX:+CMSClassUnloadingEnabled -XX:+UseConcMarkSweepGCJVM参数
  • 添加-Dgroovy.use.classvalue=trueJVM参数
  • 删除为每个ScriptXXXX类创建的"元类" ,如下所示:Groovy类没有被收集但没有内存泄漏的迹象
  • 清除缓存并关闭 GroovyClassLoader
  • 使用内省手动清除缓存中的类的一些字段 GroovyScriptEngineImpl
  • 等等...

这是ScriptXXXXEclipse Memory Analyzer中其中一个类的"最短路径到GC" :

Eclipse Memory Analyzer转储

我在这里显然没有解决方案,似乎没有一个真正起作用,因为类加载器总是保持对从未获得GCed的类的引用.

如果您想重现该问题,请参阅以下代码示例:

GroovyScriptEngineImpl se;

while (true)
{
    se = new GroovyScriptEngineImpl(new GroovyClassLoader());
    CompiledScript script = se.compile("println(\"hello\")");
    script.eval(se.createBindings());
}
Run Code Online (Sandbox Code Playgroud)

谢谢

更新:在阅读了pczeus的回复之后,我尝试限制元空间,并且有些类似乎确实正在卸载,我认为这是ScriptXXX类.

也就是说,几分钟后我Out of Metaspace在脚本执行过程中遇到错误.

这是我用VisualVM获得的配置文件:

Java VisualVM中的配置文件

Eclipse Memory Analyzer中用于ScriptXXX类的"GC路径" 确实是空的(它们不再是类的实例),即使该类仍然在直方图中列出.

java groovy memory-leaks classloader

9
推荐指数
1
解决办法
3467
查看次数