标签: classloader

有没有办法让ClassLoader加载哪些类?

我正在尝试为旧框架实现一些单元测试.我试图模拟出数据库层.不幸的是,我们的框架有点陈旧,并没有完全采用最佳实践,因此没有明确的关注点分离.我有点担心试图模拟数据库层可能会使JVM加载大量甚至无法使用的类.

我不太了解类加载器,所以这可能不是问题.有没有办法在特定ClassLoader加载的所有类中达到峰值,以证明引擎盖下发生了什么?

java unit-testing jvm classloader

13
推荐指数
2
解决办法
2万
查看次数

具有多个应用程序的Tomcat上的类加载器行为

在Tomcat 5.5服务器上,我在系统类路径中放了一个类(并修改catalina.bat来选择它),或者如果我将类放在共享的lib目录中.现在,如果我有两个不同的应用程序使用相同的类,它们的WEB-INF lib/classes目录中没有该类,则它们使用该类的相同实例.我理解一个类加载器将委托给它的父类加载器的概念,如果它找不到它,那么在这种情况下,因为该类不存在于WEB-INF/classes或WEB-INF/lib中WebAppX类加载器将分别尝试共享,公共和系统类加载器.

然而,这对我来说似乎很奇怪,两个不同的应用程序可以使用此方法共享上下文.有人可以帮我理解为什么会这样.例如,在下面的代码中,当共享CommonCounter时,两个servlet分别部署在单独的战争中,并且它们可以读取由另一个增加的计数器值.

编辑 对我而言,两个独立的应用程序可以以这种方式共享上下文.实际上,如果它们具有相同的类实例,它们甚至可以在两个不同的应用程序中实现多线程/同步,这看起来非常违反直觉.

package com.test;
public class CommonCounter {

    public static int servlet1;
    public static int servlet2;
}




public class Servlet1 extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        CommonCounter.servlet1++;
        System.out.println("Other one had "+CommonCounter.servlet2+" hits");
    }   
}



public class Servlet2 extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        CommonCounter.servlet2++;
        System.out.println("Other one had "+CommonCounter.servlet1+" hits");
    }   
}
Run Code Online (Sandbox Code Playgroud)

java tomcat classloader

13
推荐指数
1
解决办法
8309
查看次数

奇怪的jboss控制台错误

我正在为已经多模块的maven项目创建额外的模块.对于这个我希望一切都像其他模块(意味着依赖)一样只是为了测试hello world,然后我会去做一些更复杂的东西.当它部署到jboss服务器上时它确实打印了hello world,但是我在控制台上遇到了一些奇怪的错误,有没有人有类似的经历?我该如何解决?这里是 :

15:48:35,789 ERROR [STDERR] log4j:ERROR A "org.jboss.logging.appender.FileAppender" object is not assignable to a "org.apache.log4j.Appender" variable.
15:48:35,789 ERROR [STDERR] log4j:ERROR The class "org.apache.log4j.Appender" was loaded by 
15:48:35,790 ERROR [STDERR] log4j:ERROR [BaseClassLoader@9a8d9b{vfszip:/C:/jboss-5.1.0.GA/server/default/deploy/new-module-0.0.1-SNAPSHOT.war/}] whereas object of type 
15:48:35,790 ERROR [STDERR] log4j:ERROR "org.jboss.logging.appender.FileAppender" was loaded by [org.jboss.bootstrap.NoAnnotationURLClassLoader@506411].
15:48:35,790 ERROR [STDERR] log4j:ERROR Could not instantiate appender named "FILE".
Run Code Online (Sandbox Code Playgroud)

这是Appender xml的一部分

http://pastebin.com/X7Dgdrki

java jboss log4j classloader maven

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

如何将我的自定义类加载器设置为默认值?

我正在尝试使用自定义类加载器来练习自己,我有一些问题.有没有办法表明JVM全局使用我的自定义类加载器?例如,我编写了在Tomcat 6下运行的小应用程序.servlet由容器管理,我应该在哪里设置我的类加载器?另外,webapp使用了一些第三方罐子,我可以控制这些罐子的类加载吗?

在独立应用程序的情况下,上述答案是否会有所不同?

谢谢!

java tomcat classloader

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

ClassLoader泄漏 - 他们值得解决吗?

ClassLoader泄漏通常会导致java.lang.OutOfMemoryError:PermGen.在处理应用程序服务器的过程中,您可能会看到这是许多重新部署常见应用程序的结果.可以在这两个链接上看到对此问题的解释和可能的解决方案.(其中包括)

http://dev.eclipse.org/blogs/memoryanalyzer/2008/05/17/the-unknown-generation-perm/ http://blogs.oracle.com/fkieviet/entry/classloader_leaks_the_dreaded_java

现在大部分时间他们很容易绕过.只需增加-XX:MaxPermSize,当不可避免的情况发生时,完全重启JVM.尝试解决这个问题的问题是,在大型应用程序中,许多类可能导致类加载器泄漏,因此类仍然保留在permgen中.

由此产生两个问题:

是否合理地说这样的问题更好地增加最大烫发大小并在必要时重新启动或者应该找到更高优先级的解决方案?

有没有更简单的方法来解决类加载器泄漏?

