When to use #Singleton annotation of Jersey? - java

I am developing a RESTful Web Service and while reading the Jersey documentation I came across an annotation #Singleton
In my web service I am mostly returning data based on the unique keys provided as parameter.
An analogy would be return all the information of a Student when the Student_Id is passed.
So my question is when #Singleton would be suited in such kind of Web Services?
As per documentation for #RequestScoped
If the resource is used more than one time in the request processing, always the same instance will be used.
Then in that case we should not bother to use #Singleton right?
Also what could be the use cases where we have to make a new instance for every request?
I did have a look at this post but my question was not answered.

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.
Most cases you use this default setting so you don't use #Singleton scope. You can also create a singleton Jersey resource class by using #Singleton annotation. Then you need to register the singleton class in the MyApplication class, e.g.,
#Path("/resource")
#Singleton
public class JerseySingletonClass {
//methods ...
}
public class MyApplication extends ResourceConfig {
/*Register JAX-RS application components.*/
public MyApplication () {
register(JerseySingletonClass.class);
}
}

Came along this question, because for the first time I had a use case for not using #Singleton annotation.
Singleton is a design pattern, you should use it if:
The object you are "singletonizing" keeps a state that must be shared and kept unique (example: a global counter)
Generally, I design REST API without keeping a state, everything is handled in the method (full closure): so generally all my resources are singletons (use case: better performance)
That said, today I found this use case for not using Singleton:
#Path("/someendpoint/{pathparam}/somethingelse/")
//#Singleton
public class MyResource {
#PathParam("pathparam")
private String pathparam;
}
Using this, I'm bounding the path param to my instance, so it must be RequestScoped.
Generally, I'd have put #PathParam annotation in every method, so #Singleton would have been right on the class.
I'm not sure about the performances however, creating and destroying an object isn't a free operation

In most cases default scope #RequestScoped should be sufficient for your needs.
#Singleton may hold state. I had the problem when my endpoint was annotated as #Singleton so it reused the same EntityManager during concurrent calls. After removing #Singleton, during concurrent calls, different EntityManager object instances are used. If endpoint calls are subsequent, it may be that previous/old EntityManager will be used. - Jersey, Guice and Hibernate - EntityManager thread safety

There is actually a use case specified in the Jersey 2 manual for using the SseBroadcaster when serving Server-Sent events, it is covered in this provided example
The BroadcasterResource resource class is annotated with #Singleton annotation which tells Jersey runtime that only a single instance of the resource class should be used to serve all the incoming requests to /broadcast path. This is needed as we want to keep an application-wide single reference to the private broadcaster field so that we can use the same instance for all requests. Clients that want to listen to SSE events first send a GET request to the BroadcasterResource, that is handled by the listenToBroadcast() resource method.
Using the #Singleton, The application will only contain one SseBroadcaster for all incoming requests, one such broadcaster is enough to serve multiple clients, so it only needs to be instantiated once!
JAX-RS SSE API defines SseBroadcaster which allows to broadcast individual events to multiple clients.

Related

How #ControlAdvice captures exceptions?

