0

My web app runs tomcat 7, myfaces, primefaces.

I have a problem on my production m/c that I am not able to replicate on development environment even though the exact code and libraries are loaded on both the machines. The only difference is the tomcat subversion, dev has tomcat7.0.35 and prod has tomcat7.0.40

javax.servlet.ServletException: javax.el.ELException: java.lang.NoClassDefFoundError: Could not initialize class com.myapps.util.UIStringUtil
javax.faces.webapp.FacesServlet.service(FacesServlet.java:229)
com.myapps.util.LoginFilter.doFilter(LoginFilter.java:56) **root cause** java.lang.NoClassDefFoundError: Could not initialize class com.myapps.util.UIStringUtil
com.myapps.bean.UserAuthBean.login(UserAuthBean.java:106)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
java.lang.reflect.Method.invoke(Method.java:597)
org.apache.el.parser.AstValue.invoke(AstValue.java:278)
org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:274)
org.apache.myfaces.view.facelets.el.ContextAwareTagMethodExpression.invoke(ContextAwareTagMethodExpression.java:96)
org.apache.myfaces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:68)
javax.faces.component.UICommand.broadcast(UICommand.java:120)
javax.faces.component.UIViewRoot._broadcastAll(UIViewRoot.java:1028)
javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:286)
javax.faces.component.UIViewRoot._process(UIViewRoot.java:1375)
javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:752)
org.apache.myfaces.lifecycle.InvokeApplicationExecutor.execute(InvokeApplicationExecutor.java:38)
org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:170)
org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
javax.faces.webapp.FacesServlet.service(FacesServlet.java:197)
com.myapps.util.LoginFilter.doFilter(LoginFilter.java:56)

I am not sure why this is happening. I am curious why this is being thrown as a javax.el.Elexception, where was this is being thrown from with in java bean code. The exact line of code where this is happening is (UserAuthBean.java:106)

context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, 
                    UIStringUtil.getUIString("msgKey"), 
                    UIStringUtil.getUIString("msgKey")));

UIStringUtil class has static variables and methods that help read data from resource bundles.

As I mentioned earlier, this is only happening on the production box and we are not able to reproduce it on the development box.

Please provide some help here.

Murali D
  • 448
  • 1
  • 4
  • 18
  • How are you deploying the application and libraries I wonder. My spider senses tell me that there are classloader conflicts going on here, but without having access to the machine that will always remain just a gut feeling. – Gimby Dec 12 '13 at 09:20
  • Just figured out a solution, but still don't know why the issue came in the first place. In UIStringUtil class, I replaced private static ResourceBundle appmsgbundle = FacesContext.getCurrentInstance().getApplication().getResourceBundle(FacesContext.getCurrentInstance(),"appmessages"); with private static ResourceBundle appmsgbundle = ResourceBundle.getBundle("com.myapps.util.appmessages"); And that fixed the problem. It looks like, for some reason FacexContext initiation was having a problem. But don't know why. – Murali D Dec 12 '13 at 10:18

1 Answers1

1

It's thrown as an ELException because it happened during executing some EL expression.

You should be looking at the root cause of the exception to learn about the root cause of the exception. Look further down in the stack trace to find the root cause. The first is already present in the incomplete stacktrace you posted:

java.lang.NoClassDefFoundError: Could not initialize class com.myapps.util.UIStringUtil

This basically means that loading of the class as done by Java under the covers as follows

Class.forName("com.myapps.util.UIStringUtil");

has failed with an exception. If you're absolutely positive that the class is present in the runtime classpath, then that can only mean that any of the static variables or initializer blocks of the class has thrown an exception. Loading a class namely initializes all static variables and executes all static initilaizer blocks (haven't you ever wondered how those JDBC drivers work?).

That exception should in turn be visible as the bottommost root cause in the stack trace, after the java.lang.NoClassDefFoundError cause. Perhaps a rather self-explaining java.lang.NullPointerException?

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • ..yes indeed, as posted in my comment on the question above, I discovered that the ResourceBundle initialization from FacesContext was causing the problem. But I am still not sure why that would a problem on production box and not on development box. Also, as described in my fix above, when I take FacesContext out of picture to initialize the ResourceBundle everything seems to work OK. At this point I have a fix, but still don't understand what caused the issue. – Murali D Dec 12 '13 at 12:15
  • `FacesContext` is only available during a HTTP request which triggered the `FacesServlet` (obviously, because it's the one responsible for creating the `FacesContext` as a thread local). An arbitrary class isn't necessarily loaded exactly during a HTTP request which triggered the `FacesServlet`. It can also be loaded there before, e.g. during application startup. So the assumption that the `FacesContext` would be available during loading of a class is a very wrong one. – BalusC Dec 12 '13 at 12:17
  • This is definitely done during a HTTP request cycle, so FacesContext is available. – Murali D Dec 12 '13 at 12:21
  • Uh, as said, an arbitrary class isn't necesarily loaded during a HTTP request which triggered the `FacesServlet`. In your particular case, the class was already loaded beforehand and marked as unavailable because loading of the class failed. Any subsequent attempt to access the class won't reload the class or so, even when the preconditions are right (during a HTTP request which triggered the `FacesServlet`). You've there simply a severe design mistake by incorrectly relying on the `FacesContext` being available **all time** in static context. – BalusC Dec 12 '13 at 12:22
  • "" the class was already loaded beforehand and marked as unavailable because loading of the class failed"" .. is probably the reason, I didn't know that could happen..Thanks – Murali D Dec 12 '13 at 12:26