views:

671

answers:

0

I have a stateful web service deployed onto Tomcat. It consists of factory service and main API service, and works just fine. Factory service returns a W3CEndpointReference to main API instance, and client uses the session.

Now, I'm trying to run the very same service as a standalone application. In this case, the W3CEndpointReference returned by the factory suddenly starts to point to factory URI, not to main service one.

When references from runs against Tomcat and standalone are compared, it becomes clear that standalone reference has a wrong URI. Specifically, it points to factory URI, not main API one.

Here's correct reference:

...
<ns3:Address>http://localhost:8080/td2ws/api&lt;/ns3:Address&gt; 
...

Here's references when factory is called on standalone process:

<Address>http://localhost:9009/td2ws/factory&lt;/Address&gt;

My understanding that some code under servlet context has a knowledge of correspondence between service class (Td2Ws) and it's URI, and adjusts the references accordingly. That piece of code is not in effect under standalone process though. I can even suspect that code uses sun-jaxws.xml, but I don't know how to "turn it on".

How can I make stateful web service in standalone application work?

Here are relevant parts of the code:

Factory service (stateless):

@WebService(targetNamespace="http://server.td2ws.sf.net/") 
public class Td2WsFactory {
    @WebMethod(operationName="StartSession", action="urn:StartSession")
    @WebResult(name="Reference")
    public W3CEndpointReference startSession() {
     StatefulWebServiceManager<Td2Ws> manager = Td2Ws.getManager();

     // for standalone execution only
     if( manager == null ) {
      manager = new StatefulInstanceResolver<Td2Ws>(Td2Ws.class);
      Td2Ws.setManager(manager);
     }

     Td2Ws session = new Td2Ws();
     return manager.export(W3CEndpointReference.class,session);
    }
}

Stateful API:

@Stateful
@WebService(targetNamespace="http://server.td2ws.sf.net/") 
@Addressing
public class Td2Ws {
    private static StatefulWebServiceManager<Td2Ws> manager;

    public static void setManager(StatefulWebServiceManager<Td2Ws> manager ) {
     Td2Ws.manager = manager;
    }

    public static StatefulWebServiceManager<Td2Ws> getManager() {
     return Td2Ws.manager;
    }

    @WebMethod(operationName="Login", action="urn:Login")
    public void login(
         @WebParam(name="Username") String username,
         @WebParam(name="Password") String password,
         @WebParam(name="Domain") String domain,
         @WebParam(name="Project") String project
         ) throws Td2WsException {

Client code (targeted to standalone):

public static void main(String[] args) throws Exception {
 Endpoint epf = Endpoint.publish("http://localhost:9009/td2ws/factory", new net.sf.td2ws.server.Td2WsFactory());
 Endpoint eps = Endpoint.publish("http://localhost:9009/td2ws/api", new net.sf.td2ws.server.Td2Ws());

 URL factoryUrl = new URL("http://localhost:9009/td2ws/factory?wsdl");
 QName factoryQname = new QName("http://server.td2ws.sf.net/", "Td2WsFactoryService");

 URL sessionUrl = new URL("http://localhost:9009/td2ws/api?wsdl");
 QName sessionQname = new QName("http://server.td2ws.sf.net/", "Td2WsService");

 Td2WsFactory factory = new Td2WsFactoryService(factoryUrl,factoryQname).getTd2WsFactoryPort();
 System.out.println("factory: "+factory);

 W3CEndpointReference session = factory.startSession();
 System.out.println("session: "+session);

 Td2WsService service = new Td2WsService(sessionUrl,sessionQname);
 System.out.println("service: "+service);

 Td2Ws port = service.getPort(session,Td2Ws.class);
 System.out.println("port: "+port);

 port.login(
   Config.get("td.user"), 
   Config.get("td.pass"),
   Config.get("td.domain"),
   Config.get("td.project"));
 System.out.println("logged in...");

That code fails on login() as the target object has no Login operation (it's wrongly targeted to factory URI, after all):

Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: 
Cannot find dispatch method for {http://server.td2ws.sf.net/}Login