Я хочу получить имена всех общедоступных методов (пустой тип возвращаемого значения и без аргументов) класса1, который зависит от какого-либо другого класса2. Я загружаю класс через UrlClassLoader. Теперь, когда я вызываю getDeclaredMethods, он выдает NoClassDefFoundError, вызванный ClassNotFoundException.
У меня есть 3 модуля mvn как
- SampleClassLoader: использование для получения методов класса Module1.
- Module1: его класс, использующий ссылку на классы Module2. И также имеет зависимость от Module2 в своем pom.xml.
- Модуль2
Вся структура модуля выглядит следующим образом: Структура проекта
ClassLoadingTest
|----- Module1
| |--- pom.xml
| |--- src/main/java/
| | |--- com.classloadingtest.module1
| | |
| | |--- Module1Class1.java
| | |--- Module1Class2.java
|
|----- Module2
| |--- pom.xml
| |--- src/main/java/
| | |--- com.classloadingtest.module2
| | |
| | |--- Module2Class.java
|
|----- SampleClassLoader
| |--- pom.xml
| |--- src/main/java/
| | |--- com.classloadingtest.sampleClassLoader
| | |
| | |--- SampleClassLoader.java
Модуль1Класс1.java
public class Module1Class1 {
public void claas1Fun() {
Module2Class module2ClassObj = new Module2Class();
module2ClassObj.module2Fun();
}
}
Модуль1Класс2.java
public class Module1Class2 {
public void class2Fun(){
try {
Module2Class module2ClassObj = new Module2Class();
module2ClassObj.module2Fun();
} catch(Exception e ){
}
}
}
Module2Class.java
public class Module2Class {
public void module2Fun(){
}
}
SampleClassLoader.java
public class SampleClassLoader {
public static void main(String[] args) {
try {
URL mainSourceClassPathURL = new URL("file:" + System.getProperty("user.dir") + "/ClassLoadingTest/Module1/target/classes/");
URL[] urls = { mainSourceClassPathURL};
ClassLoader classLoader = URLClassLoader.newInstance(urls);
Class<?> testCaseClass = classLoader.loadClass("com.classloadingtest.module1.Module1Class1");
Method method[] = testCaseClass.getDeclaredMethods();
for (int i = 0 ; i < method.length ; i++) {
System.out.println(method[i].getName());
}
} catch (Exception e){
e.printStackTrace();
}
}
}
Теперь при запуске SampleClassLoader для класса Module1Class1
печатает
claas1Fun
Но при работе для класса Module1Class2
он выдает NoClassDefFoundError как:
Exception in thread "main" java.lang.NoClassDefFoundError: com/classloadingtest/module2/Module2Class
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.getDeclaredMethods(Class.java:1975)
at com.classloadingtest.sampleClassLoader.SampleClassLoader.main(SampleClassLoader.java:26)
Caused by: java.lang.ClassNotFoundException: com.classloadingtest.module2.Module2Class
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.net.FactoryURLClassLoader.loadClass(URLClassLoader.java:814)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 4 more
У меня есть два вопроса, а именно:
- Почему при использовании
try catch
выдает ошибку? - Если class1 уже загружен в
classLoader.loadClass
, то почему методgetDeclaredMethods
должен загружать зависимые классы?
Module1Class1
иModule1Class2
заключается вtry/catch
, и только второй выдает NCDFE? - person Kayaman   schedule 20.09.2019loadClass
не будет выполнять все шаги, чтобы сделать класс пригодным для использования. Как указано в этом ответе, мы должны различать загрузку, связывание, проверку и инициализацию класса.loadClass
выполнит загрузку, а не инициализацию, в то время как другие шаги могут быть выполнены позже или позже.try … catch
делает разницу между кодом без ветвей и методом с ветвями, требующим таблицы стековой карты. Это может повлиять на верификатор. Однако я не могу воспроизвести ваш результат… - person Holger   schedule 23.09.2019loadClass
может успешно вернуться, аNoClassDefFoundError
может произойти позже. - person Holger   schedule 23.09.2019