Description
AbstractTransportFactory calls register() at the end of its constructor, to register itself as a DestinationFactory and/or as a ConduitInitiator. Classes that extend AbstractTransportFactory (e.g. HTTPTransportFactory), and which call super's constructor, have no way to properly initialize, before being exposed as an extension. Such classes must call super() constructor, before initializing their fields.
This could lead to concurrency issues, when such object is used as an extension, before being fully initialized. Here is a stack trace of such problem:
java.lang.NullPointerException
at org.apache.cxf.transport.http.HTTPTransportFactory.getDestination(HTTPTransportFactory.java:261)
at org.apache.cxf.binding.soap.SoapTransportFactory.getDestination(SoapTransportFactory.java:134)
at org.apache.cxf.endpoint.ServerImpl.initDestination(ServerImpl.java:93)
at org.apache.cxf.endpoint.ServerImpl.<init>(ServerImpl.java:72)
at org.apache.cxf.frontend.ServerFactoryBean.create(ServerFactoryBean.java:158)
at org.apache.cxf.dosgi.dsw.handlers.PojoConfigurationTypeHandler.createServer(PojoConfigurationTypeHandler.java:143)
at org.apache.cxf.dosgi.dsw.hooks.ServiceHookUtils.createServer(ServiceHookUtils.java:86)
at org.apache.cxf.dosgi.dsw.hooks.CxfPublishHook.createServer(CxfPublishHook.java:106)
at org.apache.cxf.dosgi.dsw.hooks.CxfPublishHook.publishEndpoint(CxfPublishHook.java:80)
at org.apache.cxf.dosgi.dsw.Activator$1.run(Activator.java:164)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)
Here, the HTTPTransportFactory.getDestination() method, implementing DestinationFactory interface, is called before HTTPTransportFactory's "registry" field is assigned by constructor.