[英]Java dynamic loading a class issue
我正在尝试编写一个代码,该代码在从字符串创建它之后会编译并运行另一个Java类。
我的问题是我跑步时
Class classToLoad = null;
ClassLoader classLoader = Server.class.getClassLoader();
try {
classToLoad = classLoader.loadClass(className);
} catch (Exception e) {
e.printStackTrace();
}
它将引发ClassNotFoundException。 我的问题与软件包无关,因为如果我调试代码并将断点放在“ getClassLoader”之前,然后重新加载类,则我的代码运行良好,并且可以看到该应用程序中最近创建的类。
如何在运行时重新加载类,以便loadClass可以工作?
看一下本教程 :
...让我们看一个简单的例子。 下面是一个简单的ClassLoader子类的示例。 请注意,它如何将类加载委派给其父级,但打算重新加载的是一个类。 如果此类的加载委托给父类加载器,则以后无法重新加载。 请记住,一个类只能由相同的ClassLoader实例加载一次。
如前所述,这只是一个示例,用于向您展示ClassLoader行为的基础。 它不是您自己的类加载器的生产就绪模板。 您自己的类加载器可能不应仅限于单个类,而应该知道您需要重新加载的类的集合。 另外,您可能也不应该对类路径进行硬编码。
public class MyClassLoader extends ClassLoader{
public MyClassLoader(ClassLoader parent) {
super(parent);
}
public Class loadClass(String name) throws ClassNotFoundException {
if(!"reflection.MyObject".equals(name))
return super.loadClass(name);
try {
String url = "file:C:/data/projects/tutorials/web/WEB-INF/" +
"classes/reflection/MyObject.class";
URL myUrl = new URL(url);
URLConnection connection = myUrl.openConnection();
InputStream input = connection.getInputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int data = input.read();
while(data != -1){
buffer.write(data);
data = input.read();
}
input.close();
byte[] classData = buffer.toByteArray();
return defineClass("reflection.MyObject",
classData, 0, classData.length);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
下面是MyClassLoader的示例用法。
public static void main(String[] args) throws
ClassNotFoundException,
IllegalAccessException,
InstantiationException {
ClassLoader parentClassLoader = MyClassLoader.class.getClassLoader();
MyClassLoader classLoader = new MyClassLoader(parentClassLoader);
Class myObjectClass = classLoader.loadClass("reflection.MyObject");
AnInterface2 object1 =
(AnInterface2) myObjectClass.newInstance();
MyObjectSuperClass object2 =
(MyObjectSuperClass) myObjectClass.newInstance();
//create new class loader so classes can be reloaded.
classLoader = new MyClassLoader(parentClassLoader);
myObjectClass = classLoader.loadClass("reflection.MyObject");
object1 = (AnInterface2) myObjectClass.newInstance();
object2 = (MyObjectSuperClass) myObjectClass.newInstance();
}
可能会问:“您正在加载类的上下文是什么?” 将有助于更好地回答您的问题。
像Spring这样的大多数标准框架都在内部处理加载类,并仅公开那些类提供的方法。
尝试使用Class.forName(String name)尝试加载类并将句柄返回给类对象。
如果要专门使用自己的类加载器加载类,请使用重载的类: Class.forName(字符串名称,布尔值初始化,ClassLoader加载器)
但是您将需要确保您的类加载器能够找到要正确加载的类。
对于您正在使用的类加载器,请尝试: Thread.currentThread()。getContextClassLoader()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.