I'm trying to add rest services to a struts application using jersey.For this i need to segregate the java code in such a way that it can be commonly accessed by both the struts and rest api.This is done so that the code is shared between both rest and struts,and any change will reflect in both the services.I would like to know , how much of this idea is feasible and weather this is how usually people design rest services .
While our presentation layer isn't Struts based (usually it's either Spring Web MVC or JSF), we use Spring 3.0 + Java EE 6, specifically, EJB 3.0 and JPA 2.0 for such situations.
EJB 3.0 stateless session beans work great—they can have declarative (annotation-based) dependency injection and transaction demarcation, or they can manage their transactions, dependencies and resources themselves using whatever traditional mechanism. They seamless integrate with JPA 2.0 and are easy enough to unit test. The main advantage over pure Spring beans is that they can be deployed independently of the Web application (as an EJB JAR).
On the front-facing Web services, we also use Jersey/JAX-RS. Because Jersey/JAX-RS dependency injection is broken (it doesn't use Weld/CDI like the rest of Java EE), we've had to resort to Spring DI to 'wire' up the front-facing REST resource classes with the 'back-end' EJBs. The good thing is this works well enough to inject the EJBs into our MVC controllers and can also be used with JSF managed beans. Alternatively, you can write your REST-ful resources using Spring alone (either way has its own pros/cons, but in general both do the job well).
I know I glossed over the whole thing but I'd be glad to share more details upon request.
EDIT: Some more details, as per request.
You're first stop for learning Jersey/JAX-RS would have to be the Jersey User Guide. There are also several tutorials/examples you can easily find across the 'Net.
While you should be able to package Jersey/JAX-RS resources into the same WAR as your Struts pages, we went with the simpler alternative of deploying them separately.
Now, when deploying to Glassfish 3.1, we hit this bug, also documented here. The bottom line is that #EJB injection didn't work for us as expected.
So, instead, we fell back on to Spring using the jersey-spring contrib module, following this example.
Anyway, the rest of it is standard Java EE 6 / EJB 3.0. We identify and place all common functionality into a 'service' layer which are largely implemented as #Stateless EJBs.
Persistence is handled through JPA #Entitys accessed through a JPA inject EntityManager. Transactions are declaratively demarcated using #TransactionAttribute.
Here's a quick illustration of a typical EJB + JPA service bean:
#Stateless
public class WidgetServiceBean implements WidgetService {
#PersistenceContext
private EntityManager em;
#Override
public List<Widget> findWidgetByName(String name) {
return em.createNamedQuery("Widget.findByName", Widget.class)
.setParam("name", name).getResultList();
}
#Override
#TransactionAttribute(TransactionAttributeType.REQUIRED)
public void removeWidgetById(int id) {
em.find(Widget.class, id).remove();
}
}
(Obviously not production quality but just shows how 'lean' they can be.)
The service layer and entities are packaged as an EJB JAR which can be deployed separately, and made available to all other modules via global JNDI lookup. Or, they can be deployed within the Struts or JAX-RS WAR and as of Java EE 6 (Glassfish 3.x) they will be found, deployed as part of the module and made available to other components within the same WAR.
Some might argue that it's simpler to just use Spring beans if you're using the Spring container anyway. I would say, probably, but then you also have to use Spring's persistence framework, and Spring's transaction framework. (Spring also provides declarative transactions and persistence.) If you're already heavily invested into Spring then that might be an easier path.
OTOH, EJB 3.0, JPA 2.0 and JTA have also been radically simplified from their predecessors and are part of the Java EE standard so it's an architectural decision with a lot of dimensions.
Related
I am trying to narrow down the major changes in in EJB 3 and EJB 2, and noted the following changes
EJB 3.X does not required a deployment descriptor; does this mean we can not have a deployment descriptor ?
Also the home and the remote interfaces ? does this mean we can not implement any the aforementioned interfaces in EJB 3.x. Can someone explain what are the main use of Home and the remote interfaces in EJB 2.x
EJB 2.x does not use or implement POJOs , can some one explain the exact use of POJOs in EJB 3.x, with a minor example
I have covered EJB 3, yet I do not have any knowledge in EJB 2.x
Regards
Rashendra
ad 1/ One can certainly have explicit XML-based deployment descriptor with EJB 3.0. However, as compared with 2.x, it is not anymore obligatory to have one. One uses explicit XML deployment descriptor when some of the settings specified on Java class itselfs needs to be augmented.
ad 2/ There is an remote/local bean interface with EJB 3.0, obligatory with remote beans and optional with local beans. There is no home interface in 3.x anymore, which was used to manage the live cycle of entity beans (read:data) and session beans in 2.x. As the entity beans have been replaced by JPA and the life cycle management of session beans has been removed from the client code written by application developer, there is no need for home interface anymore.
ad 3/ Have a look at Java EE tutorial, it covers this well and there are certainly examples.
I have already implemented the MVC pattern using the Spring framework.
In Spring there are #Controller and #RequestMapping annotations in the controller class and this framework doesn't use any HttpServlet.
I want this exact structure in Java EE (but without using any other framework).
So my question is: how can I use MVC in Java EE without using other frameworks?
Note: I don't want to use HttpServlet class
(1)
You can use JAX-RS and CDI to respond to HTTP requests, using annotations such as #Path and #RequestScoped. You might need some JAX-RS extensions or utilities for convenience, for better handling of parameters (e.g. RestEasy's #Form) and forwards to views (e.g. Jersey's Viewable).
(2)
You can also write a single HttpServlet (I hope that's not a problem) that will act as a front controller, instantiating the controller for each request. Using CDI, you can annotate your controllers with #Model (which is the same as #RequestScoped and #Named), and instantiate them in your front controller with:
#Inject #Any
private Instance<ControllerBaseClass> controllerInstance;
(...)
ControllerBaseClass controller = controllerInstance.select(«something»).get();
controller.processRequest(); // or execute() or anything you want.
request.getRequestDispatcher(«page»).forward(request, response); // or a redirect if it's a destructive operation.
What do you need to pass to select(«something»)? You can select an instance in CDI using annotation literals (consult CDI documentation) or classes (Class.forName(...)), depending on the request parameters.
Using CDI you can also make your controllers #ApplicationScoped instead of #RequestScoped.
As you see, you may need to build some infrastructure and stick to some patterns from then on, but it's perfectly feasible. I have used a mix of both strategies in a personal project and it works fine.
You can do it with technologies available in Java EE.
It's important to mention that Java EE is itself composed of many specifications/frameworks, for which there are more implementations. See this: https://java.net/projects/javaee-spec/pages/Home
Example with JSF http://www.tutorialspoint.com/jsf/jsf_architecture.htm
Example with JSP http://www.datadisk.co.uk/html_docs/jsp/jsp_mvc_tutorial.htm
Another example with JAX-RS https://jersey.java.net/documentation/latest/mvc.html
JSF is much more feature rich than JSP, and there are many components already made for it: Omnifaces, Primefaces etc. JAX-RS is for web services.
Have fun!
By simply using EJB for business logic, CDI for bean management and JSF for view.
It is incorrect to say that with Spring MVC there is no HttpServlet. From Spring Framework javadoc : DispatcherServlet (a subclass of HttpServlet) is the Central dispatcher for HTTP request handlers/controllers of the Spring framework. So it's hidden in the framework but present.
In fact, except in JSP only applications (not really MVC ... and JSP are translated in ... Servlets !) or JSF applications, you have (subclasses of) HttpServlet in all Java EE applications. And as JSF is only a specification you have to use an implemantation of JSF. There are 2 well known implementations, Oracle Mojarra or Apache MyFaces but both are ... frameworks.
Of course, you can do MVC in Java EE without any framework. As explained in Model View Component on Wikipedia MVC is a design patter independant of any of its implementations. The hard part will be no HttpServlet.
I don't know may be my question is completely meaningless, but I can't find any straight information about it.
I had my JSF + Tomcat application and it worked just fine. I want to implement Restful services and JAAS logic. In order to do that, I switched to TomEE++.
Switching to TomEE means that my server will now be more heavy and I'm afraid than it will require more cpu and ram resources than I have in my Amazon AWS micro instance.
The question is: Will the performance drop down if I switch from only JSF managed beans to JSF + EJB?
The sub-question is: what EJB injections can do, and JSF managed beans can not do? (JSF does not allow cyclic injections for example)
Will the performance drop down if I switch from only JSF managed beans to JSF + EJB?
Measuring is knowing. But generally, this concern makes no sense.
what EJB injections can do, and JSF managed beans can not do? (JSF does not allow cyclic injections for example)
Generally, they are not intented to be interchangeable. Each have their own clear responsibility. You use JSF bean management annotations to manage beans for front-end (JSF pages). You use EJB bean management annotations to manage beans for business services (BOs/DAOs). That's it.
To learn how JSF+EJB(+JPA) are supposed to work together head to the concrete examples and explanations shown in the following answers:
JSF Service Layer
JSF managed-bean EJB injection
Filter do not initialize EntityManager
JSF request scoped bean keeps recreating new Stateful session beans on every request?
I am reviewing my code from since I picked up on JSF.
One of the most complex issues has come up once again. The decision between CDI and EJB.
I am using three layers and I wonder which type of annotation to use on each of them:
- Backing beans (the Controller as defined in MVC)
- The service layer
- DAO's
My backing beans are using CDI, as long as I don't need anything from EJB.
But I am stuck on those other two. I remember reading about using EJB beans because of the pooling functionalities, which would prevent massive loads of requests (or attacks, if you will).
So in short, is there ANY reason to use EJB (Stateless, Stateful, LocalBean et cetera), considering security or anything else (excluded ViewScoped)?
Thanks in advance.
You're making a conceptual mistake here. CDI is absolutely not an alternative to EJB. CDI in its default trim doesn't offer transaction management at all. CDI is a bean management and dependency injection API, not a service layer API. In order to manage transactions in CDI, you've to add another API along with a bunch of another annotations.
CDI can replace for example JSF managed bean annotations, but definitely not EJB annotations.
So there's no means of a valid "CDI vs EJB" question. Both have their own completely distinct purposes. Note that you can perfectly inject EJB based service classes in CDI based managed bean classes.
As to security, it's not clear why you mentioned that part in the title and the tags, but the decision between CDI and EJB has nothing to do with security (simply because there's no means of a valid "CDI vs EJB" question in first place).
Yes when you require out-of-box support for transactions, concurrency, pooling etc.
I'm having a tough time understanding how the two interact and where the boundary between them lies. Do they overlap? Are there redundancies between them?
I know there are annotations associated with both, but I haven't been able to find a complete list for both with brief descriptions. Not sure if this would help clear up how they differ or where they overlap.
Really just confused. I (think I) understand EJB reasonably well, I guess I'm having a hard time understanding exactly what CDI brings to the table and how it supplants or enhances what EJB already offers.
It is currently indeed a bit confusing as there are now multiple component models in Java EE. They are CDI, EJB3 and JSF Managed Beans.
CDI is the new kid on the block. CDI beans feature dependency injection, scoping and an event bus. CDI beans are the most flexible with respect to injection and scoping. The event bus is very lightweight and very well suited for even the simplest of web applications. In addition to this, CDI also exposes a very advanced feature called portable extensions, which is a kind of plug-in mechanism for vendors to provide extra functionality to Java EE that can be made available on all implementations (Glassfish, JBoss AS, Websphere, etc).
EJB3 beans were retrofitted from the old legacy EJB2 component model* and were the first beans in Java EE to be managed beans via an annotation. EJB3 beans feature dependency injection, declarative transactions, declarative security, pooling, concurrency control, asynchronous execution and remoting.
Dependency injection in EJB3 beans is not as flexible as in CDI beans and EJB3 beans have no concept of scoping. However, EJB3 beans are transactional and pooled by default**, two very useable things that CDI has chosen to leave in the domain of EJB3. The other mentioned items are also not available in CDI. EJB3 has no event bus of its own though, but it does have a special type of bean for listening to messages; the message driven bean. This can be used to receive messages from the Java Messaging System or from any other system that has a JCA resource adaptor. Using full blown messaging for simple events is far more heavyweight than the CDI event bus and EJB3 only defines a listener, not a producer API.
JSF Managed Beans have existed in Java EE ever since JSF was included. They too feature dependency injection and scoping. JSF Managed Beans introduced the concept of declarative scoping. Originally the scopes were rather limited and in the same version of Java EE where EJB3 beans could already be declared via annotations, JSF Managed Beans still had to be declared in XML. The current version of JSF Managed Beans are also finally declared via an annotation and the scopes are expanded with a view scope and the ability to create custom scopes. The view scope, which remembers data between requests to the same page is a unique feature of JSF Managed Beans.
Apart from the view scope, there is very little still going for JSF Managed Beans in Java EE 6. The missing view scope in CDI there is unfortunate, since otherwise CDI would have been a perfect super set of what JSF Managed Beans offer. Update: In Java EE 7/JSF 2.2 a CDI compatible #ViewScoped has been added, making CDI indeed that perfect super set. Update 2: In JSF2.3 the JSF managed beans have been deprecated in favour of CDI managed beans.
With EJB3 and CDI the situation is not that clear cut. The EJB3 component model and API offers a lot of services that CDI does not offer, so typically EJB3 cannot be replaced by CDI. On the other hand, CDI can be used in combination with EJB3 - e.g. adding scope support to EJBs.
Reza Rahman, expert group member and implementor of a CDI implementation called CanDI, has frequently hinted that the services associated with the EJB3 component model can be retrofitted as a set of CDI annotations. If that were to happen, all managed beans in Java EE could become CDI beans. This does not mean that EJB3 disappears or becomes obsolete, but just that its functionality will be exposed via CDI instead of via EJB's own annotations like #Stateless and #EJB.
Update
David Blevins of TomEE and OpenEJB fame explains the differences and similarities between CDI and EJB very well on his blog: CDI, when to break out the EJBs
*
Although it's just an increment in version number, EJB3 beans were for the most part a completely different kind of bean: a simple pojo that becomes a "managed bean" by applying a simple single annotation, vs the model in EJB2 where a heavyweight and overly verbose XML deployment descriptor was required for each and every bean, in addition to the bean being required to implement various extremely heavyweight and for the most part meaningless component interfaces.
** Stateless session beans are typically pooled, stateful session beans typically not (but they can be). For both types pooling is thus optional and the EJB spec does not mandate it either way.
CDI: it is about dependency injection. It means that you can inject interface implementation anywhere. This object can be anything, it can be not related to EJB. Here is an example of how to inject random generator using CDI. There is nothing about EJB. You are going to use CDI when you want to inject non-EJB services, different implementations or algorithms (so you don't need EJB there at all).
EJB: you do understand, and probably you are confused by #EJB annotation - it allows you to inject implementation into your service or whatever. The main idea is that class, where you inject, should be managed by EJB container.
Seems that CDI does understand what EJB is, so in Java EE 6 compliant server, in your servlet you can write both
#EJB EJBService ejbService;
and
#Inject EJBService ejbService;
that's what can make you confusing, but that's probably the only thing which is the bridge between EJB and CDI.
When we are talking about CDI, you can inject other objects into CDI managed classes (they just should be created by CDI aware frameworks).
What else CDI offers... For instance, you use Struts 2 as MVC framework (just example), and you are limited here, even using EJB 3.1 - you can't use #EJB annotation in Struts action, it is not managed by container. But when you add Struts2-CDI plugin, you can write there #Inject annotation for the same thing (so no more JNDI lookup needed). This way it enhances EJB power, but as I mentioned before, what you inject with CDI - it does not matter if it is related to EJB or not, and that's its power.
PS. updated link to the example
Albert Einstein: If you can't explain it simply, you don't understand it well enough
Ejbs and CDI are pretty simple to understand.
Ejbs:
Will always be annotated by scope qualifiers, for instance, #Stateless, #Stateful, #Request etc
The instances of Ejbs is controlled by the Java EE framework and pooled. It is the duty of EE framework to provide the instances for the consumer.
#Stateless
public class CarMaker(){
public void createCar(Specification specs){
Car car = new Car(specs);
}
}
The CarMaker is Annotated with specific Ejbs scope, therefore, it's Ejb
CDI:
Not managed entirely by EE framework, instances has to be created by yourself.
It is always dependent. let me explain "Dependent" with example:
class Specification {
private String color;
private String model;
//- Getter and Setter
}
The Specification class is CDI, since it is not annotated with Ejb scopes and also this has to initialized by your code not EE framework.
One point to be noted here is that since we didn't Annotated the Specification class, it is by default Annotated by #Dependent annotation.
#Dependent <- By default added
class Specification { ... }
Further reading: You need to study more between Ejbs scope annotation and CDI scope annotation, that will further clear the conceptl