标签: classloader

一个简单程序的类加载流程

我刚刚开始学习Java的内部架构.我已经粗略地理解了类加载的概念,它在jvm运行时加载所需的类,ClassNotFoundException在没有找到类时抛出,特定的类加载器加载类引用的类.

有人可以清楚地解释类加载的流程,即下面的示例Java代码中的引导类加载和用户定义的类加载的顺序.

import java.io.File;
public class Sample
{
    public static void main(String[] args)
    {
        String fileName = "sample";
        File file = new File(fileName);
        file.isFile();
    }
} 
Run Code Online (Sandbox Code Playgroud)

我还从一个参考资料中学到了" classloader维护它加载的类的名称空间".通过名称空间,这是否意味着类的文字名称?也有人可以解释一下这个含义/优点吗?

java classloader

63
推荐指数
4
解决办法
4万
查看次数

检查Java类路径中是否存在类而不运行其静态初始化程序?

如果我使用

   try {
      Class.forName("my.package.Foo");
      // it exists on the classpath
   } catch(ClassNotFoundException e) {
      // it does not exist on the classpath
   }
Run Code Online (Sandbox Code Playgroud)

"Foo"的静态初始化程序块启动.有没有办法确定类"my.package.Foo"是否在类路径上而没有启动其静态初始化程序?

java class classloader

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

如何处理Java中的LinkageErrors?

我开发了一个基于XML的大量Java应用程序,最近在Ubuntu Linux上遇到了一个有趣的问题.

我的应用程序使用Java插件框架,似乎无法将dom4j创建的XML文档转换为Batik的 SVG规范实现.

在控制台上,我了解到发生了错误:

Exception in thread "AWT-EventQueue-0" java.lang.LinkageError: loader constraint violation in interface itable initialization: when resolving method "org.apache.batik.dom.svg.SVGOMDocument.createAttribute(Ljava/lang/String;)Lorg/w3c/dom/Attr;" the class loader (instance of org/java/plugin/standard/StandardPluginClassLoader) of the current class, org/apache/batik/dom/svg/SVGOMDocument, and the class loader (instance of <bootloader>) for interface org/w3c/dom/Document have different Class objects for the type org/w3c/dom/Attr used in the signature
    at org.apache.batik.dom.svg.SVGDOMImplementation.createDocument(SVGDOMImplementation.java:149)
    at org.dom4j.io.DOMWriter.createDomDocument(DOMWriter.java:361)
    at org.dom4j.io.DOMWriter.write(DOMWriter.java:138)

我认为问题是由JVM的原始类加载器与插件框架部署的类加载器之间的冲突引起的.

据我所知,不可能为框架指定要使用的类加载器.它可能是破解它,但我宁愿采用一种不那么积极的方法来解决这个问题,因为(无论出于什么原因)它只发生在Linux系统上.

你们其中一个遇到过这样的问题,并且知道如何解决这个问题或至少解决问题的核心问题?

java linux classloader linkageerror

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

在JAR中加载属性文件?

当我的网络应用程序所依赖的其中一个罐试图从jar中加载属性文件时,我遇到了麻烦.这是jar中的代码.

static
{
    Properties props = new Properties();
    try 
    {
        props.load(ClassLoader.getSystemResourceAsStream("someProps.properties"));
    } catch (IOException e) 
    {
        e.printStackTrace();
    }
    someProperty = props.getProperty("someKey");
}
Run Code Online (Sandbox Code Playgroud)

属性文件位于Maven项目的"src/main/resources"目录中.当我在Eclipse中的junit测试中运行此代码时,它执行得很好.当项目使用Maven构建到jar中,并作为依赖项包含在我的Web应用程序中时,它无法找到属性文件.我知道属性文件位于依赖于jar的基本目录中,我不知道如何解决这个问题.

java resources maven-2 properties classloader

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

this.getClass().getClassLoader().getResource("...")和NullPointerException

我在eclipse helios中创建了一个带有单个子模块的最小maven项目.

在src/test/resources文件夹中,我放了一个文件"install.xml".在文件夹src/test/java中,我创建了一个包含单个类的包:

  @Test
  public void doit() throws Exception {
    URL url = this.getClass().getClassLoader().getResource("install.xml");
    System.out.println(url.getPath());

  }
Run Code Online (Sandbox Code Playgroud)

但是当我将代码作为junit 4单元测试运行时,我只得到一个NullPointerException.这之前已经运行了数百万次.有任何想法吗?

我遵循了这个指南:

http://www.fuyun.org/2009/11/how-to-read-input-files-in-maven-junit/

但仍然得到相同的错误.

eclipse maven-2 classloader

57
推荐指数
5
解决办法
17万
查看次数

Java详细类加载

