Class.getDeclaredMethods, выбрасывающий NoClassDefFoundError для метода класса без аргументов и пустого возвращаемого типа - PullRequest
0 голосов
/ 20 сентября 2019

Я хочу получить имена всех открытых методов (void, возвращаемого типа и без аргументов) для class1, который зависит от некоторого другого class2.Я загружаю класс через UrlClassLoader.Теперь, когда я вызываю getDeclaredMethods, он выбрасывает NoClassDefFoundError, вызванный ClassNotFoundException.

У меня 3 mvn-модуля:

  1. SampleClassLoader: использование его для получения методов класса Module1.
  2. Module1: его класс с использованием ссылки на классымодуля 2.И также имеет зависимость от Module2 в своем pom.xml.
  3. Module2

Вся структура модуля выглядит следующим образом: Структура проекта

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

Module1Class1.java

public class Module1Class1 {
    public void claas1Fun() {
        Module2Class module2ClassObj = new Module2Class();
        module2ClassObj.module2Fun();
    }
}

Module1Class2.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

У меня два вопросавот что:

  1. При использовании try catch, почему он выдает ошибку?
  2. Если class1 уже загружен в classLoader.loadClass, тогда зачем getDeclaredMethods метод нужно загружатьзависимые классы?

1 Ответ

0 голосов
/ 20 сентября 2019

Что касается проблемы try-catch, то дело в том, что java.lang.NoClassDefFoundError - это не Exception, а Error, что является более серьезным видом Throwable.

.говоря, невосстановимыми (как OutOfMemoryError или StackOverflowError, ...), поэтому они редко перехватываются.

Если вы хотите поймать NoClassDefFoundError, вы должны добавить catch(NoClassDefFoundError e) к вашей попытке

...