vendredi 20 septembre 2019

Class.getDeclaredMethods throwing NoClassDefFoundError for class method with no arguments and void return type

I want to get the names of all the public methods (void return type and no arguments) of a class1 which is dependent on some other class2. I am loading class through UrlClassLoader. Now when i am calling getDeclaredMethods, it is throwing NoClassDefFoundError caused by ClassNotFoundException.

I am having 3 mvn modules as

  1. SampleClassLoader: Using it to get the methods of class of Module1.
  2. Module1: Its class using the reference to classes of Module2. And has a dependency of Module2 in its pom.xml also.
  3. Module2

The whole module structure looks like: Project Structure

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();
        }

    }
}

Now, When Running the SampleClassLoader for class Module1Class1 prints

claas1Fun

But when running for class Module1Class2 it is giving NoClassDefFoundError as:

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

I am having two questions here that is:

  1. When using try catch, why it is giving error?
  2. If the class1 is already loaded at classLoader.loadClass then why getDeclaredMethods method need to load dependent classes?




Aucun commentaire:

Enregistrer un commentaire