Java类加载器无法加载模块?

Java类加载器无法加载模块?,java,classloader,Java,Classloader,我似乎在为正在开发的应用程序在模块加载器中加载类时遇到了问题。基本上,我将要加载的所有类都扩展了另一个类,它位于实际应用程序包中。出于我们的目的,我们将其称为模块。模块位于实际应用程序之外的单独文件夹中 加载程序遍历文件夹,并对扩展名为.class的任何文件执行loadFile()方法。所有类都有包声明作为模块类,以及类头中的扩展模块声明 这是loadFile()方法,不包括头和异常子句: String fileName = file.getName(); String className =

我似乎在为正在开发的应用程序在模块加载器中加载类时遇到了问题。基本上,我将要加载的所有类都扩展了另一个类,它位于实际应用程序包中。出于我们的目的,我们将其称为模块。模块位于实际应用程序之外的单独文件夹中

加载程序遍历文件夹,并对扩展名为.class的任何文件执行loadFile()方法。所有类都有包声明作为模块类,以及类头中的扩展模块声明

这是loadFile()方法,不包括头和异常子句:

String fileName = file.getName();
String className = fileName.replace(".class", ""); //Strips extension
Class<?> aClass = Class.forName(className, true, new URLClassLoader(new URL[] { file.toURI().toURL() }));
Class<? extends Module> modClass = aClass.asSubclass(Module.class);
return modClass.getConstructor().newInstance();
String fileName=file.getName();
字符串className=fileName.replace(“.class”,”)//条带延伸
Class aClass=Class.forName(className,true,新的URLClassLoader(新的URL[]{file.toURI().toURL()}));

类来自URLCLassLoader的文档:

此类加载器用于从引用URL的URL搜索路径加载类和资源 JAR文件和目录。假定以“/”结尾的任何URL都引用目录。 否则,假定URL引用一个JAR文件,该文件将根据需要打开

因此,您必须为目录或.jar使用URL

两种解决方案:

  • 强制用户向您提供.jar文件,其中包括某种清单,以及他们希望加载的类名。开发人员使用这种方法。在过去使用过这种方法之后,依赖项都应该打包在.jar文件中,从而打包在URLClassLoader的搜索路径中,并且能够被加载
  • 使用文件目录的URL,并在该目录中搜索.class文件。我不确定是否将使用此方法加载依赖项

  • 在URLClassLoader中,不要传递文件,而是传递父文件夹。但是,如果类都在“默认包”中,则此操作正常工作,因此正在加载的.class文件顶部不能有包声明

    默认情况下,类加载器还将触发正确构建类所需的所有类的加载:它将尝试加载超类、超超类等。。。所有接口和超级接口,静态字段和方法所需的类,方法签名所需的类(返回类型和参数)。它通常不会尝试加载方法内部使用的类,直到您执行这些方法

    但是,通常类加载器并不“包含”所有这些类,例如,您的类最终将继承java.lang.Object,而您的URLClassLoader将不包含Object.class文件。因此,类装入器委托给它们的父类装入器

    您当前正在创建一个URLClassLoader,但没有指定父级,在Java 7中,至少父级将默认为“系统类装入器”,只要您在普通Java应用程序中,并且不在特定的类装入器层次结构中执行代码本身,就可以了。但是,如果您在web应用程序或OSGI容器等中运行该代码。。您应该为URLClassLoader指定一个适当的父级进行委托,例如Thread.currentThread().getContextClassLoader()或this.getClass().getClassLoader()


    我想您需要所有这些,因为您需要在运行时动态加载这些类。

    可能URL是一个绝对文件路径,而不是指向应用程序类路径中的类的路径。Argh,可能就是这样,因为它指的是一个.class文件在单独文件夹中的位置,所以它切换到一个.jar文件系统,工作正常。谢谢你的建议。