Tag: classloader

CompletableFuture / ForkJoinPool设置类加载器

我解决了一个非常具体的问题,其解决方案似乎是基本的: 我的(Spring)应用程序的类加载器层次结构是这样的: SystemClassLoader -> PlatformClassLoader -> AppClassLoader 如果我使用Java CompleteableFuture来运行线程。 线程的ContextClassLoader是: SystemClassLoader -> PlatformClassLoader -> ThreadClassLoader 因此,虽然我不得不访问AppClassLoader任何类,因为所有外部库类都驻留在那里。 源代码库非常大,所以我不希望/不能将所有与线程相关的部分重写为其他内容(例如,将自定义执行程序传递给每个调用)。 所以我的问题是: 如何使用例如CompleteableFuture.supplyAsync()创建的线程使用AppClassLoader作为父级? (而不是PlatformClassloader ) 我发现ForkJoinPool用于创建线程。 但在我看来,一切都是静态的和最终的 。 所以我怀疑即使在系统属性中设置自定义ForkJoinWorkerThreadFactory也会有所帮助。 或者是吗? 编辑以回答评论中的问题: 你在哪里部署? 这是在jetty / tomcat /任何JEE容器内运行吗? 我正在使用默认的Spring Boot设置,因此使用内部tomcat容器。 你有什么确切的问题? 确切的问题是: java.lang.IllegalArgumentException:从类加载器中看不到从方法引用的org.keycloak.admin.client.resource.RealmsResource 您提交给supplyAsync()的作业是从AppClassLoader创建的,不是吗? 从MainThread调用supplyAsync ,它使用AppClassLoader 。 但是,调试应用程序显示所有此类线程都将PlatformClassLoader作为其父级。 至于我的理解,这是因为ForkJoinPool.commonPool()是在应用程序启动期间构建的(因为它是静态的),因此使用默认的类加载器作为父类PlatformClassLoader 。 因此,来自此池的所有线程都将PlatformClassLoader作为ContextClassLoader (而不是AppClassLoader )的父级。 当我在MainThread创建自己的执行程序并将此执行程序传递给supplyAsync一切正常 – 我可以在调试期间看到,确实现在AppClassLoader是我的ThreadClassLoader的父ThreadClassLoader 。 这似乎证实了我在第一种情况下的假设,即公共池不是由MainThread创建的,至少不是在使用AppClassLoader本身时。 完整堆栈跟踪: java.lang.IllegalArgumentException: org.keycloak.admin.client.resource.RealmsResource […]

Android类解析中的陌生事物

我在Android上观察了很多行为(我正在研究multidex问题,所以我在4.4.4中使用了一个模拟器)让我对Android类加载无言以对: 在类加载器加载时, 不应该解析Android类。 但是如果我创建一个类: public class M { public Foo m(String i) { switch (i) { case “0”: return new Foo(); case “1”: return new Foo2(); } return null; } } 并调试我的应用程序,添加手表: getClass().getClassLoader().findLoadedClass(“Foo”) getClass().getClassLoader().findLoadedClass(“Foo2”) 然后我可以看到加载M确实加载了Foo和Foo2 ! 所以课程得到了解决。 奇怪的是,这几乎是第二个问题,但是如果我添加M extends Application ,那么M根本就不会被解析,即使实例化它也是如此。 当调用m(X)时, Foo和Foo2仅被加载到JVM中m(X)当X为”0″时加载Foo ,对于X=”1″加载Foo2 )。 这里有没有人对这些基本问题有合理的解释: 为什么M解决了,不应该解决类。 即使实例化M也不应加载Foo或at least Foo2 。 为什么扩展Application的类表现不同? 是否有其他Android类以不同的方式运行?

为什么Class.getPackage为来自不同包的类返回相同的包?

我创建一个新的ClassLoader并使它定义一个新的Class ,这意味着新的类应该在一个新的命名空间中,它就是AFAIK。 奇怪的是,当我在新类上调用Class.getPackage时,它返回与在我的主命名空间中的任何其他类上调用getPackage返回的完全相同的对象。 根据JVM规范 : 类或接口的运行时包由包名称和类或接口的类加载器定义。 换句话说,如果在同一个包中有两个类,但是由不同的类加载器加载,则它们被认为是在不同的包中。 (这也可以通过下面的测试用例中的reflection来“确认”。) 那么当我这样做时,我会从两个类的getPackage得到相同的结果? 这是我的测试: package pkg; import java.io.*; // Yes, you can try commenting this class, you’ll get the same result. class LoadedClass { LoadedClass() { System.out.println(“LoadedClass init”); } } class MyClassLoader extends ClassLoader { Class defineClass(String name, byte[] b) { return defineClass(name, b, 0, b.length); } } class […]

