相关疑难解决方法(0)

如何在Java中创建父/子/子优先ClassLoader,或如何覆盖已在父CL中加载的旧Xerces版本?

我想创建一个父/ last/child-first类加载器,例如一个类加载器,它首先在子类loder中查找类,然后只委托它的父ClassLoader来搜索类.

澄清:

现在我知道,要得到完整的类加载分离-我需要使用像传递null,因为它是父的URLClassLoader,归功于这个回答我刚才的问题

但是,当前的问题来帮我解决这个问题:

  1. 我的代码+依赖jar正被加载到现有系统中,使用ClassLoader将System的ClassLoader设置为它的父级(URLClassLoader)

  2. 该系统使用的某些库与我需要的版本不兼容(例如,旧版本的Xerces,不允许我运行我的代码)

  3. 如果运行独立,我的代码运行完全正常,但如果从该ClassLoader运行则它会失败

  4. Howerver我确实需要访问父ClassLoader中的许多其他类

  5. 因此,我想允许我使用自己的Override,父类加载器"jars":如果在子类加载器中找到我调用的类(例如,我提供了一个带有我自己的jar的更新版本的Xerces,而不是一个用户由加载我的代码和jar的ClassLoader.

这是加载我的代码+ Jars的系统代码(我无法更改此代码)

File addOnFolder = new File("/addOns"); 
URL url = addOnFolder.toURL();         
URL[] urls = new URL[]{url};
ClassLoader parent = getClass().getClassLoader();
cl = URLClassLoader.newInstance(urls, parent);
Run Code Online (Sandbox Code Playgroud)

这是"我的"代码(完全取自Flying Sauser"Hello World"代码演示):

package flyingsaucerpdf;

import java.io.*;
import com.lowagie.text.DocumentException;
import org.xhtmlrenderer.pdf.ITextRenderer;

public class FirstDoc {

    public static void main(String[] args) 
            throws IOException, DocumentException {

        String f = new File("sample.xhtml").getAbsolutePath();
        System.out.println(f);
        //if(true) return;
        String inputFile = "sample.html";
        String url = new File(inputFile).toURI().toURL().toString();
        String outputFile = …
Run Code Online (Sandbox Code Playgroud)

java classloader

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

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万
查看次数

自定义Java类加载器没有用于加载依赖项?

我一直在尝试设置一个自定义类加载器,它拦截类以打印出正在加载到应用程序中的类.类加载器看起来像这样

public class MyClassLoader extends ClassLoader {
    @Override
    public Class<?> loadClass(String name) throws ClassNotFoundException {
        System.out.println("Loading: " + name);
        return super.loadClass(name);
    }
}     
Run Code Online (Sandbox Code Playgroud)

它只是吐出它加载的所有类的名称.但是,当我尝试运行一些代码时,

import org.python.util.PythonInterpreter;
public class Scripts {
    public String main(){

        PythonInterpreter p = new PythonInterpreter();
        p.exec("print 'Python ' + open('.gitignore').read()");

        return "Success! Nothing broke";
    }
}
Run Code Online (Sandbox Code Playgroud)

通过

MyClassLoader bcl = new MyClassLoader();
Class c = bcl.loadClass("Scripts");

Method m = c.getMethod("main");
String result = (String) m.invoke(c.getConstructor().newInstance());
Run Code Online (Sandbox Code Playgroud)

它打印出来

Loading: Scripts
Loading: java.lang.Object
Loading: java.lang.String
Loading: org.python.util.PythonInterpreter
Python build/
.idea/* …
Run Code Online (Sandbox Code Playgroud)

java jvm metaprogramming class classloader

17
推荐指数
1
解决办法
7369
查看次数

标签 统计

classloader ×3

java ×3

class ×1

classpath ×1

jar ×1

jvm ×1

metaprogramming ×1