How To Catch A ClassNotFoundException

By , 13 April 2014

How To Catch A ClassNotFoundException
How To Catch A ClassNotFoundException

HTTP request from spammers trying to exploit our commenting system is causing a ClassNotFoundException deep in the JSF / Java code. Specifically, spammers are sending serialized objects in the javax.jsf.ViewState parameter for classes that no longer exist in our system. The resulting exception is this:

How To Catch A ClassNotFoundException
java.lang.ClassNotFoundException: ox.cms.designer.UIMenu$MenuLayout
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:247)
    at com.sun.faces.renderkit.ApplicationObjectInputStream.resolveClass(ApplicationObjectInputStream.java:95)
    at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1574)
    at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
    at java.io.ObjectInputStream.readEnum(ObjectInputStream.java:1685)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1325)
    at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1666)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1322)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at java.util.HashMap.readObject(HashMap.java:1030)
    at sun.reflect.GeneratedMethodAccessor12161.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:974)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1848)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1752)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
    at com.sun.faces.renderkit.ClientSideStateHelper.doGetState(ClientSideStateHelper.java:255)
    at com.sun.faces.renderkit.ClientSideStateHelper.getState(ClientSideStateHelper.java:198)
    at com.sun.faces.renderkit.ResponseStateManagerImpl.getState(ResponseStateManagerImpl.java:100)
    at com.sun.faces.application.view.StateManagementStrategyImpl.restoreView(StateManagementStrategyImpl.java:224)
    at com.sun.faces.application.StateManagerImpl.restoreView(StateManagerImpl.java:188)
    at com.sun.faces.application.view.ViewHandlingStrategy.restoreView(ViewHandlingStrategy.java:123)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.restoreView(FaceletViewHandlingStrategy.java:453)
    at com.sun.faces.application.view.MultiViewHandler.restoreView(MultiViewHandler.java:142)
    at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:303)
    at javax.faces.application.ViewHandlerWrapper.restoreView(ViewHandlerWrapper.java:303)
    at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:192)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:116)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)

Nasty stuff.

The problem gets worse because ClassNotFoundException is a checked exception (although somehow the URLClassLoader gets to ignore it), so we can't just put a catch block in our filter because the compiler complains that the exception is never thrown.

Fortunately there is a simple, if not slightly ugly solution:

            try {

                // this line allows us to catch a ClassNotFoundException
                if (false) Class.forName("java.lang.Class");
                chain.doFilter(request, response);
            } catch (ClassNotFoundException cnfe) {
                Log.warning(cnfe.getMessage() + " (spam)");
            }

So much for checked exceptions.

About Roger Keays

How To Catch A ClassNotFoundException

I guess I'd call myself a problem solver. Either that, or I'm some sort of organic machine designed to convert oxygen into carbon dioxide. You could go either way on that. I'm into languages and stuff. I wrote a book. It's okay, I guess. What else? I like reading, swimming, eating, and playing music. Satisfied? Sheesh.

Leave a Comment

Please visit https://rogerkeays.com/how-to-catch-a-classnotfoundexception to add your comments.