标签: classloader

Java ClassLoader委托模型?

在调用loadClass()a时ClassLoader,是否ClassLoader首先检查是否已加载该类,还是立即将此检查委托给其父级ClassLoader

Java API说:

当请求查找类或资源时,ClassLoader实例会在尝试查找类或资源本身之前,将对类或资源的搜索委托给其父类加载器.

但是在Java Reflection in Action一书中有一个关于类加载器的特定章节,它说:

类加载器调用findLoadedClass来检查是否已经加载了类.如果类加载器没有找到加载的类,则在父类加载器上调用loadClass.

哪个是对的?

java classloader

12
推荐指数
1
解决办法
9178
查看次数

Java或任何其他语言:哪个方法/类调用了我的?

我想在我的方法内部编写一个代码,用于打印哪个方法/类调用它.

(我的假设是我不能改变任何东西,除了我的方法..)

其他编程语言怎么样?

编辑:谢谢你们,JavaScript怎么样?蟒蛇?C++?

javascript python java programming-languages classloader

12
推荐指数
1
解决办法
727
查看次数

强制类加载

在C#或.net IL中是否有办法强制一个具有类型初始值设定项(静态构造函数)的类来加载自身,而不访问它的任何参数?

假设我上了课

public static class LogInitialization {
    static LogInitialization() {
        System.Console.WriteLine("Initialized");
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法让这条线打印出来?

请注意,该类是静态的,因此我无法将其实例化以强制初始化,并且它没有公共成员,因此我无法访问它们以启动它.

.net c# static-constructor classloader typeinitializer

12
推荐指数
2
解决办法
2961
查看次数

ClassLoader.defineClass抛出的ClassCircularityError

我正在使用自定义类加载器加载类.在大多数情况下,一切正常,但有时当我加载特别复杂的项目/库时,我得到一个奇怪的错误:

Exception in thread "main" java.lang.ClassCircularityError: 
  org/apache/commons/codec/binary/Hex
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:466)
    at my.custom.class.Loader.loadClass(...)
Run Code Online (Sandbox Code Playgroud)

看看Javadocs,我不希望defineClass抛出这个特殊的错误. org/apache/commons/codec/binary/Hex是我正在尝试加载的类.defineClass在它定义类之前,它几乎就像想要一个类的副本 - 这对我来说毫无意义.

想法?

java circular-dependency classloader

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

如何在Sun的JVM中禁用延迟类加载/初始化?

默认情况下,Sun的JVM都懒惰地加载类并且懒惰地初始化(即调用它们的<clinit>方法)它们.考虑以下类,ClinitBombExceptionstatic{}块中抛出一个.

public class ClinitBomb {
    static {
        explode();
    }   
    private static void explode() {
        throw new RuntimeException("boom!");
    }       
}
Run Code Online (Sandbox Code Playgroud)

现在,考虑如何触发炸弹:

public class Main {
    public static void main(String[] args) {
        System.out.println("A");
        try {
            Class.forName("ClinitBomb");
        } catch (Exception e) {
            e.printStackTrace(System.out);
        }
        System.out.println("B");
        ClinitBomb o2 = new ClinitBomb();
        System.out.println("C");
    }
}
Run Code Online (Sandbox Code Playgroud)

我们保证爆炸发生在B点之前,因为forName文件说明了这一点; 问题是它是否发生在A点之前(Main加载时).在Sun的JVM中,即使main()包含静态引用ClinitBomb,它也会在A之后发生.

我想要一种方法告诉JVM ClinitBomb一旦初始化就加载并初始化Main(因此炸弹 A点之前爆炸).一般来说,我想要一种方式来说,"无论何时加载/初始化类X,对任何一个也是如此它引用的Y类."

有没有办法做到这一点?

java class classloader static-initializer

12
推荐指数
1
解决办法
4572
查看次数

JDK1.7 ClassLoader内存泄漏

我有孩子优先的UrlClassLoader来动态加载jar文件.然后我做一个反射来调用加载的jar文件中的方法.一旦完成,我宁愿卸载类加载器.然后我尝试做一些压力测试代码,以确保我的代码顺利运行.基本上,我尝试做的是在循环语句中加载和卸载jar.这是我的代码:

    for (int i = 0; i < 1000; i++) {
        //Just to show the progress
        System.out.println("LOAD NUMBER : " + i);

        ChildFirstURLClassLoader classLoader = null;
        try {
            File file = new File("C:\\library.jar");
            String classToLoad = "com.test.MyClass";
            URL jarUrl = new URL("file:" + file.getAbsolutePath());

            classLoader = new ChildFirstURLClassLoader(new URL[] {jarUrl}, null);
            Class<?> loadedClass = classLoader.loadClass(classToLoad);
            Method method = loadedClass.getDeclaredMethod("execute",
                    new Class[] {});

            ClassLoader currCl= Thread.currentThread().getContextClassLoader();
            Thread.currentThread().setContextClassLoader(classLoader);
            method.invoke(null);
            Thread.currentThread().setContextClassLoader(currCl);

            method = null;
            loadedClass = null;
        } finally {
            if (classLoader != …
Run Code Online (Sandbox Code Playgroud)

java memory-leaks classloader

12
推荐指数
1
解决办法
1251
查看次数

从加载的类中获取字节码

假设在我的JVM中我有一个加载的类Class<C> myClass.有可靠吗?方法向JVM询问字节码.class的内容?就是这样的:

<C> byte[] getClassBytecode(Class<C> myClass) {
    return /* the contents of the .class resource where C was loaded from */;
}
Run Code Online (Sandbox Code Playgroud)

(显然InputStream会和它一样好byte[]).我知道我可以使用myClass.getResource()(和朋友)来获取类文件,但是在类名上敲击以获取一个提供给getResource的URL感觉不对.此外,我不确定在C动态生成(例如使用javax.tools.JavaCompiler)的情况下这将如何表现.

任何(更好)的想法?

注意:目标是能够推动 字节码 类到不同的JVM并使用自定义类加载器在那里加载它们

java class classloader

12
推荐指数
1
解决办法
7441
查看次数

在Java 7中加载KeyStore会泄漏Classloader

在Java 7中加载KeyStore时,类加载器被泄露.

我已经使用Tomcat 7.0.47中的"Find Leaks"功能和classloader-leak-prevention确认了这一点.这是测试代码,带有@Configuration泄漏webapp和带有@Controller泄漏webapp.

基本上这些线为我造成了泄漏:

InputStream is = null;
try {
    is = new FileInputStream("./app.truststore");
    KeyStore keyStore = KeyStore.getInstance("JKS");
    keyStore.load(is, "changeit".toCharArray());
} catch (Exception e) {
    System.out.println(e);
} finally {
    if (is != null) {
        is.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我删除KeyStore.load()一切正常,但这显然不是一个有效的解决方案.

它不适用于Oracle JDK 1.7u15,u17,u21,u25,u40和u45以及OpenJDK 1.7u40和u45.

它适用于Oracle JDK 1.6u39,u41,u43和45以及OpenJDK 1.6.0.

这是在Microsoft Windows Server 2008 R2 Standard 64 Bit上测试的.OpenJDKs是alexkasko在GitHub上的最新非官方版本.

有谁知道可能导致Classloader泄漏的原因是什么?我尝试使用堆转储并调用"GC根目录的最短路径",但没有返回任何结果.

java memory-leaks classloader

12
推荐指数
1
解决办法
516
查看次数

java.lang.LinkageError:ClassCastException

我确实遇到过TestNG和RESTeasy的烦人问题.

我有一个类,它针对API类运行多个测试,该类使用RESTeasy框架来暴露自己.

但是,如果我让测试运行maven(mvn test),那么我得到以下异常:

java.lang.LinkageError: ClassCastException: attempting to castjar:file:/C:/Users/rit/.m2/repository/org/jboss/resteasy/jaxrs-api/2.3.0.GA/jaxrs-api-2.3.0.GA.jar!/javax/ws/rs/ext/RuntimeDelegate.classtojar:file:/C:/Users/rit/.m2/repository/org/jboss/resteasy/jaxrs-api/2.3.0.GA/jaxrs-api-2.3.0.GA.jar!/javax/ws/rs/ext/RuntimeDelegate.class
at javax.ws.rs.ext.RuntimeDelegate.findDelegate(RuntimeDelegate.java:126)
at javax.ws.rs.ext.RuntimeDelegate.getInstance(RuntimeDelegate.java:96)
at javax.ws.rs.core.Response$ResponseBuilder.newInstance(Response.java:394)
at javax.ws.rs.core.Response.status(Response.java:116)
at javax.ws.rs.core.Response.status(Response.java:130)
at com.pd.api.TokenAPI_V1.validateAccessToken(TokenAPI_V1.java:141)
at com.test.pd.api.TokenAPI_V1Test.testIfValidAccessTokenReturnsCorrectHTTPHeadersWhenTokenIsNotFound(TokenAPI_V1Test.java:359)
Run Code Online (Sandbox Code Playgroud)

测试只是调用API obejct的方法,该方法返回一个Response对象(来自RESTeasy).作为测试框架,我使用TestNG.

测试方法

@Test
public void testIfValidAccessTokenReturnsCorrectHTTPHeadersWhenTokenIsNotFound() throws InvalidAccessTokenException {
    Mockito.when(tokenService.validateAccessToken(TestConstants.ACCESS_TOKEN)).thenThrow(new InvalidAccessTokenException());

    Response response = tokenAPI_v1.validateAccessToken(TestConstants.ACCESS_TOKEN, TestConstants.USER_AGENT);
    assert "no-store".equals(response.getMetadata().getFirst("Cache-Control"));
    assert "no-cache".equals(response.getMetadata().getFirst("Pragma"));
}
Run Code Online (Sandbox Code Playgroud)

问题说明

看起来RESTeasy框架在不同的类加载器中加载RuntimeDelegate.如果我看一下源代码,那么在RuntimeDelegate(包括第126行)中有以下方法:RuntimeDelegate.java.

因此,与错误相关的主要语句是instanceof check:

if (!(delegate instanceof RuntimeDelegate))
Run Code Online (Sandbox Code Playgroud)

如果我检查委托实例的类加载器与RuntimeDelegate的类加载器,那么我得到以下输出:

delegate.getClass().getClassLoader() -> org.powermock.core.classloader.MockClassLoader@31e46a68

RuntimeDelegate.class.getClassLoader() -> sun.misc.Launcher$AppClassLoader@3c0fabe9
Run Code Online (Sandbox Code Playgroud)

我知道这当然不起作用,但我想知道为什么RESTeasy的东西被加载到MockClassLoader而不是另一个.特别是因为我没有模拟被测试的TokenAPI.

奇怪的事实

奇怪的是,当我从IntelliJ运行测试时(我选择只运行包含产生错误的方法的给定类的所有测试),然后它就会运行.看起来它与mvn测试运行maven项目中的所有测试(或者至少我认为是这样)的事实有某种关系.

java testng classloader mockito powermock

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

有和没有getClassLoader的getResourceAsStream有什么区别?

我想知道以下两者之间的区别:

MyClass.class.getClassLoader().getResourceAsStream("path/to/my/properties");

MyClass.class.getResourceAsStream("path/to/my/properties");

谢谢.

java classloader

11
推荐指数
1
解决办法
4431
查看次数