I'm on learning phase of Spring boot
I've code where its written like below to handle exception in whole application. Not sure how its working, but I have NoDataFoundException class in code and its being used at place where no data found issues are happening.
#ControlAdvice
class ControllerAdvisor {
#ResponseStatus(HttpStatus.BAD_REQUEST)
#ExceptionHandler(NoDataFoundException.class)
#ResponseBody
public ResponseEntity<Object> handleNodataFoundException(
NoDataFoundException ex, WebRequest request) {
Map<String, Object> body = new LinkedHashMap<>();
body.put("timestamp", LocalDateTime.now());
body.put("message", "No cities found");
return new ResponseEntity<>(body, HttpStatus.NOT_FOUND);
}
Want to know, how and when handleNodataFoundException method automatically gets called when NoDataFoundException instance gets created ?
Does spring calls this method handleNodataFoundException on the basis of #ExceptionHandler(NoDataFoundException.class) which is bind to method itself and moreover irrespective of name of the method ?
how spring looks for parameters required for above method ? what if it has more parameters in it ?
This is done by proxying (Proxy.class).
Proxying is a mechanism in which a kind of pseudo class is created dynamically and mimics your own class (same methods) and is used to intercept all the method calls. This way it can act before and after the method calls as it please, and in the middle call the real method that you developed.
When you create a #Service in Spring, or a #Stateless in EJB, you never actually create the instances, you delegate the instance creation on the framework (Spring or EJB). Those frameworks proxy your classes and intercept every call.
In your case, and putting it simple, the proxy has a catch around the real call to your method, that catch captures exceptions, and acts upon the framework configuration built based on all the annotations that you created (#ControlAdvice, #ExceptionHandler and so on). And so it can call the handleNodataFoundException(...) in the cases that you defined with annotations.
Update visualization via stacktrace
For instance, if you have two Spring #Component (or #Service, #Repository or whatever), and one calls the other one in a plain call, and you get an exception, in the stacktrace you see plenty of method calls (involving all kind of different classes) between your two component classes, all those are proxies and framework classes that take care of proxying, invoking, configuration and all the magic that the framework does. And everything is triggered by the proxy of your second component just before calling the real code that you developed, because the first component, at execution time, doesn't really call an instance of your class, but an instance of the proxy of your class that the framework created.
If you run a plain main, with two classes calling one to the other, instantiated by you with new, you will only see 3 lines in the stacktrace, because there the instances are plain instances created by you.

JavaEE Web JAX-RS: can i use instance variables inside it's class?

I'm looking for thread-safe Servlet alternative and I've found JAX-RS technology.
So can i use instance variables inside it's class like this (is it thread safe):
#Path("helloworld")
public class HelloWorldResource {
private String msg;
#GET
public void doSmth() {
this.msg = "test";
}
}
?
Resource scope will default to #RequestScope so a new instance of your resource will be created per request.
From Chapter 3. JAX-RS Application, Resources and Sub-Resources
#RequestScoped
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.
So as long as msg is not static it should be created per request.
This also means that after the request is handled you are going to lose any state contained in the resource, what use case are you trying to solve here?

How do you configure a JAX-RS MessageBodyWriter on a per-request basis?

Essentially, I have a MessageBodyWriter that writes objects as JSON, and I'd like to be able to control some aspects of the output based on which resource method handled the request. However, the default lifecycle of #Provider classes is singleton (one per JVM), so I can't inject an instance of some configuration object. This leaves me with 2 obvious workarounds:
Use custom annotations: Each call to writeTo(...) includes the list of annotations on the method that was invoked, so I could check for the existence of some annotation. However, JAX-RS methods are already pretty laden with metaprogramming.
Use a ThreadLocal property map: Assuming one request per thread, but this approach breaks encapsulation a bit. The resource methods needs to be aware that there is some other class out there, looking for this map.
Is there a way to change the lifecycle of the Provider itself? I am using Jersey.
Not sure why you need a MessageBodyWriter Provider with per-request basis. If you just want to distinguish which methods are with JSON ouput and which are not, then jersey-json does already support.
And although the #Provider is singleton. You still can use per-request object within it like below.
#Provider
public class StViewProcessor implements ViewProcessor<ST> {
......
#Context
HttpServletRequest request;
public void writeTo(ST st, Viewable viewable, OutputStream out)
throws IOException {
System.out.println(request.getRequestURI());
...
}
}
And if you want to inject your instance per request, you can have a look at PerRequestTypeInjectableProvider. Here is a link about it.
The JAX-RS 1.1 spec requires that implementations support singleton providers and allows support for other lifecycles but doesn't suggest anything else along those lines. As far as I'm aware, pure Jersey doesn't support anything beyond singletons. With the jersey-spring contrib module, you get support for using Spring as Jersey's IoC container (where it gets its resource and provider instances from). I know Spring supports multiple lifecycles, including request, but I'm not sure if support for that is built into jersey-spring.

Jersey REST Server: instantiating resource classes

A tutorial on the Jersey REST server [1] says of the Jersey servlet:
This servlet analyzes the incoming HTTP request and selects the correct class and method to respond to this request. This selection is based on annotations in the class and methods.
When the servlet "selects the correct class and method", does it re-instantiate the class every time? Or does it keep one instance of every resource class?
This would seem to matter because, if these resources classes have references to objects that store application-wide state, these state objects would be re-instantiated along with the resources, and would not end up storing state data correctly.
[1] http://www.vogella.com/articles/REST/article.html#restjersey
Jersey will establish a new instance of each class per request unless you annotate the class with #Singleton.
See: https://jersey.java.net/documentation/latest/jaxrs-resources.html#d0e2331
Actually according to this post default annotation type is change from singleton to per-request. Which means before one instance is used for every request but now create new class object for per-request. If you postwant to change it you can use resourceFactory annotation.
#Target({ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Documented
#ResourceFactory(SingletonProvider.class)
public #interface Singleton {}
Also you can check this link for com.sun.jersey.spi.resource JavaDoc

Using EJBContext getContextData - is this safe?

I am planning to use EJBContext to pass some properties around from the application tier (specifically, a message-driven bean) to a persistence lifecycle callback that cannot directly be injected or passed parameters (session listener in EclipseLink, entity lifecycle callback, etc.), and that callback is getting the EJBContext via JNDI.
This appears to work but are there any hidden gotchas, like thread safety or object lifespan that I'm missing? (Assume the property value being passed is immutable like String or Long.)
Sample bean code
#MessageDriven
public class MDB implements MessageListener {
private #Resource MessageDrivenContext context;
public void onMessage(Message m) {
context.getContextData().put("property", "value");
}
}
Then the callback that consumes the EJBContext
public void callback() {
InitialContext ic = new InitialContext();
EJBContext context = (EJBContext) ic.lookup("java:comp/EJBContext");
String value = (String) context.getContextData().get("property");
}
What I'm wondering is, can I be sure that the contextData map contents are only visible to the current invocation/thread? In other words, if two threads are running the callback method concurrently, and both look up an EJBContext from JNDI, they're actually getting different contextData map contents?
And, how does that actually work - is the EJBContext returned from the JNDI lookup really a wrapper object around a ThreadLocal-like structure ultimately?
I think in general the contract of the method is to enable the communication between interceptors + webservice contexts and beans. So the context should be available to all code, as long as no new invocation context is created. As such it should be absolutely thread-safe.
Section 12.6 of the EJB 3.1 spec says the following:
The InvocationContext object provides metadata that enables
interceptor methods to control the behavior of the invocation chain.
The contextual data is not sharable across separate business method
invocations or lifecycle callback events. If interceptors are invoked
as a result of the invocation on a web service endpoint, the map
returned by getContextData will be the JAX-WS MessageContext
Furthermore, the getContextData method is described in 4.3.3:
The getContextData method enables a business method, lifecycle callback method, or timeout method to retrieve any interceptor/webservices context associated with its invocation.
In terms of actual implementation, JBoss AS does the following:
public Map<String, Object> getContextData() {
return CurrentInvocationContext.get().getContextData();
}
Where the CurrentInvocationContext uses a stack based on a thread-local linked list to pop and push the current invocation context.
See org.jboss.ejb3.context.CurrentInvocationContext. The invocation context just lazily creates a simple HashMap, as is done in org.jboss.ejb3.interceptor.InvocationContextImpl
Glassfish does something similar. It also gets an invocation, and does this from an invocation manager, which also uses a stack based on a thread-local array list to pop and push these invocation contexts again.
The JavaDoc for the GlassFish implementation is especially interesting here:
This TLS variable stores an ArrayList. The ArrayList contains
ComponentInvocation objects which represent the stack of invocations
on this thread. Accesses to the ArrayList dont need to be synchronized
because each thread has its own ArrayList.
Just as in JBoss AS, GlassFish too lazily creates a simple HashMap, in this case in com.sun.ejb.EjbInvocation. Interesting in the GlassFish case is that the webservice connection is easier to spot in the source.
I can't help you directly with your questions regarding EJBContext, since the getContextData method was added in JEE6 there is still not much documentation about it.
There is however another way to pass contextual data between EJBs, interceptors and lifecycle callbacks using the TransactionSynchronizationRegistry. The concept and sample code can be found in this blog post by Adam Bien.
javax.transaction.TransactionSynchronizationRegistry holds a Map-like structure and can be used to pass state inside a transaction. It works perfectly since the old J2EE 1.4 days and is thread-independent.
Because an Interceptor is executed in the same transaction as the ServiceFacade, the state can be even set in a #AroundInvoke method. The TransactionSynchronizationRegistry (TSR) can be directly injected into an Interceptor.
The example there uses #Resource injection to obtain the TransactionSynchronizationRegistry, but it can also be looked up from the InitialContext like this:
public static TransactionSynchronizationRegistry lookupTransactionSynchronizationRegistry() throws NamingException {
InitialContext ic = new InitialContext();
return (TransactionSynchronizationRegistry)ic.lookup("java:comp/TransactionSynchronizationRegistry");
}

Categories