线程创建监听器

是否可以在java中编写线程创建监听器? 例如使用aop?! 我的意思是这样的,如果我的应用程序创建一个线程,我想在我自己的表,容器或其他东西中注册这个对象。

将java对象/类从一个类加载器复制到另一个类加载器

您有没有办法将一个类加载的上下文(atrributes等)从一个类加载器(例如’make’class Point)复制到另一个类加载器? 说清楚,示例:我在CL 1上有一个对象Point。现在在另一个CL2上运行,我想在CL 3中创建这个对象。 一些obj: class Point { int x; int y; public Point() {} //getters and setters 风景: … class CL2 { // Running on CL 2 … // Point obj from CL 1 Object point = gotFromCL1(); // Want to create the object on Cl2 Object pointCL2 = point.conversion(); 但我不能使用sun.reflection(不可用),并且序列化不起作用,因为CL2使用CL 1自动“重建”对象。 我考虑的一个解决方案是做一个“100%”javareflectionrconstruct,基本上从CL2获取对象的字段并设置新的obj。 […]

在OSGi Bundle中使用JavaCompiler

我正在重构Java应用程序以使用OSGi。 该应用程序的一个function是使用javax.tools.JavaCompiler Java编译。 在原始应用程序中,此过程通过向编译器提供现有类路径来完成,就像这样。 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); String[] options = {“-classpath”, System.getProperty(“java.class.path”)}; DiagnosticListener listener = new DiagnosticListener() {…}; StandardJavaFileManager fileManager = compiler.getStandardFileManager(listener, null, null); Iterable fileObjects = fileManager.getFileObjects(sourceFile); CompilationTask task = compiler.getTask(null, fileManager, listener, Arrays.asList(options), null, fileObjects); task.call(); 但是,这在OSGi包中不起作用,因为类路径不再包含所需的路径。 在重构的OSGi版本的应用程序中,编译器需要访问与上述代码在同一个包中的类,以及来自其他包的类。 如何让编译器知道这些类? 我想到了两种可能的解决方案: 为编译器提供包含上述代码的bundle使用的类加载器,因为它知道所有必需的类。 但是,从我在这里和这里读到的内容来看,这似乎不是一个可行的解决方案。 使用已安装捆绑包的物理位置构建类路径。 我查看了org.osgi.framework.Bundle.getLocation()但我不确定这是否是一个可靠的解决方案。 我得到的路径(至少在Eclipse中部署时)是相对的,我不确定它们是否可以安全地在所有平台和情况下使用。 上面的选项2似乎可能吗? 有更好的解决方案吗?

loadClass(String name)和loadClass(String name,boolean resolve)之间的区别

loadClass(String name)和loadClass(String name, boolean resolve)什么区别? 我知道的唯一区别是loadClass(String name, boolean resolve) )如果resolve参数为true,则调用findLoadedClass(String)? 那么当true或false传递给resolve参数时? 我对这两个function感到很困惑。 谢谢。

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

我想知道以下两者之间的区别: MyClass.class.getClassLoader().getResourceAsStream(“path/to/my/properties”); 和 MyClass.class.getResourceAsStream(“path/to/my/properties”); 谢谢。

声明变量final和static

此评论是在代码审核中进行的,而制作该评论的人不再在我们的团队中。 在运行时必须由类加载器解析的任何类型都不应该具有被声明为final和static的引用保持的实例。 这是代码行: private final static Logger log = LoggerFactory.getLogger(MyClass.class); 我熟悉声明loggers静态或非静态的争论,但这个评论似乎更为通用。 我找不到任何关于为什么静态和最终都不好的解释。 有人可以详细说明吗?

通过URLCassloader加载加密的JarFile

我一直在编写一个小系统来动态加载AES加密的jar文件。 我的代码: public static void main(String args[]) throws Exception { String jar = “http://site.com/api/rsc/test.jar”; List urls = new ArrayList(); urls.add(getURL(jar)); URL jarurl = urls.get(0); ObjectInputStream ois = new ObjectInputStream((new URL(“http://site.com/api/rsc/key_1.txt”).openStream())); Object o = ois.readObject(); DESKeySpec ks = new DESKeySpec((byte[])o); SecretKeyFactory skf = SecretKeyFactory.getInstance(“DES”); SecretKey key = skf.generateSecret(ks); Cipher c = Cipher.getInstance(“DES/CFB8/NoPadding”); c.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec((byte[]) […]