views:

21

answers:

2

Hi,

I have a simple webservice created with Netbeans 6.5 and deployed into 2 glassfish servers V2.1 and V3. The ws has a basic method GetInstanceID that I call 3 times from a client.

@WebService()
public class FirstWS {

private long m_instanceID = 0;   //instance id

//Log
private void WriteLog(String cadena){
    String msg = "";
    DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss:SSS");
    Date fecha = new Date();
    msg = dateFormat.format(fecha) + " ***** " + this.getClass().getName() + " (m_instanceID=" + m_instanceID + "): " + cadena +
          "           " + "ThreadID=" + Thread.currentThread().getId() + " ThreadName=" + Thread.currentThread().getName();
    Logger.getLogger(this.getClass().getName()).log(Level.INFO,msg);
}

//Constructor
public FirstWS() {
    Random rnd = new Random();
    m_instanceID = rnd.nextLong();
    WriteLog("Executing Constructor");
}

//PostConstruct
@PostConstruct
public void ThisIsThePostConstruct() {
    WriteLog("Executing PostConstruct");
}

//PreDestroy
@PreDestroy
public void ThisIsThePreDestroy() {
    WriteLog("Executing PreDestroy");
}

//Method
@WebMethod(operationName = "GetInstanceID")
@WebResult(name="InstanceID")
public long GetInstanceID() {
    //TODO write your implementation code here:
    WriteLog("Executing GetInstanceID");
    return m_instanceID;
}

}

I always though that web services were singleton by default.

On the glassfish V2.1 server the ws is working as expected, with a singleton lifecycle:

  • Only one instance is created.
  • Only one execution of constructor method.
  • Only one execution if postconstructor method.
  • Only one execution of predestroy method when ws is undeployed.

Client log

InstanceID = -4747957096764272596

InstanceID = -4747957096764272596

InstanceID = -4747957096764272596

Server log

26/08/2010 13:08:15:146 * first.test.FirstWS (m_instanceID=-4747957096764272596): Executing Constructor ThreadID=68 ThreadName=httpSSLWorkerThread-8080-0

26/08/2010 13:08:15:161 * first.test.FirstWS (m_instanceID=-4747957096764272596): Executing PostConstruct ThreadID=68 ThreadName=httpSSLWorkerThread-8080-0

26/08/2010 13:08:15:364 * first.test.FirstWS (m_instanceID=-4747957096764272596): Executing GetInstanceID ThreadID=69 ThreadName=httpSSLWorkerThread-8080-1

26/08/2010 13:08:15:380 * first.test.FirstWS (m_instanceID=-4747957096764272596): Executing GetInstanceID ThreadID=69 ThreadName=httpSSLWorkerThread-8080-1

26/08/2010 13:08:15:396 * first.test.FirstWS (m_instanceID=-4747957096764272596): Executing GetInstanceID ThreadID=69 ThreadName=httpSSLWorkerThread-8080-1

26/08/2010 13:08:38:849 * first.test.FirstWS (m_instanceID=-4747957096764272596): Executing PreDestroy ThreadID=626 ThreadName=Thread-540

But on the glassfish V3 server the ws isn't working as expected, because a new instance of the ws is created for EVERY call to the GetInstanceID:

  • One instance is created for every call.
  • One execution of constructor method for every call.
  • Two (!?!?!) executions of postconstructor method for every call.
  • The predestroy method isn't called when ws is undeployed.

Client log

InstanceId = 7754248300017958713

InstanceId = -1714184485890589231

InstanceId = -4156829683887899017

Server log

INFO: 26/08/2010 15:16:11:429 * first.test.FirstWS (m_instanceID=7754248300017958713): Executing Constructor ThreadID=103 ThreadName=http-thread-pool-8080-(2)

INFO: 26/08/2010 15:16:11:429 * first.test.FirstWS (m_instanceID=7754248300017958713): Executing PostConstruct ThreadID=103 ThreadName=http-thread-pool-8080-(2)

INFO: 26/08/2010 15:16:11:429 * first.test.FirstWS (m_instanceID=7754248300017958713): Executing PostConstruct ThreadID=103 ThreadName=http-thread-pool-8080-(2)

INFO: 26/08/2010 15:16:12:429 * first.test.FirstWS (m_instanceID=7754248300017958713): Executing GetInstanceID ThreadID=103 ThreadName=http-thread-pool-8080-(2)

INFO: 26/08/2010 15:16:12:460 * first.test.FirstWS (m_instanceID=-1714184485890589231): Executing Constructor ThreadID=102 ThreadName=http-thread-pool-8080-(1)

INFO: 26/08/2010 15:16:13:429 * first.test.FirstWS (m_instanceID=-1714184485890589231): Executing PostConstruct ThreadID=102 ThreadName=http-thread-pool-8080-(1)

INFO: 26/08/2010 15:16:13:429 * first.test.FirstWS (m_instanceID=-1714184485890589231): Executing PostConstruct ThreadID=102 ThreadName=http-thread-pool-8080-(1)

INFO: 26/08/2010 15:16:14:429 * first.test.FirstWS (m_instanceID=-1714184485890589231): Executing GetInstanceID ThreadID=102 ThreadName=http-thread-pool-8080-(1)

INFO: 26/08/2010 15:16:14:445 * first.test.FirstWS (m_instanceID=-4156829683887899017): Executing Constructor ThreadID=103 ThreadName=http-thread-pool-8080-(2)

INFO: 26/08/2010 15:16:15:429 * first.test.FirstWS (m_instanceID=-4156829683887899017): Executing PostConstruct ThreadID=103 ThreadName=http-thread-pool-8080-(2)

INFO: 26/08/2010 15:16:15:429 * first.test.FirstWS (m_instanceID=-4156829683887899017): Executing PostConstruct ThreadID=103 ThreadName=http-thread-pool-8080-(2)

INFO: 26/08/2010 15:16:15:429 * first.test.FirstWS (m_instanceID=-4156829683887899017): Executing GetInstanceID ThreadID=103 ThreadName=http-thread-pool-8080-(2)

INFO: Closing Metro monitoring root: amx:pp=/mon/server-mon[server],type=WSEndpoint,name=/FirstWebApplication-FirstWSService-FirstWSPort

So, why this behaviour on glassfish V3? How could I have a singleton web service on glassfish V3?

A: 

I think this might be a spec issue (Java EE 5 vs. Java EE 6), and you might need to use the @Stateless annotation:

package com.sun.tutorial.javaee.ejb;

import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebService;

    @Stateless
    @WebService
    public class HelloServiceBean {
        private String message = "Hello, ";

        public void HelloServiceBean() {}

        @WebMethod
        public String sayHello(String name) {
            return message + name + ".";
        }
    }

Correction: This works for me in Glassfish V3.

The Alchemist
Thanks to point me in the right direction
A: 

Finally I found the problem: the type of the project. In NetBeans I created the web service in a "Web Aplication" project so it was deployed into a servlet container in Glassfish and @Stateless and @Singleton annotations don't work. You must create the ws in a "EJB Moule" project and it will be deployed into a EJB container so @Stateless and @Singleton annotations work correctly.

As Java EE 6 says "Singleton session beans offer similar functionality to stateless session beans but differ from them in that there is only one singleton session bean per application, as opposed to a pool of stateless session beans, any of which may respond to a client request. Like stateless session beans, singleton session beans can implement web service endpoints."