EJB: what's the point of class-level annotations? - annotations

I'm reading this book, Pro JPA2: Mastering the Java Persistance API, and I'm not getting the usefulness of the class-level annotation like in this example:
#EJB(name="cart", beanInterface=ShoppingCart.class)
public class ShoppingCartServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = request.getSession(true);
ShoppingCart cart = (ShoppingCart) session.getAttribute("cart");
//......
}
}
What's the point of putting that #EJB if the value of the cart variable won't be auto-injected in there and you have to init the var. yourself? Won't the code work just as well w/o that annotation? What does the annotation actually do?
I get the usefulness of the other type of annotations, like when you put it on the method or a variable, it'll auto-inject stuff. Just here, at the class level, it looks useless.

class level #EJB (or #Resource) defines that your ShoppingCartServlet depends on some EJB, in your case "cart". You need that, if you want to access to EJBs from non-managed context, like POJOs. In this case, you have to make a JNDI look-up in order to get a reference to the EJB which you can define either with ejb-ref (ejb-local-ref) descriptor, or class level #EJB annotation.

That looks like a class level annotation rather than method level, and I have no idea why one would want to annotate a servlet as EJB, but the #EJB annotation when used properly will provide that class with many different things for free, such as transactions etc...

Related

How would you setup an JSF entity, service and backing bean [duplicate]

I'm trying to get used to how JSF works with regards to accessing data (coming from a spring background)
I'm creating a simple example that maintains a list of users, I have something like
<h:dataTable value="#{userListController.userList}" var="u">
<h:column>#{u.userId}</h:column>
<h:column>#{u.userName}</h:column>
</h:dataTable>
Then the "controller" has something like
#Named(value = "userListController")
#SessionScoped
public class UserListController {
#EJB
private UserListService userListService;
private List<User> userList;
public List<User> getUserList() {
userList = userListService.getUsers();
return userList;
}
}
And the "service" (although it seems more like a DAO) has
public class UserListService {
#PersistenceContext
private EntityManager em;
public List<User> getUsers() {
Query query = em.createQuery("SELECT u from User as u");
return query.getResultList();
}
}
Is this the correct way of doing things? Is my terminology right? The "service" feels more like a DAO? And the controller feels like it's doing some of the job of the service.
Is this the correct way of doing things?
Apart from performing business logic the inefficient way in a managed bean getter method, and using a too broad managed bean scope, it looks okay. If you move the service call from the getter method to a #PostConstruct method and use either #RequestScoped or #ViewScoped instead of #SessionScoped, it will look better.
See also:
Why JSF calls getters multiple times
How to choose the right bean scope?
Is my terminology right?
It's okay. As long as you're consistent with it and the code is readable in a sensible way. Only your way of naming classes and variables is somewhat awkward (illogical and/or duplication). For instance, I personally would use users instead of userList, and use var="user" instead of var="u", and use id and name instead of userId and userName. Also, a "UserListService" sounds like it can only deal with lists of users instead of users in general. I'd rather use "UserService" so you can also use it for creating, updating and deleting users.
See also:
JSF managed bean naming conventions
The "service" feels more like a DAO?
It isn't exactly a DAO. Basically, JPA is the real DAO here. Previously, when JPA didn't exist, everyone homegrew DAO interfaces so that the service methods can keep using them even when the underlying implementation ("plain old" JDBC, or "good old" Hibernate, etc) changes. The real task of a service method is transparently managing transactions. This isn't the responsibility of the DAO.
See also:
I found JPA, or alike, don't encourage DAO pattern
DAO and JDBC relation?
When is it necessary or convenient to use Spring or EJB3 or all of them together?
And the controller feels like it's doing some of the job of the service.
I can imagine that it does that in this relatively simple setup. However, the controller is in fact part of the frontend not the backend. The service is part of the backend which should be designed in such way that it's reusable across all different frontends, such as JSF, JAX-RS, "plain" JSP+Servlet, even Swing, etc. Moreover, the frontend-specific controller (also called "backing bean" or "presenter") allows you to deal in a frontend-specific way with success and/or exceptional outcomes, such as in JSF's case displaying a faces message in case of an exception thrown from a service.
See also:
JSF Service Layer
What components are MVC in JSF MVC framework?
All in all, the correct approach would be like below:
<h:dataTable value="#{userBacking.users}" var="user">
<h:column>#{user.id}</h:column>
<h:column>#{user.name}</h:column>
</h:dataTable>
#Named
#RequestScoped // Use #ViewScoped once you bring in ajax (e.g. CRUD)
public class UserBacking {
private List<User> users;
#EJB
private UserService userService;
#PostConstruct
public void init() {
users = userService.listAll();
}
public List<User> getUsers() {
return users;
}
}
#Stateless
public class UserService {
#PersistenceContext
private EntityManager em;
public List<User> listAll() {
return em.createQuery("SELECT u FROM User u", User.class).getResultList();
}
}
You can find here a real world kickoff project here utilizing the canonical Java EE / JSF / CDI / EJB / JPA practices: Java EE kickoff app.
See also:
Creating master-detail pages for entities, how to link them and which bean scope to choose
Passing a JSF2 managed pojo bean into EJB or putting what is required into a transfer object
Filter do not initialize EntityManager
javax.persistence.TransactionRequiredException in small facelet application
It is a DAO, well actually a repository but don't worry about that difference too much, as it is accessing the database using the persistence context.
You should create a Service class, that wraps that method and is where the transactions are invoked.
Sometimes the service classes feel unnecessary, but when you have a service method that calls many DAO methods, their use is more warranted.
I normally end up just creating the service, even if it does feel unnecessary, to ensure the patterns stay the same and the DAO is never injected directly.
This adds an extra layer of abstraction making future refactoring more flexible.

