Apache Wink resource lifecycle - java

I'd like to know what the expected lifecycle behavior is for a class that responds to REST requests.
I have a class that's derived from javax.ws.rs.core.Application that identifies another class for responding to requests.
In that other class, it is annotated with #Path("foo") and methods within this class are annotated with #Path("bar"). When a request is made to foo/bar, I can see that the constructor is executed, then the PostConstruct method is properly called. After the method returns a response to the client, I can see that PreDestroy is called and then the class is squashed. On the next request, the process repeats.
Is this the correct behavior? Or is there a way that this class can remain in memory so that it doesn't need to go through the constructor and PostConstruct each time a request is made? This method relies on JAXB marshalling and various XSL transformations - I would like to cache the compiled XSLT transformation objects as well as the results of some transformations, but if the class is reinstantiated each time it is called, it makes it impossible for local caching.
This is running with Java 7, Wink, and Tomcat 7. Can someone please let me know if this is the expected behavior, or am I missing something that will just keep this class alive?
Thanks.

By JAX-RS specification, the Resources (the classes annotated with #Path) are created per request.
There are several ways to override this behavior.
The simplest way that can be used according to the JAX-RS specification, is to create a resource instance yourself (you are responsible to call the PostConstruct, not sure when and how you call to PostDestroy in this case) and return it using javax.ws.rs.core.Application.getSingletons()
Alternately, you can put #org.apache.wink.common.annotations.Scope(ScopeType.SINGLETON) annotation on your resource.
If you use Spring, Wink has a neat Spring integration module, so the Spring's lifecycle will be used. See http://incubator.apache.org/wink/1.0/html/5.5%20Spring%20Integration.html

Related

Is each Play framework web request handled with a new dependency injected controller instance, but then what about static controller methods?

My questions are about the lifecycle of controllers in the Play framework for Java, if the controllers are stateful instances or stateless with static methods, and how to use dependency injection in the controller code.
Is each web request handled by a new instance of a Play controller class, i.e. can a controller store state in fields such as services injected into the controller constructor?
(where in the documentation is it explained?)
Has the Play framework changed since earlier versions (and if so, at what version?) regarding if controllers are stateful instances or stateless controllers with static methods?
Where can you see code examples about how the framework injects services into a controller instance when stateful controller is used and example of how to inject services into a static controller method?
Regarding the latter, i.e. injection into a static method I suppose that would either have to be a parameter to the method which the frameworks will add, or if not possible you maybe instead will have to use a service locator from within the method e.g. instantiate a Guice module class and then use "injector.getInstance" from within the static controller method.
This subject is touched in the section "Dependency injecting controllers" at the following page:
https://www.playframework.com/documentation/2.4.x/JavaDependencyInjection
However, it does not show with code how to actually inject services into a controller instance (but probably the same way as other "components" i.e. with #Inject annotation) and certainly it does not currently show how to use DI with a static controller method.
I am confused about these things because I have not found documentation being clear about my questions, and I have also read in a Play book (from 2013) that the controller methods should be programmed as stateless and the controller methods should be static.
However, when now using activator for generating a Play application for Java with the latest Play version (2.4.6) I can see that the generated Controller method (Application.index) is NOT static.
Also, at the following documentation page, the controller method is NOT static:
https://www.playframework.com/documentation/2.4.x/JavaActions
This is confusing, and since it is VERY fundamental to understand whether or not each request is handled by a Controller instance or not (i.e. if state can be used) I think this should be better documented at the page about Controller/Actions than the current documentation (the above linked page) which is not explaining it.
The documentation about dependency injection touches the subject about static and non-static methods at the section "Dependency injecting controllers" mentioning "static routes generator" but I think it should be better explained including code examples.
If someone in the Play team is reading this question, then please add some information to the above linked pages, for example please do mention (if my understanding is correct) that in previous versions of Play the controller methods were static and for those versions you should never store state in fields, but in later versions (beginning from version x?) each request is handled by an instance of a controller and can therefore use state (e.g. constructor parameters injected by the framework).
Please also provide code examples about injection used with static controller methods and injection into stateful controller instances with one instance per request.
The section "Component lifecycle" in the dependency injection page only mentions "components" but I think it should also be explicit about the controller lifecycle and its injection, since it is such a fundamental and important knowledge to communicate clearly to all developers to avoid bugs caused by misunderstandings about being stateful or not.
Is each web request handled by a new instance of a Play controller class, i.e. can a controller store state in fields such as services injected into the controller constructor? (where in the documentation is it explained?)
As far as I can tell, controllers are by default singleton objects. This is not clearly documented, but it is implied that controller instances are reused. See the migration guide for Playframework 2.4:
The injected routes generator also supports the # operator on routes, but it has a slightly different meaning (since everything is injected), if you prefix a controller with #, instead of that controller being directly injected, a JSR 330 Provider for that controller will be injected. This can be used, for example, to eliminate circular dependency issues, or if you want a new action instantiated per request.
Also, check this commend made by James Roper (Play core committer) about if controllers are singleton or not:
Not really - if using Guice, each time the controller is injected into something, a new instance will be created by default. That said, the router is a singleton, and so by association, the controllers it invokes are singleton. But if you inject a controller somewhere else, it will be instantiated newly for that component.
This suggests that the default is to reuse controller instances when responding to requests and, if you want a new action per request, you need to use the syntax described in the migration guide. But... since I'm more inclined to prove and try things instead of just believe, I've created a simple controller to check that statement:
package controllers
import play.api._
import play.api.mvc._
class Application extends Controller {
def index = Action {
println(this)
Ok(views.html.index("Your new application is ready."))
}
}
Doing multiple requests to this action prints the same object identity for all the requests made. But, if I use the # operator on my routes, I start to get different identities for each request. So, yes, controllers are (kind of) singletons by default.
Has the Play framework changed since earlier versions (and if so, at what version?) regarding if controllers are stateful instances or stateless controllers with static methods?
By default, Play had always advocated stateless controllers, as you can see at the project homepage:
Play is based on a lightweight, stateless, web-friendly architecture.
That had not changed. So, you should not use controllers' fields/properties to keep data that changes over time/requests. Instead, just use controllers' fields/properties to keep a reference to other components/services that are also stateless.
Where can you see code examples about how the framework injects services into a controller instance when stateful controller is used and example of how to inject services into a static controller method?
Regarding code examples, Lightbend templates repository is the place to go. Here are some examples that use dependency injection at the controllers level:
https://github.com/adrianhurt/play-api-rest-seed
https://github.com/knoldus/playing-reactive-mongo
https://github.com/KyleU/boilerplay
Dependency Injection with static methods is not supported, and that is why Playframework stills offers old apis to use with static methods. The rule of thumb here is: choose between DI and static methods. Trying to use both will just bring complexity to your application.
Ok, thank you marcospereira.
I have now also confirmed that you indeed get different instances (different toString values which can be printed/logged in a controller method) of the controller for each request.
For those who are interested, the solution (to get different instances of controller class for each request) is to use for example the following:
GET / #controllers.Application.index()
instead of the following:
GET / controllers.Application.index()
in the file "conf/routes"
AND to also use the following:
routesGenerator := InjectedRoutesGenerator
instead of the following:
routesGenerator := StaticRoutesGenerator
in the file "build.sbt"
Regarding the statement that Play has a "stateless" architecture:
Maybe I am wrong, but as far as I understand the terminology, the "stateless" means that the web server does not store any state between requests?
The word "stateless" does not mean that a controller instance can not use fields, e.g. injected into the constructor.
If an injected object is stored as a field in a controller, then that field is a "state" of the controller.
Therefore, even if you use "InjectedRoutesGenerator" and the "#" prefix to get "stateful" controller instances, that injected "state" is only stored within one request, so you can still say that the framework itself is "stateless" since the server does not store any state between multiple requests.
Please do correct me if I have misunderstood something about Play being stateless.

Jersey #PathParam at instance level vs at method level

In a Jersey class, Which is more appropriate of the two:
On an instance variable
#PathParam("service-id")
private String serviceId;
On a method argument
public Response subscribe(#PathParam("service-id") String serviceId){}
I'm using first one only because service-id is required by almost all my methods. However, a colleague of mine had a comment over this approach that ultimately Jersey classes are based on servlets and servlets should not have stateful variables.
I read about this in the JSR-311 java docs
Because injection occurs at object creation time, use of this
annotation on resource class fields and bean properties is only
supported for the default per-request resource class lifecycle.
Resource classes using other lifecycles should only use this
annotation on resource method parameters.
Since in a webapp, my Jersey class is going to follow per-request resource class lifecycle, I feel first approach is safe. Thoughts please :)
It is made safe by virtue of only allowing this annotation in request-scope (so that every request gets its own bean/resource instance and there is no shared state).
I'd probably give each method the full set of parameters, though, even if it is a bit repetitive. Makes it easier to see at a glance what is going on. That's a code style issue, though, and people can have different opinions here.
This is only coding styles issues since this code has exactly the same result.
I also prefer to define it in the method, instead of defining it in the instance.
Whatever, once compiled, the result is the same! :)

JAX-RS - Can two classes have the same #Path identifier?

I have a webapp that redirects to a particular URI: let's say /service/library. In another bundle, I have a jaxrs server that listens for /service in the URI, and defines some beans to handle the request. There are quite a few beans there already, and one of the classes is already implemented to handle requests for /service/library. I am trying to create a new class that also handles requests for /service/library, but with a different absolute URI path, for example: /service/library/mynewlibrary. My question is, is it possible to define the same #Path identifier in two classes, or must they be unique, in other words, will I need to use a URI like /service/mylibrary for my new class implementation instead of implementing a second class that also uses the same #Path identifier? I am pretty new to JAX-RS, so I hope my question makes sense!
Thanks!
It's possible to have two #Path annotations that match the URI. In your case, if servlet-mapping is service, you may have #Path("/library") and #Path("library/mynewlibrary").
When request arrives, the matching paths are sorted in descending order, so the second class should be called, when a request with /service/library/mynewlibrary arrives.
It's most certainly possible to have two methods with the same #Path annotation, e.g., if they're distinguished by other means (such as HTTP method or #Consumes annotation). The #Path on a class acts as a default/root for the #Paths on the class's methods. Moreover, it's not a problem at all if you've got one path that is “within” another; JAX-RS specifies that the most specific match possible is used. (I prefer to not do it that way, instead having the “outer” class return a reference to the “inner” class on a suitable partial match, so that every path has a traceable route to responsibility that definitely leads to a single class. That requires a fairly different way of arranging the #Path annotations though.)
But if you've ended up with two methods that can serve the same incoming request, you've got a clash and the JAX-RS implementation will be free to pick which one to use (in an implementation-dependent manner). That's probably not what you want, as computers tend to make bad decisions when given a free choice.
You can achieve your goal to have /service/library/mynewlibrary using below configuration.
In your existing class you have /service/library configured at class level so you can configure /service at class level in new class you are adding and then at method level configure /library/mynewlibrary.
This way it will not have same path for both classes and your goal is also achieved. I tried this and it works.

#Asynchronous private method in EJB

I have an asynchronous method in my EJB singleton that's called from another method in the same class. I already know that I can't call the asynchronous method directly, I have to obtain an EJB proxy. The problem is, I don't want the asynchronous method to be visible outside the class; but when I make it private, it's not executed asynchronously. (I'm using Glassfish v3.)
The javadocs don't say anything about the required access level. So should this be considered a bug in Glassfish?
method annotation cannot be used in private methods. When Glassfish is compiling your EJB it will basically convert your annotation into a piece of code that will surround your code in a proxy. If your method is private it will bypass the proxy Glassfish created... So, in your case I suggest to create a new EJB with your asynchronous method in inject it in your current EJB
That's a very interesting bit of feedback. I can see the value in what you are trying to do. Try marking your bean as an #LocalBean and annotating your #Asynchronous method as protected.
As #LocalBean support is basically done via subclassing the bean class (dynamically or statically), it isn't really possible for the container to override the private method. But I can certainly see your use case. If the protected method approach doesn't work, we can probably add this as an enhancement to EJB.next.
Would still give access to other beans in the same package, but it's at least less public. I've often wished Java had an 'only subclasses' scope. I've almost never used protected and thought, "great, now everyone in my package can access this too."

Are all methods proxied when using Spring AOP?

When using Spring AOP to create a proxy for a class using NameMatchMethodPointcutAdvisor and BeanNameAutoProxyCreator does this essentially proxy every call to the object, but only apply the advice to the matched methods, or somehow create a Proxied object that only has those methods and uses the normal object for the calls that are supposed to be intercepted?
The way, I think I understand it is that it does proxy every call to the object but then only calls the Advisor on the methods that match - but I can't find a good example/post to confirm this.
Depends on the technique used. (It is configurable by an attribute proxy-target-class in your aop config)
JDK dynamic proxies are proxies by interface - each methods of the interface goes through the proxy, as you said, and if it matches happens to be an "advised" method, the advisor is applied. Otherwise it is delegated to the original object
CGLIB proxies are effectively subclasses defined at runtime of your concrete classes. I can't be sure in this, but I assume only the "advised" methods are overridden, the rest retain the definition of the superclass.
However, no matter which mechanism is used:
it isn't your concern how exactly are the proxies implemented
this doesn't impact performance in a significant way - Debunking myths: proxies impact performance by the Spring team about proxy performance myths
or somehow create a Proxied object that only has those methods and uses the normal object for the calls that are supposed to be intercepted?
How would this actually work? When a class has a reference to the class that is being proxied, it only has one reference to it. It either has to invoke a proxy class or a non-proxied class. Spring can't know which methods you are calling and therefore can't give you one type if you need to call the advised method and another type if you're not.

Categories

Resources