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.
Related
We have a multimodule Java EE 5 project running on Weblogic 10.3.x. One module has the EJBs and our batch processor is running from the web-module. Since we don't have CDI in JavaEE5, we have to do a JNDI-lookup on the EJBs. The EJBs are defined with #Stateless on the class and #Remote on the interface.
I have succeeded accessing the EJBs by looking the following string:
ejb/batchService#com.example.service.batch.ejb.BatchServiceRemote
However, I belive this is highly platformdependent, and I suspect I should have put something inside the web.xml and probably into the weblogic.xml at least in the web-module - maybe even in the EJB module...
Could anyone enlighten me how to do this propperly? Or is this the best way available?
JNDI format of local bean is
java:comp/env/BeanClassName
JNDI format for remote bean is
mappedName#com.package.BeanClassName
for
#Stateless(mappedName = "mappedName")
public class BeanClassName {
PS. This format supported by WebLogic 10.3. Behaviour of another application servers may be differentю
Prior to EJB 3.1 / EE 6, there are no standardized lookup strings for EJBs. Since they're not standardized, hard-coding the actual binding name of the EJB does make your project product-specific.
The best solution is to create another level of indirection: declare an <ejb-local-ref> in web.xml (or as #EJB/#EJBs on a servlet or other component class), and then use java:comp/env/xyz to lookup the ref. Then, use platform-specific bindings for the EJB ref.
I would be very much thankful to clear me some question about this new EJB3.0 and above version:
1) if suppose I need ejbCreate, ejbActivate and all other events so how can I get it from the new EJB3.0 and above ver.
2) I always have problem to find particular xml file to alocate a JNDI name according to variety of Application Servers so is there any way that I can give JNDI name without xml file and can also be use a portable name that in every Application Server it can be findable of EJB deployed on app server remotely
3)Can any buddy tell me, i have hosting plan of Java/Linux which supports
i) Tomcat - 5.5.xSupport
ii)JDK - 1.6.x Support
iii)JSP/servlet - 2.0 Support
can it be possible that EJB 3.1 be deployed because some where i have got that tomcat is not able to deploy EJB so please give me some advice help...
Thank You...!!!
please Help me...!!!
1) if suppose i need ejbCreate, ejbActivate and all other events so
how can i get it from the new EJB3.0 and above ver.
In EJB 3 and above, the EJB lifecycle is handled through life cycle annotations, such as: #PostConstruct and #PreDestroy.
2) i always have problem to find perticular xml file to alocate a JNDI
name according to variety of Application Servers so is there any way
that i can give JNDI name without xml file and can also be use a
portable name that in every Application Server it can be findable of
EJB deployed on app server remotly
The #Stateless and #Stateful annotations have two attributes that might solve this issue (name and mappedName). Yet
The mapped name is product-dependent and often installation-dependent.
Hope it helps you.
1) ejbCreate, ejbActivate etc. are related to EJB 2.x, if you need similar functionality in EJB 3.x, you should decorate your methods with annotations #PostActivate, #PrePassivate etc. Method signature should follow certain rules, example for #PostActivate:
The method annotated with #PostActivate must follow these
requirements:
The return type of the method must be void.
The method must not throw a checked exception.
The method may be public, protected, package private or private.
The method must not be static.
The method must not be final.
This annotation does not have any attributes.
2) It seems that you're referring to name and mappedName attributes of #Stateless and #Stateful annotations. For more details see official documentation. From my experience mappedName is better, but it's application-server-specific, e.g. on Glassfish it works perfectly. Example:
#Stateless(mappedName="ejb/myBean")
public class MyFirstBean {
..
}
Since no one answered Question 3 ..
3)Can any buddy tell me, i have hosting plan of Java/Linux which supports i) Tomcat - > 5.5.xSupport ii)JDK - 1.6.x Support iii)JSP/servlet - 2.0 Support
No, you are going to need a server that supports Java EE. Read How to deploy EJB based application on Tomcat
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.
In my company the usage of the Spring framework is discouraged and instead Java EE 6 is promoted. But recently I read about Springs #Transactional annotation at Using #Transactional and think this could be really useful for our code.
As far as I understand a method annotated with #Transactional will either reuse an already existing transaction or open up a new transaction if no active transaction exists when calling that method. Is there something analogous (e.g. a similar annotation) available in Java EE 6?
EJB components have this transactional control in Java EE. You can set the transaction of a method on the EJB to be Required, RequiresNew, Supports, etc. You would almost always use a Stateless Session Bean (#Stateless) for the requirements you describe:
> #TransactionAttribute(value=[MANDATORY,
> REQUIRED, REQUIRES_NEW, SUPPORTS,
> NOT_SUPPORTED, NEVER]
Required, the default, will re-use an existing txn if there's one running or create a new one if there is not. Java EE 6 ships with EJB 3.1, so you don't even need the Business Interface and you can package the EJBs in the WAR file if you want. Therefore you are using EJBs, but to the developer they are much easier to integrate if all you want is JTA support.
This is a useful cheat sheet for the EJB annotations and there are numerous guides if you Google for them.
Java EE 7 now contains #javax.transactional.Transactional.
It acts quite the same as the spring annotation.
In Java EE 6, one may annotate the EJB bean class itself, or the individual business methods in an EJB (both session EJBs and MDBs) with the TransactionAttribute annotation. This can be applied only if you use container managed transactions.
Valid values for the annotation are defined in the TransactionAttributeType annotation:
NOT_SUPPORTED
SUPPORTS
REQUIRED
REQUIRES_NEW
MANDATORY
NEVER
The semantics of these values haven't changed from the earlier versions of the EJB specification. These annotations are available since Java EE 5, when annotations were introduced in EJB 3.0. Note that, some of the values are not applicable in certain scenarios - MDBs for instance cannot be annotated with anything but REQUIRED and NOT_SUPPORTED; any other values would not make sense for container managed trasactions for a MDB (after all, the container must either create a transaction or musn't, in this case).
If you want a quick overview of how the transaction attributes compare between the EJB 3.0 and Spring models, I would gladly point you in the direction of Java Transaction Design Strategies. Disclaimer: I'm just a satisfied reader of this book.
EJB's (stateless and stateful) are default transactional components, default transactional property is REQUIRED, similar to spring..
I'm trying to inject a EJB within my RESTful Service (RESTEasy) via Annotations.
public class MyServelet implements MyServeletInterface {
...
#EJB
MyBean mybean;
...
}
Unfortunately there is no compilation or AS error, the variable "mybean" is just null and I get a NullPointerException when I try to use it.
What I'm doing wrong?
Here are some side-informations about my architecture:
JBoss 4.2.2.GA
Java version: 1.5.0_17
local MDB-Project
remote EJB-Project
WAR Project with the RESTful Service which uses the remote EJB and sends messages to the local MDB-Project
Thanks in advance!
br
Dominik
p.s: everything is working fine when I use normal context lookup.
I had a similar problem (though without #Remote beans). The way it worked for me - sample application is here: https://github.com/kubamarchwicki/rest-app/ (this works: https://github.com/kubamarchwicki/rest-app/blob/master/service-webapp/src/main/webapp/WEB-INF/web.xml#L9)
The crack with context lookup is that the name changes with a change of the ear name. If you fancy things like versions, it makes the whole thing hard to trace or forces you to hardcode ear name somewhere in the code.
Just a few cents to an old discussion ;-)
This is not exactly my forte, so maybe I am way off... but, can you do EJB stuff in a WAR? I was under the impression you needed to do EJB work in an EAR.
JBoss 4.2.2.GA is not a fully compliant Java EE 5 server, it does not support EJB references injection in servlets or application clients, only in the EJB layer. Use JBoss 5 for that (or perform a lookup).
JBoss 4.2.2.GA supports only Servlet 2.4. There is no support of DI on Servlet 2.4. Hence you always get 'null' for myBean variable. As suggested, please migrate to JBoss 5.0 which supports Servlet 2.5 which makes use of Java 5 features like annotations.