来自Link
下方链接的答案我发现可以通过将其添加到classpath来解决它。但我使用Custom ClassLoader来加载jar axiom-impl-1.2.14。 有没有办法实现这个目标?
axiom jar正在使用ClassLoader。枚举getResources(String name)在jar中内部加载xmls。我们的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;
}
}
}
答案 0 :(得分:1)
由于您没有指定详细信息,我假设与另一版本的axiom-impl
发生冲突,该版本位于加载应用程序其余部分的类加载器的类路径中(否则您可以只需使用一个或多个URLClassLoader
实例或更改应用程序类加载器的类加载策略。
我也假设(正如您在评论中提到的)axiom-api
和axiom-impl
都由同一个自定义类加载器加载,或者您将这两个JAR中的类合并为一个JAR(在这种情况下,我假设您不在同一个JAR中包含axiom-dom
,因为这会导致其他问题)。
如果这些假设成立,那么你需要的是一个类加载器,它从一个或多个JAR文件加载类,并使用parent last作为类加载策略。要实现这一点,您不需要像在尝试发布的代码中那样重新实现JAR加载逻辑。相反,您可以使用URLClassLoader
,但您需要扩展它以将其类加载策略从默认父级更改为父级。在Apache Axiom本身的源代码中有一个这样的例子:
您可以按原样使用该代码,但您可能希望删除javax.*
上的包过滤器,因为在您的情况下这不是必需的。