Search code examples
web-servicesweblogicweb-deploymentweblogic12cstateless

NameAlreadyBoundException if use of @Stateless in a webservice with web.xml


I'm trying to deploy in Weblogic 12c a webservice using the following annotations:

@SchemaValidation
@BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
@WebService(serviceName = "xxxxx",
        targetNamespace = "http://bla/BusinessServices/yyy/xxxxx/V1",
        wsdlLocation = "META-INF/wsdl/zzz/yyy/xxxxx/V1/xxxxxConcrete.wsdl",
        portName = "xxxxxPort",
        endpointInterface = "ble.businessservices.yyy.xxxxx.v1.xxxxx")
//@Transactional(value= Transactional.TransactionFlowType.SUPPORTS, version= Transactional.Version.WSAT12)
@Stateless
@SecurityPolicies(@SecurityPolicy(uri = "my_policy"))
@DeclareRoles("my-role")
@Interceptors({InterceptorClass1.class, InterceptorClass2.class, InterceptorClass3.class})
public class xxxxxV1 extends HttpServlet implements xxxxx {...}

I'm using a web.xml to define the servlet alias and a weblogic.xml file to define the context root I want to use.

The problem is, if I leave the @Stateless annotation, when deploying I get the following exception:

Target state: deploy failed on Server services_server
javax.naming.NameAlreadyBoundException: my-webservice-name-impl-1.0.0.0-SNAPSHOT.war#MyWebServiceName is already bound; remaining name 'app/wsee'
    at weblogic.deploy.api.tools.deployer.Jsr88Operation.report(Jsr88Operation.java:547)
    at weblogic.deploy.api.tools.deployer.Deployer.perform(Deployer.java:140)
    at weblogic.deploy.api.tools.deployer.Deployer.runBody(Deployer.java:88)
    at weblogic.utils.compiler.Tool.run(Tool.java:158)
    at weblogic.utils.compiler.Tool.run(Tool.java:115)
    at weblogic.Deployer.run(Deployer.java:74)
    ... 15 more

On the other hand, if I delete web.xml, I can deploy without error, but of course the URL to my webservice is not the one I want to define: it uses the /portName/serviceName URL.

And, if I delete the @Stateless annotation, I get the needed URL, but the interceptors are ignored, which is logically unacceptable.

I have tried using the @Transactional annotation (see commented code above), but interceptors keep getting ignored.

Anyone has an idea of what I'm missing? Ideally, I would use web.xml and @Transactional and get into the interceptors.

Thank you all!


Solution

  • Found a workaround for making everything work as needed: the delegation pattern.

    The webservice class has now the following annotations:

    @SchemaValidation
    @BindingType(javax.xml.ws.soap.SOAPBinding.SOAP12HTTP_BINDING)
    @WebService(serviceName = "xxxxx",
            targetNamespace = "http://bla/BusinessServices/yyy/xxxxx/V1",
            wsdlLocation = "META-INF/wsdl/zzz/yyy/xxxxx/V1/xxxxxConcrete.wsdl",
            portName = "xxxxxPort",
            endpointInterface = "ble.businessservices.yyy.xxxxx.v1.xxxxx")
    @Transactional(value= Transactional.TransactionFlowType.SUPPORTS, version= Transactional.Version.WSAT12)
    @SecurityPolicies(@SecurityPolicy(uri = "my_policy"))
    public class xxxxxV1 extends HttpServlet implements xxxxx {...}
    

    I then use a delegate class xxxxxV1Delegate with the following annotations:

    @Stateless
    @DeclareRoles("my-role")
    @Interceptors({InterceptorClass1.class, InterceptorClass2.class, InterceptorClass3.class})
    public class xxxxxV1Delegate {...}
    

    In this class all the implementation is done (basically copy-pasting what was in the webservice class and deleting the @Overrides)

    The webservice class will inject a xxxxxV1Delegate and contain all the @Override methods. Each method will just call the exact same method in the delegate class.