3
votes

Short: (Portlet-)Container swallows Exception thrown by @PostConstruct method in backing bean.

Is this behavior intentional, a bug or container specific?

Long: I am running a portlet on WebSphere Portal 7, where i force managed bean construction in a PhaseListener so it can send the user back to the start page, when the system encounters unrecoverable problems during Bean construction/post-construction.

I am using the following code to 'force' construction:

@SuppressWarnings("unchecked")
public static <T> T getManagedBean(final String beanName)
{
    final FacesContext context = getFacesContext();
    return (T)context.getApplication().evaluateExpressionGet(context, "#{" + beanName + "}", Object.class);
}

I tested throwing a RuntimeException from the @PostConstruct method

@PostConstruct
public void initialize()
{
    throw new RuntimeException("test");
}

The stacktrace ends up on the RAD(Eclipse) log:

com.ibm.ws.webcontainer.annotation.WASAnnotationHelper doInvoke unable to invoke method --> [initialize] on class --> [foo.bar.UpdateAddress]
                             java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
at java.lang.reflect.Method.invoke(Method.java:611)
at com.ibm.ws.webcontainer.annotation.WASAnnotationHelper.doInvokeSingle(WASAnnotationHelper.java:432)
at com.ibm.ws.webcontainer.annotation.WASAnnotationHelper.doInvokeChain(WASAnnotationHelper.java:400)
at com.ibm.ws.webcontainer.annotation.WASAnnotationHelper.doPostConstruct(WASAnnotationHelper.java:220)
at com.sun.faces.vendor.WebSphereInjectionProvider.invokePostConstruct(WebSphereInjectionProvider.java:86)
at com.sun.faces.mgbean.BeanBuilder.invokePostConstruct(BeanBuilder.java:225)
...
Caused by: java.lang.RuntimeException: test
    at foo.bar.UpdateAddress.initialize(UpdateAddress.java:119)
    ... 121 more

But there is no exception to catch in my PhaseListener and it happily continues without being aware of an Exception during the @PostConstruct.

Is this behavior intentional, a bug or container specific?

It looks like at least JBoss has a similar way of handling : http://www.coderanch.com/t/499013/JSF/java/PostConstruct-exception-handling

1

1 Answers

3
votes

Per section 15.5.9 of the Servlet 3.0 specification:

The @PostConstruct annotation MUST be supported by all classes that support dependency injection and called even if the class does not request any resources to be injected. If the method throws an unchecked exception the class MUST not be put into service and no method on that instance can be called.

If you're seeing different behavior, then this looks like a product defect. If the servlet is not being put into service but the exception is being swallowed, this sounds like a serviceability defect. In either case, I would recommend opening a PMR with IBM. Note that it is unlikely that your terms of service allow decompiling WebSphere Application Server classes, even for the purposes of debugging.