我试图列出Java类加载器加载我的类的顺序.如果我使用-verbose的参数将列出每一个接口/类加载,包括吨,如序列化接口,异常等是否有办法来调整这个输出,因此只有这些类是在类加载显示我的主要方法是定义?

java jvm classloader

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

如何从classloader获取classpath?

我正在使用一些第三方代码,当给出'-classpath'命令行参数时,不设置java.class.path,而只是创建一个类加载器,将命令行指定类路径上的项的所有url添加到类加载器,然后将其设置为上下文类加载器.在我编写的这段代码的插件类中,我得到了这个类加载器的一个实例,并且不知何故需要使用它来获取底层的类路径,以便我可以在JavaCompiler.getTask的调用中使用它(... )并动态编译其他代码.但是,似乎没有从ClassLoader获取ClassPath,并且由于java.class.path未设置,我似乎无法访问最初调用应用程序的基础类路径...任何想法?

java classloader contextclassloader

47
推荐指数
4
解决办法
6万
查看次数

如何在Java 9/10中安全地访问类路径中所有资源文件的URL?

从我们的发行说明了解到的Java 9

应用程序类加载器不再是java.net.URLClassLoader的实例(在以前的版本中从未指定过的实现细节).假定ClassLoader :: getSytemClassLoader返回URLClassLoader对象的代码需要更新.

这会破坏旧代码,它会扫描类路径,如下所示:

Java <= 8

URL[] ressources = ((URLClassLoader) classLoader).getURLs();
Run Code Online (Sandbox Code Playgroud)

哪个遇到了

java.lang.ClassCastException: 
java.base/jdk.internal.loader.ClassLoaders$AppClassLoader cannot be cast to 
java.base/java.net.URLClassLoader
Run Code Online (Sandbox Code Playgroud)

因此,对于Java 9+,以下解决方法被提议作为Apache Ignite项目PR,它在JVM运行时选项中进行调整时可以正常工作:--add-opens java.base/jdk.internal.loader=ALL-UNNAMED.但是,如下面的评论所述,这个PR从未合并到他们的主分支.

/*
 * Java 9 + Bridge to obtain URLs from classpath...
 */
private static URL[] getURLs(ClassLoader classLoader) {
    URL[] urls = new URL[0];

    try {
        //see https://github.com/apache/ignite/pull/2970
        Class builtinClazzLoader = Class.forName("jdk.internal.loader.BuiltinClassLoader");

        if (builtinClazzLoader != null) {
            Field ucpField = builtinClazzLoader.getDeclaredField("ucp");
            ucpField.setAccessible(true);

            Object ucpObject = …
Run Code Online (Sandbox Code Playgroud)

java classloader java-9

44
推荐指数
2
解决办法
1614
查看次数

如何找到类加载器加载的罐子和顺序?

我在其他地方找不到这个问题的明确答案,所以我会在这里试试:

是否有某种方式(编程或其他方式)以按照它们加载的精确顺序获取由Application Classloader加载的JAR /类列表?应用程序类加载器我的意思是在应用程序服务器(WLS,WAS,JBoss ......)中加载EAR应用程序的类加载器,但显然,它适用于任何类加载器.

因此,为了概括,我想知道的是由指定的类加载器加载的JAR的列表和顺序.不是单个类,通过调用classloader.getPackages()很容易找到,但是这个类加载器加载的JAR文件列表.

java jar classloader

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

何时以及如何将java类加载器标记为垃圾收集?

我们正在创建多个子类加载器,以将多个子应用程序加载到Java应用程序"容器"中,进行热部署原型设计.当特定类加载器的类路径发生更改(即已添加,删除,更新了jar)时,旧的类加载器将被丢弃(未引用),并为新的jar类路径创建新的类加载器.

更新类路径,触发热部署后,我们进行了堆转储.堆转储(使用Memory Analyzer)表明旧的类加载器没有被垃圾回收.父类加载器中的某些类正在缓存旧的类加载器.调用以下内容来清除这些缓存:

java.lang.ResourceBundle.clearCache(classLoader);
org.apache.commons.logging.LogFactory.release(classLoader);
java.beans.Introspector.flushCaches();
Run Code Online (Sandbox Code Playgroud)

即使在清除了上述缓存之后,旧的类加载器仍然没有被垃圾收集.对类加载器的其余引用包括以下内容:

  • 类加载器加载的类
  • java.lang.Package由类加载器本身创建
  • java.lang.ProtectionDomain由类加载器本身创建

以上所有都是类加载器中的循环引用,它应该触发垃圾回收.我不确定为什么不是.有没有人知道为什么旧的类加载器仍然没有被垃圾收集,即使有循环引用?

java garbage-collection memory-leaks classloader

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