Java 从外部jar加载类时,NoClassDefFoundError仅适用于少数类

Java 从外部jar加载类时,NoClassDefFoundError仅适用于少数类,java,jar,classloader,external,Java,Jar,Classloader,External,我试图加载外部jar中包含的所有类。我不能将jar作为库包含在我的项目中,我必须从用户定义的未知位置加载它。到目前为止,我正在使用扩展urlclassloader的类加载器加载这些类。资料来源如下: public class JarLoader extends URLClassLoader { public JarLoader() { super(new URL[0], ClassLoader.getSystemClassLoader()); } private static fin

我试图加载外部jar中包含的所有类。我不能将jar作为库包含在我的项目中,我必须从用户定义的未知位置加载它。到目前为止,我正在使用扩展urlclassloader的类加载器加载这些类。资料来源如下:

public class JarLoader extends URLClassLoader {

public JarLoader() {
    super(new URL[0], ClassLoader.getSystemClassLoader());
}

private static final String ENDING_CLASS = ".class", URL_PREFIX = "file:";

public final Set<Class<?>> loadCraftbukkit(final JarFile pJar) {
    if (pJar != null) {

        try {
            addURL(new URL(URL_PREFIX + pJar.getName()));
            final Enumeration<JarEntry> entries = pJar.entries();
            final Set<Class<?>> loadedClasses = new HashSet<>();
            while (entries.hasMoreElements()) {
                final JarEntry entry = entries.nextElement();
                final String className = getClassName(entry);
                if (className != null) {
                    try {
                        final Class<?> loadedClass = loadClass(className);
                        loadedClasses.add(loadedClass);
                    } catch (ClassNotFoundException | NoClassDefFoundError pExc) {
                        // ignore invalid class
                    }
                }
            }
            return loadedClasses;
        } catch (MalformedURLException | ClassFormatError ignore) {
            // won't happen if legal jarfile
        }
    }
    return null;
}

private final String getClassName(final JarEntry pEntry) {
    final String name = pEntry.getName();
    if (name.endsWith(ENDING_CLASS)) {
        return name.substring(0, name.lastIndexOf(ENDING_CLASS)).replace('/', '.');
    }
    return null;
}
}
public类JarLoader扩展了URLClassLoader{
公共JarLoader(){
super(新URL[0],ClassLoader.getSystemClassLoader());
}
私有静态最终字符串结尾为_CLASS=“.CLASS”,URL_PREFIX=“file:”;
public final Set>loadedClasses=new HashSet();
while(entries.hasMoreElements()){
final JarEntry=entries.nextElement();
最终字符串className=getClassName(条目);
if(className!=null){
试一试{
最终类loadedClass=loadClass(类名);
添加(loadedClass);
}捕获(ClassNotFoundException | NoClassDefFoundError pExc){
//忽略无效类
}
}
}
返回加载的类;
}捕获(MalformedURLException | ClassFormatError忽略){
//如果法律文件无效,就不会发生
}
}
返回null;
}
私有最终字符串getClassName(最终JarEntry pEntry){
最终字符串名=pEntry.getName();
if(name.endsWith(结束类)){
返回name.substring(0,name.lastIndexOf(ENDING_CLASS)).replace(“/”,“.”);
}
返回null;
}
}
奇怪的是,在1800多个类中,只有37个类抛出了“NoClassDefFoundError”。这些类没有加载,因此我的程序在出现空指针后无法运行

这是我正在加载的罐子:
这就是我所能找到的来源:
这是我所能找到的文档:


我怎样才能加载这37个类?我试图以字节的形式读取它们,并使用classloader的“defineClass”方法自己加载它们,但这个方法也无法加载它们。有人知道如何解决这个问题吗?

你的应用程序似乎达到了65K方法的限制,这是Android非常著名的限制。 资料来源:

有关更多信息,请参阅:

你的应用程序似乎达到了65K方法的限制,这是Android非常著名的限制。 资料来源:

有关更多信息,请参阅:
如果不知道错误原因,很难知道

通常这是由于类路径中不包含依赖项(类加载器未能加载超类而导致的
ClassNotFoundException
被包装在
NoClassDefFoundError
中)或静态字段或块中的某个运行时异常


值得指出的是,对NoClassDefFoundError的这一极好的解释是:

如果不看到错误原因,很难知道

通常这是由于类路径中不包含依赖项(类加载器未能加载超类而导致的
ClassNotFoundException
被包装在
NoClassDefFoundError
中)或静态字段或块中的某个运行时异常


值得一提的是,对
NoClassDefFoundError

java.lang.NoClassDefFoundError
java.lang.NoSuchMethodError
的这一出色解释是在运行时被访问时抛出的,类加载器无法加载类,因为类路径中不存在这些类。如果您的程序从未尝试在运行时访问类路径中不存在的类或方法,您永远不会得到
NoClassDefFoundError
NoSuchMethodError
java.lang.NoClassDefFoundError
java.lang.NoSuchMethodError
在运行时被访问时抛出,类加载器无法加载类,因为它不在类路径中。如果您的程序从未尝试在运行时访问类路径中不存在的类或方法,则您将永远不会得到
NoClassDefFoundError
NoSuchMethodError

此应用程序正在windows上的我的jre 8环境上运行。不应具有Andriod的限制此应用程序在windows上运行于我的jre 8环境。不应该有andriodcan的限制吗?您可以添加堆栈跟踪吗?通常在加载缺少依赖类的类时会出现错误。就像你的用户JAR需要另一个一样。我面临着完全相同的问题。你找到解决办法了吗?@HariRam不,对不起。实际上可能是以下idelvall所述的限制。是否可以添加堆栈跟踪?通常,加载缺少依赖类的类时会出现错误。就像你的用户JAR需要另一个一样。我面临着完全相同的问题。你找到解决办法了吗?@HariRam不,对不起。实际上可能是下面idelvall所说的限制。他没有要求定义他没有要求定义