在我正在开发的应用程序的模块加载程序中加载类时,我似乎遇到了问题。基本上,我将要加载的所有类都扩展了另一个类,它位于实际应用程序中的包中。为了我们的目的,我们叫它模块。模块位于实际应用程序之外的单独文件夹中。
加载器遍历一个文件夹,并对扩展名为loadFile()的任何文件执行.class ()方法。所有类都将包声明作为Module类,以及类头中的extends声明。
这是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();我一直在第三行得到一个ClassNotFoundException。过了这一步,如果它不是ClassNotFoundException,所有的依赖都会被解决吗?
发布于 2012-06-01 21:54:24
来自URLCLassLoader的文档:
这个类加载器用于从引用JAR文件和目录的URL搜索路径加载类和资源。任何以'/‘结尾的URL都假定是指目录。否则,假设URL引用一个JAR文件,该JAR文件将根据需要打开。
因此,您必须对目录或.jars使用URL。
有两种解决办法:
发布于 2012-06-01 22:16:02
在URLClassLoader中,不要传递文件,而是传递父文件夹。但是,如果类都在“默认包”中,这是正确的,因此您正在加载的.class文件的顶部不能有包声明。
默认情况下,类加载器还将触发正确构建类所需的所有类的加载:它将尝试加载超类、超类等.所有接口和超级接口、静态字段和方法所需的类、方法签名所需的类(返回类型和参数)。它通常不会尝试加载方法内部使用的类,直到您执行这些方法。
但是,类加载器通常不会“包含”所有这些类,例如,您的类最终将继承java.lang.Object,而您的URLClassLoader将不包含Object.class文件。因此,类加载器将委托给它们的父类加载器。
您目前正在创建一个URLClassLoader,而没有指定父类,在Java 7中,至少父类将默认为"system class loader",只要您是在普通的java应用程序中,并且没有在特定的类加载器层次结构中执行代码本身,这是很好的。但是,如果您在web应用程序或OSGI容器中运行该代码等。您应该给URLClassLoader一个适当的父级委托,例如Thread.currentThread().getContextClassLoader()或this.getClass().getClassLoader()。
我认为您需要所有这些,因为您需要在运行时动态加载这些类。
https://stackoverflow.com/questions/10857720
复制相似问题