Java 未找到功能的元工厂';默认值';;这通常意味着axiom-impl.jar不在类路径中

Java 未找到功能的元工厂';默认值';;这通常意味着axiom-impl.jar不在类路径中,java,axis2,axiom,Java,Axis2,Axiom,从下面链接中的答案 我发现可以通过将它添加到类路径来解决这个问题。但我使用定制类加载器来加载jar axiom-impl-1.2.14。 有没有办法做到这一点 axiom jar正在使用ClassLoader。枚举getResources(字符串名称)以在jar中内部加载该xmls。本例中的XML文件位于jar文件中。所以我正在寻找一种解决方案,通过它我可以获得XML的文件URL 源代码: 公共类ExternalClassLoader扩展了ClassLoader{ private String

从下面链接中的答案

我发现可以通过将它添加到类路径来解决这个问题。但我使用定制类加载器来加载jar axiom-impl-1.2.14。 有没有办法做到这一点

axiom jar正在使用ClassLoader。枚举getResources(字符串名称)以在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;
    }
}
私有字符串jarFile=”“;
私有哈希表类=新哈希表();
公共外部类加载器(字符串位置){
super(ExternalClassLoader.class.getClassLoader());
this.jarFile=jarLocation;
}
@凌驾
公共类loadClass(字符串className)引发ClassNotFoundException{
返回findClass(类名称);
}
@凌驾
公共类findClass(字符串类名称){
字节类字节[];
类结果=null;
System.out.println(“类:“+className”);
result=(Class)classes.get(className);
如果(结果!=null){
返回结果;
}
试一试{
返回findSystemClass(类名);
}捕获(例外e){
}
JarFile jar=null;
试一试{
jar=新的JarFile(JarFile);
字符串classLocation=className.replace('.','/');
JarEntry=jar.getJarEntry(classLocation+“.class”);
InputStream=jar.getInputStream(条目);
ByteArrayOutputStream ByTestStream=新建ByteArrayOutputStream();
int nextValue=is.read();
而(-1!=nextValue){
byteStream.write(下一个值);
nextValue=is.read();
}
classByte=ByTestStream.toByteArray();
结果=定义类(className,classByte,0,classByte.length,null);
class.put(类名、结果);
返回结果;
}捕获(例外e){
System.out.println(“错误类:“+className”);
返回null;
}最后{
试一试{
jar.close();
}捕获(IOE异常){
e、 printStackTrace();
}
}
}
@凌驾
公共InputStream getResourceAsStream(字符串名称){
试一试{
System.out.println(“资源:“+jarFile+”/“+name”);
JarFile jar=新的JarFile(JarFile);
JarEntry=jar.getJarEntry(名称);
返回jar.getInputStream(条目);
}捕获(IOE异常){
System.out.println(“错误资源:“+jarFile+”/“+name”);
返回null;
}
}

}

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

我还假设(正如您在评论中提到的)
axiom api
axiom impl
都是由同一个自定义类装入器装入的,或者您将这两个JAR中的类合并到一个JAR中(在这种情况下,我假设您不在同一个JAR中包含
axiomdom
,因为这会导致其他问题)

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


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

您可以提供一些关于您正在使用的类加载类型的详细信息吗?实际上,由于冲突风险,我不想在我的项目中包含此JAR。我编写了一个简单的e自定义类加载器加载此jar中的类。但我面临问题,因为此jar内部使用getResources从类路径加载axiom.xml。但我不想将其添加到类路径中。axiom api和axiom impl是否由相同的类加载器加载?是的。由相同的类加载器加载。如果axiom api和axiom impl由相同的类加载加载器,该类加载器是自定义类加载器,您在标题中收到错误消息,这意味着您的自定义类加载器没有正确实现资源加载。因此,要获得问题的答案,您需要显示该类加载器的代码。