java memory-leaks application-server classloader

13
推荐指数
2
解决办法
4576
查看次数

多个静态变量实例

我正在尝试使用不同的类加载器来加载特定的类,并查看该类中的静态变量是否可以具有不同的实例.

基本上,我正在尝试编写Stephen C在此答案中提到的代码.

这是我的课程:

CustomClassLoader.java

class CustomClassLoader extends ClassLoader
{
    public Class loadClass(String classname)  throws ClassNotFoundException {
        return super.loadClass(classname, true);
    }
}
Run Code Online (Sandbox Code Playgroud)

Test.java(包含驱动程序)

class Test {
        public static void main(String[] args) throws Exception {
                CustomClassLoader c1 = new CustomClassLoader();
                CustomClassLoader  c2 = new CustomClassLoader();
                Class m1, m2;

                m1 = c1.loadClass("A");
                m2 = c2.loadClass("A");

                m1.getField("b").set(null, 10);

                System.out.println(m1.getField("b").get(null));
                System.out.println(m2.getField("b").get(null));
        }

}
Run Code Online (Sandbox Code Playgroud)

A.java(包含静态变量)

class A {
        public static int b = 5;
}
Run Code Online (Sandbox Code Playgroud)

当我运行Test类时,我得到以下输出:

$ java Test
10
10
Run Code Online (Sandbox Code Playgroud)

我希望输出为10和5.如何让代码创建我的静态变量的两个实例?

注意:我这样做只是为了实验和学习 …

java reflection static classloader

13
推荐指数
2
解决办法
6801
查看次数

如何在Java中更改默认类加载器?

假设我有三个类,example.ClassA,example.ClassB和example.ClassLoader.ClassA打印出HelloWorld,ClassB导入example.ClassA并调用其main()方法.如果我这样做:

java -cp Example.jar -Djava.system.class.loader = example.ClassLoader example.ClassA

它工作并使用我的类加载器.但是,如果我这样做:

java -cp Example.jar -Djava.system.class.loader = example.ClassLoader example.ClassB

ClassB使用我的类加载器,但ClassA(由ClassB导入)使用默认的类加载器加载.

有没有办法强制Java总是使用我的类加载器(除非明确指定另一个类加载器)?

编辑:感谢下面的PaŭloEbermann的回答,我认为问题是我正在调用父类加载器(URLClassLoader)来加载我不需要触摸的类,并且那些加载的类设置为它的上下文类加载器,因此从它导入的类使用我的自定义加载器的父类加载器.(令人困惑,抱歉)现在我可以通过手动读取每个类来使它工作,但是它似乎是多余的,因为我直接复制了URLClassLoader的代码.有没有办法告诉父类加载器查找和定义类,但是将Class的上下文类加载器设置为自定义类?

java class classloader

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

Java添加到未知类型的通用列表

我之前遇到过一些我在Java中没有遇到过的东西,也就是说,我需要在运行时创建一个新的ArrayList类实例而不分配已知类型然后将数据添加到列表中.这听起来有点模糊,所以这是一个例子:

Class<?> c = i.getClass();

Constructor<?> con = ArrayList.class.getConstructor();
ArrayList<?> al = (ArrayList<?>)con.newInstance();

al.add("something");
Run Code Online (Sandbox Code Playgroud)

现在我这样做而不仅仅使用泛型的原因是因为泛型已经被大量使用而且这个例子中的"i"变量将被用作类型"?".我真的不想投入另一个通用,因为这会给用户带来更多的工作,并且在最终设计中会更不灵活.有没有办法使用下面的东西(注意:下面的内容不起作用).有人有想法吗?

ArrayList<c> al = (ArrayList<c>)con.newInstance();
Run Code Online (Sandbox Code Playgroud)

java generics reflection classloader

13
推荐指数
3
解决办法
3万
查看次数

如何在Java代码中测试Class.forName调用?

我最近在Java中乱用ClassLoaders,试图测试使用动态加载类(使用Class.forName(String name))和自定义的代码ClassLoader.

我有自己的自定义ClassLoader设置,应该可配置为ClassNotFoundException在尝试加载给定的类时抛出.

public class CustomTestClassLoader extends ClassLoader {
    private static String[] notAllowed = new String[]{};
    public static void setNotAllowed(String... nonAllowedClassNames) {
        notAllowed = nonAllowedClassNames;
    }
    public static String[] getNotAllowed() {
        return notAllowed;
    }
    public CustomTestClassLoader(ClassLoader parent){super(parent);}
    @Override
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        for (String s : notAllowed) {
            if (name.equals(s)) {
                throw new ClassNotFoundException("Loading this class is not allowed for testing purposes.");
            }
        }

        if(name.startsWith("java") || name.startsWith("sun") …
Run Code Online (Sandbox Code Playgroud)

java unit-testing classloader

13
推荐指数
1
解决办法
2064
查看次数

Java 9中的类加载器层次结构

从Java-8开始,我知道类加载器的层次结构如下: -

Bootstrap类加载器 - >扩展类加载器 - >应用程序类加载器

Java 9中类加载器层次结构的变化是什么?它是如何工作的?

java classloader java-9 java-module

13
推荐指数
2
解决办法
4033
查看次数