Search code examples
jsfnoclassdeffounderrorbean-validationomnifaces

Deploying OmniFaces 3.1 on Tomcat 8 without BV throws java.lang.NoClassDefFoundError: javax/validation/ConstraintViolation


I am attempting to install OmniFaces 3.1 for the first time. After adding the dependency to my pom file, a NoClassDefFoundError occurs when the Tomcat server is started. I have not yet made any other (web.xml, faces-config.xml) configuration changes; only added the dependency.

Apparently the exception occurs because of JSR303 dependencies arising during the processing of Omnifaces class annotations. However; on the OmniFaces showcase page I read:

All OmniFaces versions have an optional dependency on JSR303 Bean Validation which is only required when you start to actually use o:validateBean or JsfLabelMessageInterpolator.

optional being the keyword.

Here is the stack trace:

java.lang.NoClassDefFoundError: javax/validation/ConstraintViolation
    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.sun.faces.util.Util.classHasAnnotations(Util.java:1145)
    at com.sun.faces.application.ApplicationInstanceFactoryMetadataMap.onPut(ApplicationInstanceFactoryMetadataMap.java:76)
    at com.sun.faces.application.ApplicationInstanceFactoryMetadataMap.onPut(ApplicationInstanceFactoryMetadataMap.java:43)
    at com.sun.faces.util.MetadataWrapperMap.put(MetadataWrapperMap.java:99)
    at com.sun.faces.config.processor.AbstractConfigProcessor.loadClass(AbstractConfigProcessor.java:425)
    at com.sun.faces.config.processor.FaceletTaglibConfigProcessor.processHandlerClass(FaceletTaglibConfigProcessor.java:446)
    at com.sun.faces.config.processor.FaceletTaglibConfigProcessor.processTags(FaceletTaglibConfigProcessor.java:393)
    at com.sun.faces.config.processor.FaceletTaglibConfigProcessor.processTagLibrary(FaceletTaglibConfigProcessor.java:327)
    at com.sun.faces.config.processor.FaceletTaglibConfigProcessor.process(FaceletTaglibConfigProcessor.java:271)
    at com.sun.faces.config.ConfigManager.initialize(ConfigManager.java:445)
    at com.sun.faces.config.ConfigureListener.contextInitialized(ConfigureListener.java:237)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4577)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5041)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1427)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1417)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:943)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:839)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1427)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1417)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
    at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:943)
    at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:258)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.StandardService.startInternal(StandardService.java:422)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:770)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:682)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:353)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:493)
Caused by: java.lang.ClassNotFoundException: javax.validation.ConstraintViolation
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1275)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1104)
    ... 44 more

Solution

  • This worked in 2.x, but indeed broke as described since 3.0.

    Root problem is, since JSF 2.3, taghandlers in JSF 2.3 compatible libraries are also scanned for annotations during webapp's startup. This will implicitly load the taghandler class behind <o:validateBean> even though when it isn't used anywhere in the webapp.

    I've as per issue 467 fixed it for 3.2-SNAPSHOT by refactoring the bean validation action into static context so that it doesn't get loaded when the taghandler class is loaded.