Igor Kromin |   Consultant. Coder. Blogger. Tinkerer. Gamer.

I've been working on moving our web services at work to WebLogic 12.1.2 and noticed a curious issue. When I first moved one of the web services across, I knew for a fact that the method that's annotated with @PostConstruct would fail (due to changed data source names). However, when I deployed the service it was successful. Looking at the managed server logs, the service did indeed fail during initialisation, so subsequent calls to this service were failing for me. This seemed like a problem so I went out to verify it with a simple example.

Note: this is fixed by applying WebLogic patch 20690287.

First lets look at what the Java EE 7 specification says about @PostConstruct:
...
If the method throws an unchecked exception the class MUST NOT be put into service except in the case of EJBs where the EJB can handle exceptions and even recover from them.
...


So there you go, it's quite clear that the method can throw an unchecked exception which will cause the class that the annotated method is a part of to not be put into service i.e. it should fail deployment.

So to try this out, I created a very simple JAX-WS web service and added the following method:
 WsExampleImpl.java
...
@PostConstruct
private void init() {
System.out.println("Inside init() method for WsExampleImpl");
throw new RuntimeException("This exception should stop the web service from being put into service");
}
...


I used the jwsc Ant task to build the service and then the wldeploy task to deploy it. It succeeded! This is where it should have failed. To verify, I went into the WLS console...
wspostconstruct.png


My service was in the Active state meaning it was good to serve requests. In my example service, calls would succeed, however in the real service that I was moving over we were relying on having certain information available that was set up in the @PostConstruct annotated method. Since that information was not available, that service would fail all the time.



I wanted to be absolutely sure that WebLogic was doing something fishy, so I checked out the logs, I could definitely see my service initialising and throwing the exception.
 WebLogic managed server log
Inside init() method for WsExampleImpl
<WSEE:32>com.bea.core.repackaged.springframework.beans.factory.BeanCreationException: Error creating bean with name 'net.igorkromin.WsExampleImpl': Initialization of bean failed; nested exception is com.oracle.pitchfork.interfaces.LifecycleCallbackException: Failure to invoke private void net.igorkromin.WsExampleImpl.init() on bean class class net.igorkromin.WsExampleImpl with args: null<WSEEComponentContributor.loadUsingSpring:79>
com.bea.core.repackaged.springframework.beans.factory.BeanCreationException: Error creating bean with name 'net.igorkromin.WsExampleImpl': Initialization of bean failed; nested exception is com.oracle.pitchfork.interfaces.LifecycleCallbackException: Failure to invoke private void net.igorkromin.WsExampleImpl.init() on bean class class net.igorkromin.WsExampleImpl with args: null
at com.bea.core.repackaged.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:478)
at com.bea.core.repackaged.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at com.bea.core.repackaged.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
...
at weblogic.work.SelfTuningWorkManagerImpl$WorkAdapterImpl.run(SelfTuningWorkManagerImpl.java:550)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:295)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:254)
Caused by: com.oracle.pitchfork.interfaces.LifecycleCallbackException: Failure to invoke private void net.igorkromin.WsExampleImpl.init() on bean class class net.igorkromin.WsExampleImpl with args: null
at com.oracle.pitchfork.inject.Jsr250Metadata.invokeLifecycleMethod(Jsr250Metadata.java:398)
at com.oracle.pitchfork.inject.Jsr250Metadata.invokeLifecycleMethods(Jsr250Metadata.java:368)
at com.oracle.pitchfork.inject.Jsr250Metadata.invokePostConstructAndRegisterShutdownHook(Jsr250Metadata.java:255)
at com.oracle.pitchfork.inject.Jsr250Metadata.injectAndPostConstruct(Jsr250Metadata.java:250)
at com.oracle.pitchfork.inject.Jsr250MetadataBeanPostProcessor. postProcessAfterInstantiation(Jsr250MetadataBeanPostProcessor.java:40)
at com.bea.core.repackaged.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:957)
at com.bea.core.repackaged.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:470)
... 78 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.oracle.pitchfork.inject.Jsr250Metadata.invokeLifecycleMethod(Jsr250Metadata.java:396)
... 84 more
Caused by: java.lang.RuntimeException: This exception should stop the web service from being put into service
at net.igorkromin.WsExampleImpl.init(Unknown Source)
... 89 more


So it looks like the issue is with WebLogic ignoring the exceptions being thrown. I've logged a service request with Oracle Support on this and they confirm the issue does not exist in 12.1.3, however at the moment 12.1.2 still has this problem.

-i

Did you like this post or found it useful? Considering supporting this Blog to keep its web servers running, any amount helps! Thanks!
Have comments or feedback on what I wrote? Please share them below!
comments powered by Disqus
Other posts you may like...