Hi,
I was under the impresion that the JAX-WS @PostConstruct annotation was a way of getting an initialization routine in one's web service to run one time...and only one time. This jives with my experience writing Metro web services based on Metro releases 1.5, 2.0, 2.1 and 2.2.
Imagine my surprise when I took my webservice code and without changing my source code at all, slipped in the Metro 2.3 runtime. Suddenly my @PostContruct init method is running twice! This is not what I want at all!
My research tells me Metro 2.3 is using the JAX-WS 2.2.8 RI whereas Metro 2.2, where things still work as expected, is using JAX-WS 2.2.6.5. Is this a bug in the Metro 2.3 Implementation? I saw a Glassfish bug about multiple calls to @PostConstruct methods, and while it didn't quite look like my setup, I am suspicious.
------------------
Platform specs:
I am deploying in a Tomcat 6.0.24 container
Using OpenJDK 1.7.0.25
Linux RHEL6
I walked through the code as best I could and I can see the first and second invocation of the @PostContruct method is happening inside the implementation of com.sun.xml.ws.api.server.WSEndpoint.create. I'm still honing in on this, but the older JAXWS 2.2.6 class has a create method that looks like this
public static WSEndpoint create(
@NotNull Class implType,
boolean processHandlerAnnotation,
@Nullable Invoker invoker,
@Nullable QName serviceName,
@Nullable QName portName,
@Nullable Container container,
@Nullable WSBinding binding,
@Nullable SDDocumentSource primaryWsdl,
@Nullable Collection<? extends SDDocumentSource> metadata,
@Nullable EntityResolver resolver,
boolean isTransportSynchronous,
boolean isStandard)
{
final WSEndpoint endpoint =
EndpointFactory.createEndpoint(
implType,processHandlerAnnotation, invoker,serviceName,portName,container,binding,primaryWsdl,metadata,resolver,isTransportSynchronous,isStandard);
final Iterator managementFactories = ServiceFinder.find(ManagedEndpointFactory.class).iterator();
if (managementFactories.hasNext()) {
final ManagedEndpointFactory managementFactory = managementFactories.next();
final EndpointCreationAttributes attributes = new EndpointCreationAttributes(
processHandlerAnnotation, invoker, resolver, isTransportSynchronous);
return managementFactory.createEndpoint(endpoint, attributes);
}
return endpoint;
}
where as the newer, duplicating 2.2.8 class has this method with extra stuff concerning EndpointAwareTubes (yeesh)
public static WSEndpoint create(
@NotNull Class implType,
boolean processHandlerAnnotation,
@Nullable Invoker invoker,
@Nullable QName serviceName,
@Nullable QName portName,
@Nullable Container container,
@Nullable WSBinding binding,
@Nullable SDDocumentSource primaryWsdl,
@Nullable Collection<? extends SDDocumentSource> metadata,
@Nullable EntityResolver resolver,
boolean isTransportSynchronous,
boolean isStandard)
{
final WSEndpoint endpoint =
EndpointFactory.createEndpoint(
implType,processHandlerAnnotation, invoker,serviceName,portName,container,binding,primaryWsdl,metadata,resolver,isTransportSynchronous,isStandard);
final Iterator managementFactories = ServiceFinder.find(ManagedEndpointFactory.class).iterator();
if (managementFactories.hasNext()) {
final ManagedEndpointFactory managementFactory = managementFactories.next();
final EndpointCreationAttributes attributes = new EndpointCreationAttributes(
processHandlerAnnotation, invoker, resolver, isTransportSynchronous);
WSEndpoint managedEndpoint = managementFactory.createEndpoint(endpoint, attributes);
if (endpoint.getAssemblerContext().getTerminalTube() instanceof EndpointAwareTube) {
((EndpointAwareTube)endpoint.getAssemblerContext().getTerminalTube()).setEndpoint(managedEndpoint);
}
return managedEndpoint;
}
return endpoint;
}
The second call to my @PostConstruct method happen inside the setEndpoint call on the EndpointAwareTube. Tubes...NOOOOO :-)
--------------
Thanks in advance for any clarification as to bug...or (sigh) new feature.