In Jersey 2.X, a Feature is instantiated by HK2. How can I use Factories I've also added?

In the strange, strange dependency injection world of Jersey, you can include an AbstractBinder (but maybe not just a Binder) as one of the objects in the return value of your Application's getSingletons() method.
That AbstractBinder can then call various bind() methods from within its configure() method, which Jersey, but no other JAX-RS implementation, is guaranteed to call—and hence you can link implementations to interfaces, which lets you do a semblance of dependency injection from that point forward in your application. That is, once you've done that, then injection points within, say, your resource classes will be "filled" by the implementations you've bound.
(You can also do this with factory classes, so that you bind a particular factory method's return value to a contract it implements.)
OK, fine.
Jersey also lets you place a Class that implements Feature into the return value of your Application's getClasses() method. Fine. This Feature class will be instantiated by HK2 under the covers—make a mental note of that!—and its configure(FeatureContext) method will be called at some point. At that point, the Feature may register some additional stuff by calling FeatureContext#register() and handing it whatever it wants to register.
(Presumably this is all a fairly complicated façade on top of HK2's DynamicConfiguration machinery.)
Anyway, since a Feature is instantiated by HK2 (remember?), it follows that you can #Inject things into its constructor, or have injection points elsewhere in the class. That's cool! Then HK2 can draw upon all the services it knows of to fill those injection points. Very neat.
Ah, but the question is: what is the state of the HK2 world at this point? What services can be injected into a Feature implementation instantiated as part of A JAX-RS Application's startup sequence?
If your Application's getSingletons() method returns an AbstractBinder implementation that binds a FooImpl to Foo in Singleton scope in its configure() method, can your Feature—"registered" by including its class in the return value of your Application's getClasses() method—then inject a Foo?
I think it is important to have your Foo interface binding proxied, i.e:
new AbstractBinder() {
#Override
protected void configure() {
bind(Foo.class)
.proxy(true)
.to(FooImpl.class)
.in(Singleton.class);
}
}
then dependency injection will be insensitive to the instatination order.

Jersey 2: filters and #Context injections

I've the following question:
ContainerRequestFilter is a singleton, but reading this:
Jaxrs-2_0 Oracle Spec
in chapter 9.2, they say:
Context is specific to a particular request but instances of certain JAX-RS components (providers and resource classes with a lifecycle other than per-request) may need to support multiple concurrent requests. When injecting an instance of one of the types listed in Section 9.2, the instance supplied MUST be capable of selecting the correct context for a particular request. Use of a thread-local proxy is a common way to achieve this.
In the chapter 9.2, the HttpServletRequest is not mentioned.
So the question is: is it safe in terms of concurrency to inject the HttpServletRequest inside a custom ContainRequestFilter?
I mean this:
#Provider
#PreMatching
public class AuthenticationFilter implements ContainerRequestFilter {
#Context private HttpServletRequest request;
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
// This is safe because every thread call the method with its requestContext
String path = requestContext.getUriInfo().getPath(true);
// Is this safe? The property request is injected by using #Context annotation (see above)
String toReturn = (String)request.getAttribute(name);
[...]
}
I did some empirical tests on my IDE in debug mode, sending with two different browsers two different and concurrent requests and it seems to work well; I noticed that the filter's instance is ever the same (it's a singleton), but the injected HttpServletRequest is different in the two cases.
I readed even this thread: How to access wicket session from Jersey-2 request filter? and it seems that my tests are confirmed.
But I still have doubts.
Confirm?
Yes it's safe. To understand the problem, you should understand how scopes work. In any framework that deals with scopes (and injection), the feature is implemented similarly. If an object is in a singleton scope and another object in a lesser scope needs to be injected, usually a proxy of the object will be injected instead. When a call is made on the object, it's actually a call on the proxy.
Though the spec may not mention the HttpServletRequest specifically, most JAX-RS implementation have support for this. With Jersey in particular, if this was not possible (meaning the object is not proxiable), then you would get an error message on startup with something like "not within a request scope". The reason is that the ContainerRequestFilter is created on app startup, and all the injections are handled at that time also. If the HttpServletRequest was not proxiable, it would fail to inject because on startup, there is no request scope context.
To confirm that it is not the actual HttpServletRequest and is a proxy, you can log the request.getClass(), and you will see that it is indeed a proxy.
If you are unfamiliar with this pattern, you can see this answer for an idea of how it works.
See Also:
Injecting Request Scoped Objects into Singleton Scoped Object with HK2 and Jersey

Using an interceptor with Tapestry Resteasy

I have a resource class and I'd like to be able to check an authentication token before the resource method is called, thus avoiding having to pass the token directly into the Resource method.
I have added the following to web.xml:
<context-param>
<param-name>resteasy.providers</param-name>
<param-value>com.michael.services.interceptors.AuthorisationInterceptorImpl</param-value>
</context-param>
My interceptor is implemented as follows:
#Provider
public class AuthorisationInterceptorImpl implements javax.ws.rs.container.ContainerRequestFilter {
#Inject
private ApiAuthenticationService apiAuthenticationService
#Override
public void filter(ContainerRequestContext requestContext) {
//Code to verify token
}
}
The filter method is being called before the methods in my resource class; however, the apiAuthenticationService is not being injected and is null when I attempt to call its methods.
I'm using Tapestry 5.3.7, Tapestry-Resteasy 0.3.2 and Resteasy 2.3.4.Final.
Can this be done ?
I don't think this will work, based on a quick glance at the tapestry-resteasy code.
The #Inject annotation is part of tapestry-ioc; if a class is not instantiated by Tapestry, the #Inject annotation is not honored.
Filters defined in web.xml are instantiated by the servlet container (Jetty, Tomcat, etc.) which do not have any special knowledge of Tapestry and Tapestry annotations.
I think you will be better off contributing a filter into Tapestry's HttpServletRequestHandler or RequestHandler pipelines (see their JavaDoc). I'm not sure how you can gain access to the ContainerRequestContext, however.
With tapestry-resteasy you don't need to define the provider in the web.xml file.
If you want to use Tapestry's autobuild mechanism just move your provider to the .rest package together with your resources.
If don't want to use autodiscovery/autobuild just contribute it to javax.ws.rs.core.Application
#Contribute(javax.ws.rs.core.Application.class)
public static void configureRestProviders(Configuration<Object> singletons, AuthorisationInterceptor authorisationInterceptor)
{
singletons.add(authorisationInterceptor);
}
Even though you can use rest providers for security is probably a good idea to take Howard's advice and implement your own filter in the tapestry pipeline.
BTW, you can also give tapestry-security a try :)

