标签: classloader

Class.getResource()和ClassLoader.getResource()在可执行jar中的奇怪行为

我理解Class.getResource()和ClassLoader.getResource()之间有什么区别? 从自己的代码,那

getClass().getResource("/path/image.png")
Run Code Online (Sandbox Code Playgroud)

是完全相同的

getClass().getClassLoader().getResource("path/image.png")
Run Code Online (Sandbox Code Playgroud)

发布无法读取jar文件中的图像显示使用的问题

getClass().getClassLoader().getResource("path/image.png")
Run Code Online (Sandbox Code Playgroud)

在可执行jar文件中返回null,而

getClass().getResource("/path/image.png")
Run Code Online (Sandbox Code Playgroud)

返回正确的URL.

Since Class.getResource()代表ClassLoader.getResource()在删除前导斜杠后,我希望这些调用是相同的,但显然它们不是这种情况.即使特殊类加载器附加到特定类,每次调用它仍然应该是相同的,再次导致相同的行为.

所以,问题是:是否存在以下代码在第一次调用时返回null但第二次调用的正确URL的任何明显情况?

package com.example;

import java.net.URL;

public class ResourceTest {

   public void run() {
      URL iconUrl1 = getClass().getClassLoader().getResource("path/image.png");
      System.out.println("ClassLoader.getResource(\"path/image.png\"): " + iconUrl1);

      URL iconUrl2 = getClass().getResource("/path/image.png");
      System.out.println("Class.getResource(\"/path/image.png\"): " + iconUrl2);
   }

   public static void main(String[] args) {
      ResourceTest app = new ResourceTest();
      app.run();
   }
}
Run Code Online (Sandbox Code Playgroud)

java executable-jar classloader embedded-resource

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

如何诊断Java 8元空间泄漏?

我有一个带有一些有趣行为的J2EE应用程序......堆似乎表现良好,随着时间的推移随着垃圾收集而增长和缩小.没有明显的整体长期堆扩展.然而,在我们遇到MaxMetaspace并遇到OOME之前,元空间一直稳定地以每小时20 Mb的速度增长.我尝试了并行和G1垃圾收集器(jdk1.8.0_40).

应用程序在执行期间没有重新部署,因此它似乎不是典型的类加载器泄漏.有没有人建议如何追查这个泄漏的来源?

memory-leaks permgen classloader java-8 metaspace

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

Java安全性:通过URLClassLoader加载的沙盒插件

问题摘要:如何修改下面的代码,以便在安全沙箱中运行不受信任,动态加载的代码,而应用程序的其余部分仍然不受限制?为什么URLClassLoader不像它说的那样处理它?

编辑:更新以回应Ani B.

编辑2:添加了更新的PluginSecurityManager.

我的应用程序有一个插件机制,第三方可以提供包含实现特定接口的类的JAR.使用URLClassLoader,我能够加载该类并实例化它,没问题.因为代码可能不受信任,我需要防止它行为不端.例如,我在一个单独的线程中运行插件代码,这样如果它进入无限循环或者只是花费太长时间我就可以杀死它.但是尝试为他们设置一个安全沙箱,以便他们无法做出像网络连接或访问硬盘驱动器上的文件这样的事情让我感到非常沮丧.我的努力总是导致对插件没有影响(它具有与应用程序相同的权限)或者也限制了应用程序.我希望主应用程序代码能够完成它想要的任何东西,

关于这一主题的文献和在线资源是复杂,混乱和矛盾的.我已经阅读过各种各样的地方(例如这个问题),我需要提供一个自定义的SecurityManager,但是当我尝试它时,我遇到了问题,因为JVM延迟加载JAR中的类.所以我可以很好地实例化它,但是如果我在加载的对象上调用一个方法来实例化来自同一个JAR的另一个类,那么它就会爆炸,因为它被拒绝了从JAR读取的权利.

从理论上讲,我可以在SecurityManager中检查FilePermission,看看它是否正在尝试加载自己的JAR.这没关系,但URLClassLoader文档说:"默认情况下,加载的类只被授予访问创建URLClassLoader时指定的URL的权限." 那为什么我甚至需要一个自定义的SecurityManager?URLClassLoader不应该只处理这个吗?为什么不呢?

这是一个重现问题的简化示例:

主要应用(可信)

PluginTest.java

package test.app;

import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;

import test.api.Plugin;

