#java #classloader
Вопрос:
Я пытаюсь написать свой собственный загрузчик классов. Вот мой код загрузчика классов.
package server;
import java.net.URL;
import java.net.URLClassLoader;
public class MyClassloader extends URLClassLoader {
public MyClassloader(URL[] urls) {
super(urls);
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
Class<?> aClass = super.findClass(name);
if (aClass == null) {
return this.getParent().loadClass(name);
}
return aClass;
}
}
И в качестве тестового класса для загрузки есть пустой класс.
package server;
public class MyClass {}
И главная точка входа-это
package server;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
public class Main {
public static void main(String[] args) throws Exception {
// the dir that the compiled class file located in.
File file = new File("/Users/mrd2242/Desktop/javatest/testedClass/");
MyClassloader myClassloader = new MyClassloader(new URL[]{file.toURI().toURL()});
Class<?> myClass = myClassloader.loadClass("server.MyClass");
}
}
Как показали комментарии выше, сначала я скомпилирую MyClass
MyClass.class
. Затем я перемещаю его в каталог /Users/mrd2242/Desktop/javatest/testedClass/
(обратите внимание, что у этого класса есть имя пакета, поэтому абсолютный путь к файлу .class /Users/mrd2242/Desktop/javatest/testedClass/server/MyClass.class
равен.), а затем передаю URL-адрес этого каталога конструктору MyClassloader
.
Запустите код, но он не удался. Исключением является
Exception in thread "main" java.lang.NoClassDefFoundError: java/lang/Object
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:174)
at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:550)
at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:458)
at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:452)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:451)
at server.MyClassloader.loadClass(MyClassloader.java:14)
at server.Main.main(Main.java:12)
Caused by: java.lang.ClassNotFoundException: java.lang.Object
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
at server.MyClassloader.loadClass(MyClassloader.java:14)
... 10 more
С моей точки зрения, это так запутанно. Я переопределяю этот loadClass
метод, чтобы
- Первый класс загрузки с заданного URL
URLClassLoader
-адреса с использованиемfindClass
метода. - Если 1 не удалось, используйте метод родительского загрузчика
loadClass
классов для выполнения обычного процесса загрузки класса.
Но исключением кажется отчет, который java/lang/Object
не найден. Что случилось? Спасибо!
Ответ №1:
public class MyClassloader extends URLClassLoader {
public MyClassloader(URL[] urls) {
super(urls);
}
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
try {
Class<?> aClass = super.findClass(name);
return aClass;
} catch (Exception e) {
return this.getParent().loadClass(name);
}
}
}
Я перемещаю логику отказа в блок «Попытка». Это правильно?