Java:类路径JVM中的多个资源中的哪一个?

Ond*_*žka 47 java resources jvm loading classpath

如果我有classpath中的多个同名文件(例如我有多个.jarlog4j.properties),什么是JVM如下,以选择一个规则?

mou*_*ser 51

它由使用-classpathoption 指定资源(即通常是jar文件)的顺序指定.类路径上的"早期"资源优先于它们之后指定的资源.这也可以在应用程序的清单文件中设置,然后您不需要提供-classpath选项.您可能需要查看这些文章,了解如何使用清单文件.

可以在这里找到"如何找到类"的详尽描述,其中JAR-class-path Classes部分描述了JAR文件搜索的逻辑.

  • 任何官方文档确认类路径中的"资源"早先优先于它们之后指定的资源. (2认同)

emb*_*oss 8

ClassLoader确定资源的位置(取自ClassLoader JavaDoc):

ClassLoader类使用委派模型来搜索类和资源.ClassLoader的每个实例都有一个关联的父类加载器.当请求查找类或资源时,ClassLoader实例会在尝试查找类或资源本身之前,将对类或资源的搜索委托给其父类加载器.虚拟机的内置类加载器(称为"引导类加载器")本身不具有父级,但可以作为ClassLoader实例的父级.

因此,无论您在代码中调用Class#getResource还是Class#getResourceAsStream,都会发生这种情况(取自Class.java)

public java.net.URL getResource(String name) {
    name = resolveName(name);
    ClassLoader cl = getClassLoader0();
    if (cl==null) {
        // A system class.
        return ClassLoader.getSystemResource(name);
    }
    return cl.getResource(name);
}
Run Code Online (Sandbox Code Playgroud)

ClassLoader.java:

public URL getResource(String name) {
    URL url;
    if (parent != null) {
        url = parent.getResource(name);
    } else {
        url = getBootstrapResource(name);
    }
    if (url == null) {
        url = findResource(name);
    }
    return url;
}
Run Code Online (Sandbox Code Playgroud)

其中ClassLoader#findResource实际上被ClassLoader实现覆盖.这意味着应用程序服务器,TomCat上的行为不同,或者如果您从jar文件运行,它依赖于您当前所处环境的ClassLoader实现.

下面是一个示例,您可以使用它来跟踪特定情况下的内容.