public class PluginTest {
    public static void pluginTest(String pathToJar) {
        try {
            File file = new File(pathToJar);
            URL url = file.toURI().toURL();
            URLClassLoader cl = new URLClassLoader(new java.net.URL[] { url });
            Class<?> clazz = cl.loadClass("test.plugin.MyPlugin");
            final Plugin plugin = (Plugin) clazz.newInstance();
            PluginThread thread = new PluginThread(new Runnable() {
                @Override
                public void run() {
                    plugin.go();
                }
            }); …
Run Code Online (Sandbox Code Playgroud)

java classloader securitymanager urlclassloader

33
推荐指数
3
解决办法
7770
查看次数

Java:初始化静态最终字段的顺序是什么?

好吧,所以说我有一个看起来像这样的课程:

public class SignupServlet extends HttpServlet {
    private static final Logger SERVLET_LOGGER=COMPANYLog.open(SignupServlet.class);
    private static final ExceptionMessageHandler handler = new ExceptionMessageHandler();   
    private static final SignupServletObservableAgent signupObservableAgent = 
        new SignupServletObservableAgent(null, SERVLET_LOGGER);
}
Run Code Online (Sandbox Code Playgroud)

我可以指望类加载器按顺序初始化这些字段,这样我可以依赖SERVLET_LOGGER在signupObservableAgent之前实例化吗?

java static final initialization classloader

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

如何加载Java Bootstrap类加载器?

在java中,据说所有类都是由类加载器加载的.

首先,bootstrap类加载器加载所有rt.jar类.

所以我仍然感到困惑,因为Classloader也是一个类,所以谁将加载这个BootStrapClassloader.

请解释一下.

java bootstrapping classloader

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

如何解析静态块之间的对象依赖性?

我最近在工作中遇到过这个问题.虽然我不确定这是一个好主意,但我不明白编译器如何处理静态块.

这是一个例子:

考虑你有类AB:

public class A {

    public final static List<Integer> list;
    static {
        list = new ArrayList<>();
    }
}

public class B {

    public final static int dependsOnA;
    static {
        dependsOnA = A.list.size();
    }
}
Run Code Online (Sandbox Code Playgroud)

还有一个只读的主要课程B.dependsOnA.

静态块B依赖于in A,因为它使用list静态变量.

现在,代码正确执行,并且NullPointerException在运行时不会引发.但是什么是确保list在其他地方潜在使用之前进行初始化的机制是什么?

java jvm classloader

33
推荐指数
7
解决办法
1481
查看次数

如何在android/dalvik上动态加载Java类?

我想知道是否以及如何在dalvik中动态加载dex或类文件,我写的一些quick'n'dirty测试函数是这样的:

    public void testLoader() { 
            InputStream in; 
            int len; 
            byte[] data = new byte[2048]; 
            try { 
                    in = context.getAssets().open("f.dex"); 
                    len = in.read(data); 
                    in.close(); 
                    DexFile d; 
                    Class c = defineClass("net.webvm.FooImpl", data, 0, len); 
                    Foo foo = (Foo)c.newInstance(); 
            } catch (IOException e1) { 
                    // TODO Auto-generated catch block 
                    e1.printStackTrace(); 
            } catch (IllegalAccessException e) { 
                    // TODO Auto-generated catch block 
                    e.printStackTrace(); 
            } catch (InstantiationException e) { 
                    // TODO Auto-generated catch block 
                    e.printStackTrace(); 
            } 
    } 
Run Code Online (Sandbox Code Playgroud)

而Foo界面就是这样

    public interface Foo { 
            int get42(); 
    } 
Run Code Online (Sandbox Code Playgroud)

和f.dex包含该接口的一些dx'ed实现: …

java android classloader dalvik

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

当同一个类存在于同一服务器上的不同应用程序中时,类加载如何工作?

我在应用服务器上运行了多个Web应用程序,每个Web应用程序WAR文件都包含相同jar文件的副本.

这是否意味着该jar文件中的一个类将在JVM中多次加载,对于它存在的每个WAR文件一次?接下来,如果我在这样的类中有一个静态同步方法,它是否只在它存在的web-app中的线程之间同步,而不是在不同jar文件中的同一个类中的同一方法同步WAR文件?(希望这个问题有道理,必要时会澄清).

如果是这种情况,我认为最好的解决方案是从每个WAR文件中删除jar文件并将其部署到服务器上的共享类路径文件夹中?

java classloader java-ee war-filedeployment

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

sun.reflect.CallerSensitive注释是什么意思?

@CallerSensitive上述方法的注释隐含了什么?

例如,注释存在于Class的getClassLoader方法中

 @CallerSensitive
    public ClassLoader getClassLoader() {
    //
    }
Run Code Online (Sandbox Code Playgroud)

java security reflection class classloader

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

Jar hell:如何在运行时使用类加载器将一个jar库版本替换为另一个jar库版本

我还是比较新的Java,所以请耐心等待.

我的问题是我的Java应用程序依赖于两个库.让我们称它们为库1和库2.这两个库共享对库3的相互依赖.但是:

  • 库1完全需要库3的版本1.
  • 库2完全要求库3的版本2.

这正是JAR地狱的定义(或者至少是其中的一个变体).如链接中所述,我无法在同一个类加载器中加载第三个库的两个版本.因此,我一直试图弄清楚是否可以在应用程序中创建一个新的类加载器来解决这个问题.我一直在研究URLClassLoader,但我无法弄明白.

这是一个演示问题的示例应用程序结构.应用程序的Main类(Main.java)尝试实例化Library1和Library2,并运行在这些库中定义的一些方法:

Main.java(原始版本,在尝试解决方案之前):

public class Main {
    public static void main(String[] args) {
        Library1 lib1 = new Library1();
        lib1.foo();

        Library2 lib2 = new Library2();
        lib2.bar();
    }
}
Run Code Online (Sandbox Code Playgroud)

Library1和Library2都共享对Library3的相互依赖,但是Library1需要版本1,而Library2只需要版本2.在这个例子中,这两个库只打印他们看到的Library3版本:

Library1.java:

public class Library1 {
  public void foo() {
    Library3 lib3 = new Library3();
    lib3.printVersion();    // Should print "This is version 1."
  }
}
Run Code Online (Sandbox Code Playgroud)

Library2.java:

public class Library2 {
  public void foo() {
    Library3 lib3 = new Library3();
    lib3.printVersion();    // Should print "This is …
Run Code Online (Sandbox Code Playgroud)

java jar classpath classloader

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