I have a very simple listing
my.package.data.util
public enum Mode { SQLEXPORT, PREVIEW, PRINT }
What is used in another class, since enumerations should be used
my.package.program.ComponentController
switch (_mode) { // line 278, _mode is of type my.package.data.util.Mode case PREVIEW: // Do thing for preview break; case SQLEXPORT: // Do thing for SQL break; case PRINT: // Do thing for print break; default: throw new IllegalArgumentException(); }
These two classes are in the same project and compiled into a jar file.
Then the web project uses this library (placed in the WEB-INF/lib folder). But, when the time comes to use this library and, in particular, this switch, NoClassDefFoundError appears:
NoClassDefFoundError: my / package / program / ComponentController $ 1
in my.package.program.ComponentController.doCall (ComponentController.java:278)
This is something that I cannot understand at several levels:
- Why is Java trying to load the inner class (as seen at
$1 ). There is no inner class in the ComponentController , and it has never been. - Why does Java think the switch uses this inner class as an argument
- If the class
my.package.data.util.Mode disappeared.
What's going on here?
Additional information is not in the original question
ComponentController extends another class, SessionBuilder . This class also has no inner classes.
I decompiled ComponentController using javap and tried to find interesting things in the resulting byte code.
It looks like there really is an inner class in the byte code:
public class my.package.program.ComponentController extends my.other.package.SessionBuilder SourceFile: "ComponentController.java" InnerClasses: static #192 of #2;
This class is used whenever my.package.data.util.Mode referenced:
#192 = Class
And also, when the transition actually occurs:
183: getstatic #102 // Field my/package/program/ComponentController$1.$SwitchMap$my$package$data$util$Mode:[I 186: aload_0 187: getfield #5 // Field _mode:Lmy/package/data/util/Mode; 190: invokevirtual #103 // Method my/package/data/util/Mode.ordinal:()I 193: iaload 194: tableswitch { // 1 to 3 1: 220 2: 335 3: 440 default: 516 }
Further research on issues related to Rich caused something interesting: the jar built from the library project differs by the local installation of tomcat and the one used to create the jar for the production server:
Left: jar in WEB-INF/lib via local tomcat using eclipse, right: jar , like ANT built

Now it seems that the build process used by eclipse when publishing to the local tomcat is different from what ANT does (this is AFAIK just a simple javac call)
Ok, now I just copied the jar created by ANT to the local WEB-INF/lib cats, and everything works fine. Of course, this means that after every change in the library project, I have to manually copy the new jar to my tomcat lib.
I filed this as an error report in eclipse and report any news.