Community
Participate
Working Groups
Build Identifier: 7.3.1.v20110307 (Stack trace included bellow) When trying to locate a class via Class.forName method, which ultimately delegates on org.eclipse.jetty.webapp.WebAppClassLoader.loadClass method, throws NoClassDefFoundError if the class name is accidentally miscapilatized. We do surround Class.forName into a try{}catch(Exception) block, but such a block is intended to catch exceptions, not errors. In fact, Java documentation recommends not to catch such errors and Class.forName states that will throw ClassNotFoundException if the given class name is not found. Stack trace: java.lang.NoClassDefFoundError: test/myClass (wrong name: test/MyClass) at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632) at java.lang.ClassLoader.defineClass(ClassLoader.java:616) at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141) at java.net.URLClassLoader.defineClass(URLClassLoader.java:283) at java.net.URLClassLoader.access$000(URLClassLoader.java:58) at java.net.URLClassLoader$1.run(URLClassLoader.java:197) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:411) at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:373) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:169) at com.cm.util.CMUtil.classForName(CMUtil.java:252) at com.cm.util.CMUtil.newInstance(CMUtil.java:1224) at com.cm.cfg.Config.lookup(Config.java:261) at com.cm.parser.MethodToken.get(MethodToken.java:151) at com.cm.parser.Token.eval(Token.java:82) at com.cm.parser.Token.eval(Token.java:19) at com.cm.parser.MethodToken.callMethod(MethodToken.java:46) at com.cm.web.util.WebMethodToken.callMethod(WebMethodToken.java:54) at com.cm.parser.MethodToken.get(MethodToken.java:149) at com.cm.parser.Token.eval(Token.java:84) at com.cm.parser.Token.eval(Token.java:19) at com.cm.web.tag.SetTag.doStartTag(SetTag.java:121) at org.apache.jsp.WebUsuView_005fBrowseEdit_jsp._jspx_meth_cm_set_0(org.apache.jsp.WebUsuView_005fBrowseEdit_jsp:216) at org.apache.jsp.WebUsuView_005fBrowseEdit_jsp.access$0(org.apache.jsp.WebUsuView_005fBrowseEdit_jsp:204) at org.apache.jsp.WebUsuView_005fBrowseEdit_jsp$WebUsuView_005fBrowseEdit_jspHelper.invoke0(org.apache.jsp.WebUsuView_005fBrowseEdit_jsp:408) at org.apache.jsp.WebUsuView_005fBrowseEdit_jsp$WebUsuView_005fBrowseEdit_jspHelper.invoke(org.apache.jsp.WebUsuView_005fBrowseEdit_jsp:514) at org.apache.jsp.tag.web.body_tag.doTag(org.apache.jsp.tag.web.body_tag:115) at org.apache.jsp.WebUsuView_005fBrowseEdit_jsp._jspx_meth_ui_body_0(org.apache.jsp.WebUsuView_005fBrowseEdit_jsp:200) at org.apache.jsp.WebUsuView_005fBrowseEdit_jsp._jspService(org.apache.jsp.WebUsuView_005fBrowseEdit_jsp:133) at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:109) at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:389) at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:486) at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:380) at javax.servlet.http.HttpServlet.service(HttpServlet.java:820) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:534) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1352) at com.cm.web.CMFilter.doFilter(CMFilter.java:99) at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1323) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:474) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:119) at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:480) at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226) at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:934) at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:404) at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:184) at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:869) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:117) at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:247) at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:151) at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116) at org.eclipse.jetty.server.Server.handle(Server.java:346) at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:581) at org.eclipse.jetty.server.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:1040) at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:592) at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:214) at org.eclipse.jetty.server.HttpConnection.handle(HttpConnection.java:411) at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:526) at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:41) at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:528) at java.lang.Thread.run(Thread.java:662) Reproducible: Always Steps to Reproduce: 1. Place a class into WEB-INF/classes, say test.MyClass 2. Try 'Class.forName("test.myClass")' from within the web application.
Miguel, The problem is that on windows, the class name is found, because windows file systems are case insensitive. The NoClassDefFoundError is being thrown by java.lang.ClassLoader and I can only assume that this is the standard behaviour for such mismatches. I understand that it is annoying to have an error thrown in that situation, but I don't think Jetty should differ from the standard classloader.
(In reply to comment #1) Yes, the problem has to do with Windows' case-insensitive filesystem... but somehow other servlet containers such us Tomcat do throw 'ClassNotFoundException' as expected (actually I found this issue while trying to migrate from Tomcat to Jetty) Is there any chance this issue gets solved?
well, greg has commented on the issue saying that he does not want to add a special case to the webapp classloader just so a CNFE is thrown when some someone triggers this windows issue. that being said if you care enough about the issue that you were to supply a patch with test case and reopened the issue we would take another look at it personally I think the default behavior of the classloader ought to be respected in this case but then I am not the one running into this issue and can't say how painful the work around is in userland
(In reply to comment #3) > well, greg has commented on the issue saying that he does not want to add a > special case to the webapp classloader just so a CNFE is thrown when some > someone triggers this windows issue. > > that being said if you care enough about the issue that you were to supply a > patch with test case and reopened the issue we would take another look at it > > personally I think the default behavior of the classloader ought to be > respected in this case but then I am not the one running into this issue and > can't say how painful the work around is in userland I see your point... and solving this issue is no more difficult than changing "catch(Exception e)" for "catch(Throwable e)" to me, so I'm also more interested in what it should behave like than in the impact on my code. What I'm worried about is an inconsistent behaviour of "Class.forName()" depending on the operating system's filesystem specifics... ... maybe I should file this bug/request to Oracle itself... Thanks so much as I'd rather consider this issue as "WONTFIX" also.
fwiw, I suspect if linux was plagued by an underlying filesystem that was case insensitive it would be consistent with how windows works
(In reply to comment #5) > fwiw, I suspect if linux was plagued by an underlying filesystem that was case > insensitive it would be consistent with how windows works I agree... and that's why I think I should file this issue to Oracle. I think Java should hide filesystem specifics, so if FAT or NTFS is case insensitive, Java should do nothing about it. But I think class loading should be consistent regardless the filesystem class files are stored into... IMHO Thanks so much.