GIN #Inject on variable for Rpc Services

I'm a bit lost with the use of Inject on variable.
I got this code working :
private XXServiceAsync xxServiceAsync;
#Inject
protected IndexViewImpl(EventBus eventBus, XXServiceAsync tableManagementServiceAsync) {
super(eventBus, mapper);
this.xxServiceAsync = xxServiceAsync;
initializeWidgets();
}
With this code, I can call my RPC service wherever I need in the class (On click ...)
I would like to clear a bit the code by injecting direcly in the variable ; doing so :
#Inject
private XXServiceAsync xxServiceAsync;
protected IndexViewImpl(EventBus eventBus) {
super(eventBus, mapper);
initializeWidgets();
}
This always keep the Service to NULL.
Am I doing something wrong ? Is the GIN magic with rpc services meant to be done otherwise?
Thanks!
It is still null at that point, because Gin (and Guice, and other frameworks like this) cannot assign the fields until the constructor has finished running.
Consider how this would look if you were manually wiring the code (remember that Gin/Guice will cheat a little to assign private fields, call non-visible methods):
MyObject obj = new MyObject();//initializeWidgets() runs, too early!
obj.xxServiceAsync = GWT.create(xxService.class);
If you need something in the constructor, pass it into the constructor. If you wont need it right away (such as until asWidget() is called), then a field or setter annotated with #Inject can be helpful.
If you have field level injection you can use an empty #Inject method to do your post-inject initialization. The no-arg injected method will be run after field injections on the class are complete.
#Inject void initialize(){
...
initializeWidgets()
}
Edit: I previously stated that it was run after method injection as well, but testing shows that this is not always the case.