[英]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.