0

I implemented something like this:

@Path("/svc")
public class Service {

    Resource rsc = Resource.getInstance();

    @GET
    public String doGet() {...}
}

public class Resource {

    public static Resource instance;

    private Resource() {...}

    public static getInstance(){
        if (instance == null){
            return new Resource();
        }
        return instance;
    }
}

Service class is the where the GET and POST methods are implemented, where Resource is the singleton class where some data is temporarily stored.

However, as I tested it, I found that the singleton class gets a new instance every time a method is called. The singleton class is just a classic Java singleton implementation. I know that adding the @Singleton annotation fixes the problem, but I was wondering what caused this behavior?

cassiomolin
  • 124,154
  • 35
  • 280
  • 359
Rui Chen
  • 61
  • 1
  • 7

3 Answers3

2

Short answer

Your singleton is not a singleton.

Long answer and how to fix it

The instance field is public and you are always returning a new Resource instance instead of assigning it to the instance field.

It's also recommended marking your class as final and using a synchronization in your getInstance() method:

public final class Resource {

    private static Resource instance;

    private Resource() {

    }

    public static synchronized Resource getInstance() {
        if (instance == null) {
            instance = new Resource();
        }
        return instance;
    }
}

However, it's not the best way to implement a singleton.

For more information, refer to What is an efficient way to implement a singleton pattern in Java?

Community
  • 1
  • 1
cassiomolin
  • 124,154
  • 35
  • 280
  • 359
  • 1
    Thank you, realized that this morning... quite a silly mistake. And thanks for the additional resource. – Rui Chen Nov 20 '15 at 18:04
1

you have not assigning value to instance variable.

public class Resource{
      private static Resource instance;

      private Resource(){...}

      public static getInstance(){
        if(instance == null){
    instance = new Resource();

        }
        return instance;
      }    
}

So, when you tries to getInstance() of Resource file. It is always null, which results in creating new object for class

Rohit Batta
  • 482
  • 4
  • 16
  • should also make `instance` private. And think about multi-threaded access. – Thilo Nov 20 '15 at 04:59
  • yes, you have to make it `private`. I have just added the instance value to solve problem mentioned in question. Inputs taken, thanks @Thilo – Rohit Batta Nov 20 '15 at 05:02
1

A JAX-WS web service is by itself a Singleton. This means that all the request will be handled using a single web service instance (like a Servlet). Refer to this link a detail answer is already here Singleton Object in Java Web service

By default Jersey creates a new instance of the resource class for every request. So if you don't annotate the Jersey resource class, it implicitly uses @RequestScoped scope. It is stated in Jersey documentation:

Default lifecycle (applied when no annotation is present). In this scope the resource instance is created for each new request and used for processing of this request. If the resource is used more than one time in the request processing, always the same instance will be used. This can happen when a resource is a sub resource is returned more times during the matching. In this situation only on instance will server the requests.

Community
  • 1
  • 1
Haseeb Anser
  • 494
  • 1
  • 5
  • 19
  • I don't think that is true, unless you also annotate with `@Singleton`. See the discussion in the comments on the answer you linked to. – Thilo Nov 20 '15 at 05:05