If a NoClassDefFoundError is caused by a ClassNotFoundException, why does Java expect you to catch both throwables?
error-handling, exception, java, throwable
Solution
So, you are misunderstanding your stack trace.
java.lang.NoClassDefFoundError: com/my/package/MyClass
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
at Main$MyClassLoader.getClasses(Main.java:78)
at Main.main(Main.java:109)
Caused by: java.lang.ClassNotFoundException: com.my.package.MyClass
Your code is generating a `NoClassDefFoundError`. The underlying cause is a `ClassNotFoundException`. Remember that `cause` is a property of the Throwable class, and that when printing stacktraces, Java will display information both on the direct exception and its underlying cause(s). It's tougher to say why the `define` method is failing internally, but one thing is for sure - you cannot use the keyword `package` in a package name.
Problem
When I run this code the app exits with a ClassNotFoundException: ``` //uncaught ClassNotFoundException try { Class<?> clazz = defineClass(null, bytes, 0, bytes.length, null); table.put(clazz.getName(), clazz); } catch (NoClassDefFoundError e) { } ``` When I attempt to compile this code, the compiler complains that the ClassNotFoundException is not reachable because it is not thrown from within the try-clause of the try-catch statement. ``` //Won't compile try { Class<?> clazz = defineClass(null, bytes, 0, bytes.length, null); table.put(clazz.getName(), clazz); } catch (ClassNotFoundException e) { } ``` When I run this code, the only throwable that is caught is a NoClassDefFoundError. ``` //catches throwable of type java.lang.NoClassDefFoundError, //with a java.lang.ClassNotFoundException as its cause try { Class<?> clazz = defineClass(null, bytes, 0, bytes.length, null); table.put(clazz.getName(), clazz); } catch (Throwable e) { System.out.println(e.getClass().getName()); System.out.println(e.getCause().getClass().getName()); } ``` The following code will compile and catch the error (and only the error), but it's clumsy: ``` //possible workaround try { Class<?> clazz = defineClass(null, bytes, 0, bytes.length, null); table.put(clazz.getName(), clazz); if (1 == 0) throw new ClassNotFoundException(); // we want the code to compile } catch (ClassNotFoundException e) { System.out.println("ex"); } catch (NoClassDefFoundError e) { System.out.println("err"); } ``` And yet when I write the following, I can get away without a catch clause for the cause of the error: ``` //and yet this works just fine... try { throw new Error(new IOException()); } catch (Error e) { System.out.println("err"); } ``` Example 3 would lead me to conclude that the throwable was a NoClassDefFoundError. Example 1 would lead me to conclude that the throwable was a ClassNotFoundException. And yet, Example 2 shows that java won't even let me write code to properly catch the ClassNotFoundException. Just when I was about to conclude that the problem here is the error-caused-by-an-exception, I ran the code shown in the previous example which shows that that is not the rule. Can someone please explain what's going on here? PS: this is the stack trace: ``` java.lang.NoClassDefFoundError: com/my/pckage/MyClass at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:791) at Main$MyClassLoader.getClasses(Main.java:78) at Main.main(Main.java:109) Caused by: java.lang.ClassNotFoundException: com.my.pckage.MyClass at java.lang.ClassLoader.findClass(ClassLoader.java:522) at java.lang.ClassLoader.loadClass(ClassLoader.java:423) at java.lang.ClassLoader.loadClass(ClassLoader.java:356) ... 4 more ```