1

从下面链接中的答案链接

我发现可以通过将其添加到类路径来解决它。但我正在使用 Custom ClassLoader 加载 jar axiom-impl-1.2.14。有什么办法可以做到这一点?

axiom jar 正在使用 ClassLoader。枚举 getResources(String name) 以在 jar 内部加载该 xml。在我们的例子中,XML 文件位于 jar 文件中。所以我正在寻找可以获取 XML 文件 URL 的解决方案。

源代码 :

公共类 ExternalClassLoader 扩展 ClassLoader {

private String jarFile = "";
private Hashtable<String, Class> classes = new Hashtable<String, Class>();

public ExternalClassLoader(String jarLocation) {
    super(ExternalClassLoader.class.getClassLoader());
    this.jarFile = jarLocation;
}

@Override
public Class loadClass(String className) throws ClassNotFoundException {
    return findClass(className);
}

@Override
public Class findClass(String className) {

    byte classByte[];
    Class result = null;
    System.out.println("CLASS : " + className);
    result = (Class) classes.get(className);
    if (result != null) {
        return result;
    }
    try {
        return findSystemClass(className);
    } catch (Exception e) {
    }
    JarFile jar = null;
    try {
        jar = new JarFile(jarFile);
        String classLocation = className.replace('.', '/');
        JarEntry entry = jar.getJarEntry(classLocation + ".class");
        InputStream is = jar.getInputStream(entry);
        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        int nextValue = is.read();

        while (-1 != nextValue) {
            byteStream.write(nextValue);
            nextValue = is.read();
        }

        classByte = byteStream.toByteArray();
        result = defineClass(className, classByte, 0, classByte.length, null);
        classes.put(className, result);
        return result;
    } catch (Exception e) {
        System.out.println("ERROR CLASS : " + className);
        return null;
    } finally {
        try {
            jar.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

@Override
public InputStream getResourceAsStream(String name) {
    try {
        System.out.println("RESOURCE : " + jarFile + "//" + name);
        JarFile jar = new JarFile(jarFile);
        JarEntry entry = jar.getJarEntry(name);
        return jar.getInputStream(entry);
    } catch (IOException e) {
        System.out.println("ERROR RESOURCE : " + jarFile + "//" + name);
        return null;
    }
}

}

4

1 回答 1

1

由于您没有指定详细信息,我假设与另一个版本发生冲突,该版本axiom-impl位于类加载器的类路径中,您的应用程序的其余部分是从中加载的(否则您可以只使用一个或多个URLClassLoader实例或更改应用程序类加载器的类加载策略)。

我还假设(正如您在评论中提到的那样)axiom-api并且axiom-impl都由同一个自定义类加载器加载,或者您将这两个 JAR 中的类组合成一个 JAR(在这种情况下,我假设您不这样做) t 包含axiom-dom在同一个 JAR 中,因为这会导致其他问题)。

如果这些假设成立,那么您需要的是一个类加载器,它从一个或多个 JAR 文件加载类,并使用 parent last 作为类加载策略。为了实现这一点,您不需要像您尝试在您发布的代码中那样重新实现 JAR 加载逻辑。相反,您可以使用URLClassLoader,但您需要对其进行扩展以将其类加载策略从默认父优先更改为父最后。在 Apache Axiom 本身的源代码中实际上有一个这样的例子:

http://svn.apache.org/repos/asf/webservices/axiom/tags/1.2.15/axiom-api/src/test/java/org/apache/axiom/util/stax/dialect/ParentLastURLClassLoader.java

您可能可以按原样使用该代码,尽管您可能希望删除包过滤器,javax.*因为在您的情况下不需要这样做。

于 2015-10-20T19:46:15.707 回答