The Source for Java Technology Collaboration
User: Password:



Sahoo's Blog

J2EE Archives


A javac plugin to manage your persistence.xml

Posted by ss141213 on November 26, 2007 at 07:54 AM | Permalink | Comments (3)

I am glad to say that in most cases, I do not write a persistence.xml file any more. No, I am not using any IDE to generate it for me, nor has the spec relaxed any requirement. We will discuss some other time why persistence.xml is a necessary evil. Then what has changed? Well, my compiler creates it for me - yes, I said javac creates it for me. When I execute
javac -d . -classpath ... FooEntity.java BarEntity.java Main.java
, a META-INF/persistence.xml file with necessary entries is created next to my .class file. See an example
of such a generated file. If there already exists a persistence.xml, then the above command just updates the managed persistence class names in it. It does not matter whether javac is invoked from command line, or Ant or Maven. To a certain extent, I can even control what goes into that file. e.g. I can choose the provider name, and it generates appropriate entries specific to the provider. Similarly I can also specify what should be the persistence-unit name and so on. Interested? You can use it. Read on...

No, I have not modified javac. Starting with Java SE 6, the Java Compiler allows users to plug in an annotation processor which gets called in an appropriate phase of compilation. If an annotation processor is available in javac's classpath, then javac can discover it using service discovery mechanism. Read Annotation Processing in javac for further information. Using the said feature, I have written a simple, standard compliant javac plugin to provide the necessary functionality.

How you can use?
You can download the plugin from here
; it is free, comes with no warranty. I will try to support it as time permits. To use it, just add thet jar file to classpath during compilation. That's it, now go onto compile your code as usual. Being a compiler plugin, it is not even required at runtime. Even if it's there in runtime classpath, it is harmless. So, the easiest option is to copy the jar to $JAVA_HOME/lib/ext. Since lib/ext is used in runtime as well, no matter how harmless the jar is, some people don't like this approach. More over, in a shared system, you may not even have permission to write to lib/ext. In such a case, you can follow one of the following options:

For command line javac invocation, just add it to compiler classpath using -classpath option. e.g.,
javac -classpath $HOME/pxml-javac-plugin.jar:$CLASSPATH *.java
Ant users can modify the classpath attribute of the javac task. IDE users can add the plugin.jar in their project's compilation classpath.

Maven users:
Step 1: Download the special maven2 repository format zip file from here
.
Step 2: Install it in your local maven2 repository (by default ~/.m2/repository) by running following command:
unzip -d ~/.m2/repository pxml-javac-plugin-maven.zip
Step 3: Modify your pom to add a compile time dependency to this plugin like this:

< dependency>
< groupId> org.sanjeebsahoo</groupId>
< artifactId> pxml-javac-plugin</artifactId>
< version> 1.0-SNAPSHOT</version>
< scope> compile</scope>
</dependency>

That's it, no other change is needed. Isn't it straight forward to use?

How to pass additional options to the plugin:
Sometimes you may like to pass additional options to our plugin to control what goes inside the persistence.xml. Currently supported options are described below. Unless specified, all options are optional. Since there can be multiple plugins for the javac, in order reduce probability of name collision, each option is prefixed with "pxmlplugin."
1. pxmlplugin.provider: Acceptable values are toplink, hibernate, openjpa. Default value is toplink. Use this option when you don't have a persistence.xml file to start with and you want the provider to be other than toplink.
2. pxmlplugin.pu: name of the persistence-unit. Default value is pu1. It solves two purpose, viz:
a) when a new persistence.xml is created, this will be used as the name of the persistence-unit.
b) when there already exists a persistence.xml with multiple persistence-units, this is used to select the desired one for update.
3. pxmlplugin.verbose: prints additional information as debugging aid. By default, it is switched off.
How you specify the option depends on which javac you are using. While using javac that comes with Sun JDK, prefix the option by -A. e.g.,
javac -Apxmlplugin.provider=hibernate -Apxmlplugin.pu=pu1 -Apxmlplugin.verbose -classpath pxml-javac-plugin-1.0-SNAPSHOT.jar Foo.java
For non-Sun JDK, check your javac documentation.

Conclusion:
I find this plugin very useful. It not only saves me from writing persistence.xml file in most of the case, it allows me to avoid duplicating class names in persistence.xml, thus saves me from troubles that can arise because of duplication of information. Would love to know your comments. Suggest improvements. I will be happy to make it when I get the time. Since the plugin uses all the standard APIs, I expect it to work with all Java SE 6 compatible javac. You can try and let me know.

Continue Reading...



Welcome to GlassFish @ FOSS.IN 2006

Posted by ss141213 on November 23, 2006 at 09:00 AM | Permalink | Comments (2)

GlassFish at FOSS.IN 2006
GlassFish team from Sun Microsystems will not only talk about GlassFish & Java EE platform at the forth coming FOSS.IN 2006 event, but will also have a booth where they will answer questions about GlassFish and show case GlassFish technology that includes a demo app built using GlassFish and NetBeans IDE. The complete source code and build scripts for the demo app are available here. Just unzip and explore. You can view the flash demo here.

Highlights of the demo:
1. Learn to develop real world Java EE application.
2. Learn to use Java EE 5 features of NetBeans like JPA entity bean wizard, Web Service wizard, Web Service Client wizard.
3. Auto-completion of annotations, on-the-fly verification of code against Java EE spec, refactoring etc. features in NetBeans IDE
4. Experience the integration of GlassFish with NetBeans
5. Introduction to GlassFish web based administration interface
6. Learn to use Verifier tool of GlassFish to check compliance against spec.

What does the demo app do?
It's a Java EE application which will help us capturing details about visitors who visit us in FOSS.IN 2006. What is interesting about the demo app is that it is also used as a live application in our GlassFish booth area to capture details about visitors. It has:
a) an EJB module containing a Web Service that stores visitor information in database using Java Persistence API(EJB 3), also sends a follow up email to the visitor using JavaMail.
b) a web module which contains a JSP which is used to capture visitor details. The JSP also acts as the web service client.

Important Links:
GlassFish flash demo
Source code for the demo

See you in GlassFish presentation and booth at FOSS.IN.

More blogs about



Persistence Context propagation

Posted by ss141213 on October 27, 2006 at 11:01 AM | Permalink | Comments (17)

What is persistence context propagation?
A persistence context(PC) is a set of managed entity instances in which for any persistent entity identity there is a unique entity instance (this definition is taken from Java Persistence API spec, section 5.1). An Entity Manager(EM) provides the necesarry APIs to interact with a persistence context.
There is often a need to access the entities in the same PC in different components (say multiple EJBs or web component and EJB etc.) involved in processing of a request. One way of doing this is to pass an EM instance around in the call stack from one component to another, but that's not so elegant as it pollutes the interfaces. A better and recommended approach is to use a feature called Persistence Context Propagation that is offered by the Java EE container. PC propagation allows multiple components of a Java EE application to share the same persistence context. Each component use their own EM which they obtain using dependency injection or JNDI lookup and when they use the EM in the contex of the same JTA transaction, container automaticaly binds the EM to the same PC. Thus application does not have to explicitly pass an EM from one component to another. This technique is portable across any Java EE 5 compatible application server.

Rules governing PC propagation
1. Only a PC associated with a container managed EM can be propagated.

2. A PC is propagated along with the JTA transaction.

3. PC propagation is applicable only to local environments(i.e. one JVM). PC is not propagated across remote tiers even if the remote component is collocated in the same address space as the client.

4. A PC is propagated when the called component uses EM that belongs to the same Entity Manager Factory as the caller.

5. It is an application error to attempt to propagate a PC to a SFSB that is already associated with a different PC. In such a case, EJB container throws EJBException to the caller.

Let's apply the rules (rule shown in ()) and see some cases where PC propagation takes place:

1. (rule #1) Since a container managed EM can only be obatined via @PersistenceContext or persistence-context-ref, PC propagation does not take place for EMs obtained using EntityManagerFactory.createEntityManager().

2. (rule #2) A PC won't be propagated (e.g.) when an EJB with bean managed transaction or an EJB method with transaction attribute REQUIRES_NEW, NOT_SUPPORTED or NEVER is called because transactions are not propagated to such methods(see Chapter #13 of EJB 3.0 Core specification). More over, unless the caller is associated with a transaction, PC propagation will not happen. I don't know the behavior when a request is dispatched from one web component to another using using RequstDispatcher object. There are two questions that determine the answer, viz: a) is that ever considered a local call? b) does web container propagates the JTA transaction along with the request? If you know the answer, let me know. Else, I will try to find out myself.

3. (rule #3) Don't expect PC to be propagated when you call a remote EJB even when the remote EJB happens to be running in the same JVM or part of the same application.

4. (rule #4) All the components that want to share the PC must use the same persistence unit. Container internally creates an EntityManagerFactory corresponding to a persistence unit and uses it to create EMs. Persistence units defined in separate persistence.xml files or persistence units defined separately in one persistence.xml file are considered different no matter how idenically they are set up. So, if components from two different modules in an EAR file (e.g. a Servlet calling an EJB) want to share PC, then the persistence unit must be packaged as an EAR scoped persistence unit (e.g. in a jar file in lib folder of the EAR).

5. (rule #5) If a component is associated with a PC then it can't call a local SFSB with a different extended PC to which current transaction context will be propagated. GlassFish reports this very nice message when I tried doing this in a test case: javax.ejb.EJBException: There is an active transactional persistence context for the same EntityManagerFactory as the current stateful session bean's extended persistence context. (rule #5)

These rules are not complete. Please refer to the JPA spec for more details.

Sample Application
Let's now use this feature in a simple Java EE application. In this example, a PC is shared between ReportServlet and UserCredentialManagerBean. I must say this is a bad example of PC propagation, but I just could not think of a better example for this article. The source code and build script can be downloaded from here. Instructions to build and run are available in the README. There are lots of System.out.println statements in the code that gives an insight into what is happening. All those messages go to the $GLASSFISH_HOME/domains/domain1/logs/server.log by default. Although I am using GlassFish which is the reference implementation of Java EE 5 platform, you can use it in any Java EE 5 compatible application server.
Let's now look at the relevant sample code:

1. ReportServlet.java
:
Since a servlet should not be injected with a PC, ReportServlet gets hold of a container managed EM by looking up JNDI environment as shown below:


EntityManager em = (EntityManager) new InitialContext().lookup(
"java:comp/env/persistence/EM1");

The above look up returns a valid EM because the Servlet has declared a dependency on a PC for the persistence unit named pu1 and has given this dependency a name persistence/EM1 using the following code:

@PersistenceContext(name="persistence/EM1", unitName="pu1")
public class ReportServlet extends HttpServlet {

ReportServlet begins a transaction using the injected UserTransaction object, obtains a managed entity instance by invoking lookup method of injected UserCredentialManager session bean, accesses the lazily fetched field of the entity and then commits the transaction in the code below:

utx.begin();
UserCredential user = ucm.lookupUser(name);
for(LoginAttempt attempt : user.getLoginAttempts()) {...}
utx.commit();

2. UserCredentialManagerBean.java:
This is a stateless session bean with container managed transaction(this is the default). It has a local business interface called UserCredentialManager. It uses an injected EM. The transaction attribute for lookup method is REQUIRED (default).

3. Persistence Unit:
There is an EAR scoped persistence unit called pu1 which is defined in lib/entities.jar. Both the servlet and the session bean reference this persistence unit. There are two entity beans, viz UserCredential.java and LoginAttempt.java

You may have noticed that ReportServlet does not use the EM in any meaningful way. So, it can be totally removed from ReportServlet and yet ReportServlet will be able to use the entity in the same PC as that of the EJB.

Let's see what would have happened if ReportServlet does not start the transaction before calling lookup method. Lookup method starts a new transaction and EJB container creates a new PC when the injected EM is used. This PC gets closed automatically when the transaction is ended at the end of that method, thus the returned entity becomes detached. Since fetch type for loginAttempts is LAZY (by default it is lazy for collection valued fields) and the field has not been accessed by lookup method, accessing it in the Servlet is asking for trouble (see section #3.2.4 of the JPA spec). GlassFish persistence provider is generous enough to allow such an access, but when I tested using OpenJPA, it threw a NullPointerException.

Conclusion
Hope you find this useful.

Resources
Packaging of Java EE application that uses JPA
Plugging in a thirdparty provider in GlassFish
More blogs about



Using OpenJPA as Java Persistence API provider in GlassFish

Posted by ss141213 on July 27, 2006 at 03:31 PM | Permalink | Comments (6)

As this theserverside.com announcement shows, although OpenJPA is still in the Apache incubator and not yet certified as a Java Persistence API compliant provider, it is not far from that stage. There is a source download available and I must say, it is quite easy to build. If you want to use it in GlassFish, then it's even easier. It is as simple as these intuitive steps:


Step #1: Download and install GlassFish
Download any of the latest builds of GlassFish v2 or v1_ur1 from here. Install it in any directory of your choice. I refer to that as GLASSFISH_HOME.


Step #2: Build & Install OpenJPA
Build OpenJPA using these instructions. It's really simple to build. The build process produces a zip file called openjpa-project/target/filtered-site/resources/downloads/openjpa-0.9.0.zip
Unzip this to any location. In this blog, I refer to that location as OPENJPA_HOME.


Step #3: Install OpenJPA in GlassFish
All you need to do is to make OpenJPA implementation jar files available to GlassFish runtime. This can be achieved as follows:

 cp ${OPENJPA_HOME}/openjpa*.jar ${OPENJPA_HOME}/lib/*.jar ${GLASSFISH_HOME}/domains/domain1/lib 

GlassFish will automatically make this jar part of its classpath next time when you restart the server.


Step #4: Edit persistence.xml
Make a one line change to your persistence.xml to instruct GlassFish that we want to use OpenJPA as the persistence provider for this application. This is achieved by setting element to org.apache.openjpa.persistence.PersistenceProviderImpl. Shown below is a sample persistence.xml:


<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name ="em1">
<provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
<properties>
</persistence-unit>
</persistence>

Step #5: Build and deploy your app
Now you can build your Java EE application and deploy it to GlassFish.


Conclusion:
As you can see, it is fairly simple to use any third-party provider in GlassFish. We had earlier talked about using Kodo and Hibernate in GlassFish. Please let us know, if you want any particular provider to be used in GlassFish that's not covered yet.


Resources
If you want some working applications, then you can download them from my earlier blogs:
a) a web application that uses Java Persistence API -- download the complete sample from here
b) a multi-tier Java EE application (web->ejb->JPA) -- download the complete sample from here.
After downloading, you need to change persistence.xml as described above. Then you can use the existing build.xml to build the app.


You don't have to read this if you followed the above instructions:
I will share a problem that I ran into. I did some static analysis of the OpenJPA provider class using a little static analyser tool and figured out a list of dependent jar files. First time when I tried OpenJPA in GlassFish, I only copied the list of jars that I inferred from the static analysis phase. But I never realized that OpenJPA loads a lots of classes using reflection. I never imagined that not having a dependent jar file in CLASSPATH could lead to an exception like
org.apache.openjpa.persistence.ArgumentException: No table was given for persistent type example.UserCredential even when table for that entity existed in database. Thanks to Pinaki who pointed out that OpenJPA uses Jar Service Provider mechanism quite a lot so that its Kernel can be configured for either JPA or JDO environment. As a result of this, unless all the services are available in CLASSPATH, the kerner can't be correctly configured and that unfortnately leads to very weired exceptions. When I copied all the jar files from $OPENJPA_HOME/lib to $GLASSFISH_HOME/domains/domain1/lib, it worked.

Having said that, you actually don't need to copy the following jar files as GlassFish runtime already have those classes:
geronimo-j2ee-connector_1.5_spec-1.0.1.jar
geronimo-jms_1.1_spec-1.0.1.jar
geronimo-jta_1.0.1B_spec-1.0.1.jar
persistence-api-1.0.jar
derby-10.1.3.1.jar
It's no harm done even if you copy these jar files because GlassFish will simply ignore them.

Hope you find this blog useful. More blogs about

Thanks.



Using Kodo as Java Persistence API provider in GlassFish

Posted by ss141213 on May 28, 2006 at 03:44 AM | Permalink | Comments (2)

Earlier we had shown how to plug in Hibernate in GlassFish. Now it's time for Kodo, which is another high performance & popular O/R mapping solution. Recently Kodo 4.0GA was released and it supports Java Persistence API 1.0. So, I thought I shall give a try using it in GlassFish. The instructions are really simple. They do not involve any unreasonable steps.

Step #1: Download and install GlassFish
Install it in any directory of your choice. I refer to that location as GLASSFISH_HOME here. More details about which build of GlassFish to use is given towards the end of this blog.

Step #2: Download and install Kodo 4.0GA
Yes, you should use Kodo 4.0GA or above. Don't use any of the earlier releases (like) 4.0RC1, RC2 etc. as there are issues that have been addressed in 4.0GA. Install Kodo in any directory of your choice. I refer to that location as KODO_HOME here.

Step #3: Install Kodo in GlassFish
I particularly liked the fact that, kodo.jar is a self contained jar file. It does not depend on any other APIs except standard Java EE 5 APIs which are anyway available in GlassFish. So, all we need to do is to make kodo.jar available in GlassFish domain where we want to deploy the application. This can be achieved as follows:

 cp $KODO_HOME/lib/kodo.jar $GLASSFISH_HOME/domains/domain1/lib/ 

GlassFish will automatically make this jar part of its classpath next time when you restart the server.

Step #4: Edit persistence.xml
Make a couple of changes to your persistence.xml. First of all, we need to instruct GlassFish that we want to use Kodo as the persistence provider for this application. This is achieved by setting element to kodo.persistence.PersistenceProviderImpl. Secondly, we need to provide a valid Kodo license key. This is achieved by setting kodo.LicenseKey. Shown below is a sample persistence.xml:


<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name ="em1">
<provider>kodo.persistence.PersistenceProviderImpl</provider>
<properties>
<property name="kodo.LicenseKey" value="USE YOUR LICENSE KEY"/>
</properties>
</persistence-unit>
</persistence>

Step #5: Build and deploy your app
Now you can build your Java EE application and deploy it to GlassFish.
If you want some working applications, then you can download them from my earlier blogs:
a) a web application that uses Java Persistence API -- download the complete sample from here
b) a multi-tier Java EE application (web->ejb->JPA) -- download the complete sample from here.
After downloading, you need to change persistence.xml as described above. Then you can use the existing build.xml to build the app.

Points to note:
1. The choice of persistence provider is a runtime configuration. Development process, environment, source code and build scripts do not depend on the persistence provider. This is evident from the fact that the above examples were written originally for GlassFish and its default provider. We could use it for GlassFish/Kodo combination by just changing persistence.xml.

2. We can use Java2DB feature of GlassFish even while using Kodo. In fact, example #2 uses this. This feature is very handy for folks who don't have a prexisting database schema to work with.

Which GlassFish build to use?
Use latest builds of GlassFish v2. If you want to use GlassFish v1, then you should read the following section as it discusses the two bugs that I discovered while using Kodo in GlassFish v1 (i.e.) SJSAS 9.0pe:

bug #679: This affects web applications using Java Persistence API. As a work around, you have to package enhanced classes in your web application. Kodo comes with a program called kodoc which you can use to enhance the classes. I have already fixed this bug in GlassFish v2 and it will be available in GlassFish v2 build #04. Until build #04 is available, you can download the latest GlassFish v2 nightly build and use.

bug #233: It affects EJBs using Java Persistence API. As a work around, you have to redeploy the application every time you start the server. I have a fix available in my local workspace which I am going to integrate very soon in GlassFish v2 (most likely, it shall be part of v2 build #04).

Conclusion:
Pluggability of third party Java Persistence API providers into a Java EE container offers Java EE users exciting combinations to choose from and that too without sacrificing portability of their applications. Let us know if you are interested in any other provider to be used in GlassFish and we shall give it a try.
More blogs about



Which GlassFish build to use?

Posted by ss141213 on May 05, 2006 at 01:45 AM | Permalink | Comments (3)

Looking at some of the recent postings in the GlassFish forum, there appears to be some confusion in the GlassFish user community about which build to use. I will try to address the issue in this blog.

The main reason for this confusion is due to presence of two very active branches in the GlassFish CVS repository, viz: SJSAS90_FCS_BRANCH and the trunk (a.k.a. the main branch). They look something like this:



b48
/
b47
/
b46
/
b45
/
b44
/
b43
/
/SJSAS_90FCS_BRANCH
/
/
TRUNK__..._b41_b42__/____________________ TRUNK
^
|
30 Mar 2006
(The numbers starting with b are build numbers)

As the name suggests, SJSAS90_FCS_BRANCH is used for release of Sun Java System/Application Server PE 9.0 as well as Java EE 5 SDK. As the diagram shows, this branch was forked from the trunk around 30 March 2006. It is a highly controlled branch as it is used to release a product and currently this branch is in high resistance mode as the final release date is fast approaching. As a standard product release process, not all kinds of bug fixes are going into this branch.

The situation is very different for the trunk. It is open for checkins. In fact a lot of bug fixes and quite a few enhancements have gone into the trunk since SJSAS_90FCS_BRANCH was forked. If I have to single out any one module which has changed most in the trunk since the 9.0 branch was forked, then it will be entity-persistence module, which is the Java Persistence API implementation module in GlassFish. Not all these fixes were back ported to the SJSAS_90FCS_BRANCH for obvious reasons. Be rest assured, a number of these bugs will eventually be made available in a subsequent Update Release(UR) for 9.0.

Difference between promoted builds and nightly build
As the name suggests, nightly build happens every night. Before a binary is posted in the nightly download site, it must pass a predefined set of test cases. So, you can use a nightly build during development phase of your project. Typically after a series of nightly builds, one of the nihgtly builds get promoted and is made available in the promoted builds' web site. The typical frequency has been 1 week in GlassFish project. This allows the delta between two promotions to be significant. The number of tests that are run before promoting a nightly build is much larger than what are run to test the nightly builds.

Build Numbers/Name:
Each promoted build has a unique name. e.g. b01, b02...,b48 are all names of promoted builds happening on different dates. The nightly builds also have a name. It has two components viz: the next promoted build number and the date on which it was built. e.g. glassfish-installer-b43-nightly-01_may_2006.jar.

What is the confusion?
If you look at the branch diagram, you shall see that the b41, b42 etc. were built using source from the trunk. After the FCS branch was forked, promoted builds like b43, b44, ..., b48 (this is the latest promoted build as I am writing this blog) were done using source code taken from SJSAS_90FCS_BRANCH. This has confused many users. When users see some bug being marked as fixed, it is natural for them to expect the fix to be available in the next promoted build, but that did not happen after b42. I feel it would have been better to call 9.0 branch builds as something like b43_90 and continue to use b43, b44 as build numbers for trunk builds.
To specifically address such confusion, IssueTracker has a field called target milestone, but at this point, it is not clear what should be used in this field when a fix is integrated into the trunk. I wish, we could just use 9.1.

Finally, there is no promoted builds happening on the trunk right now. If you look at the GlassFish promited builds download site, you can see that after b42, there are no promotions happening on the trunk. Only nightly builds are happening as GlassFish nightly build download site shows. If you choose the platform of your choice there, you can see that there are download bundles are available with names like glassfish-installer-b43-nightly-01_may_2006.jar. Look at the date encoded in the name. That conveys the date on which that binary was built.

When is situation going to improve?
Recently a P1 issue (#640) has been filed and very soon I am hoping to see promoted builds happening on trunk.

Conclusion
In the mean while, if you are waiting for a build which fixes one of the bugs you are encountering, then you may use the latest nightly build. Use the date to decide which one is the latest build, don't assume that since the name contains b43, it is an old build.

Continue Reading...



Using Java Persistence API in application client in Java EE platform

Posted by ss141213 on March 21, 2006 at 01:03 AM | Permalink | Comments (7)

In Java EE 5 platform Java Persistence API can be used in three types of containers, viz: ejb, web and application client container. In my earlier blogs, I had talked about using this API in web applications and in EJB applications. This time we will talk about using Java Persistence API in application clients. We also discuss about two different way of packaging the application. You can download the complete sample, unzip and run 'ant deploy' to see the sample in action. The steps are very simple as discussed below:

Step #1: Write entity bean UserCredential.java
In my previous articles I have discussed about structure of an entity bean class. So I am not going to repeat them here.

Step #2: Define a persistence unit in persistence.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
<persistence-unit name ="pu1" transaction-type="RESOURCE_LOCAL"/>
</persistence>

Points to note about this persistence.xml are:

1) One persistence.xml can be used to define multiple PUs, but in this case we have defined only one PU by name pu1.

2) We need not specify any elements/attributes other than transaction-type, as the default values are just fine. By default the entity manager's transaction type is JTA. Since Application Client Container is not required to support JTA, we can not use JTA entity managers in this example. So we have set it to RESOURCE_LOCAL here.

3) There is no need to enumerate all the entity bean class names inside because we are defining only one PU in this persistence.xml and we will be packaging the entity classes along with this persistence.xml in a jar file, so container can discover all the entity beans.

Step #3: Write Client.java
Points to note about this appclient are that:

1) It declares dependency on the PersistenceUnit using @PersistenceUnit as shown below:

@PersistenceUnit private static EntityManagerFactory emf;

Also note that, the field ucm is static. More discussion on this further below. Secondly, there is only one PU visible to this application client, hence there is no need to specify the unitName attribute in @PersistenceUnit.

2) It must be a public class because it will be used by ACC which does not belong to the package of this class.

3) We also need to write a manifest.mf file which must contain the name of the class containing the main().

4) The rest of the client class is simple. It creates an EntityManager using the injected EntityManagerFactory. It closes it at the end of the application. Since we can't use JTA, the client uses EntityTransaction API to manage transactions.

5) There is no need to write application-client.xml because it is optional. Java EE 5 compatible platform can discover appclient.jar's module type because it contains META-INF/MANIFEST.MF with a Main-Class attribute.

Step #4: Build and package the application using build.xml
When using entity beans in appclient, we have two packaging options:
Option #1: package the entity beans and the persistence.xml in a jar file (say) entities.jar. Package the appclient main class along with its manifest.mf in a separate jar (say) appclient.jar. Put both these jars into an ear file. So the final ear file looks like this:

jpa_acc_option1.ear
lib/entities.jar (contains only entity classes)
appclient.jar (contains only client main class and manifest file)

Since the entities.jar is placed in the EAR lib directory, it is automatically added to CLASSPATH while running the appclient. So, no need to use Class-Path manifest entry.

Option #2: package the entity beans and the persistence.xml in the appclient.jar along with appclient main class. No need to make an ear file in this case, as we can just deploy the appclient.jar. The appclient.jar contains following entries:

appclient.jar:
META-INF/MANIFEST.MF (this contains Main-Class attribute)
META-INF/persistence.xml
example/client/Main.class
example/entity/UserCredential.class

To demonstrate this, there are two build targets, viz: build-app1 and build-app2. The third build target internally call these two targets. Same goes for deploy and verify targets.

Both of the packaging alternatives discussed here are completely portable. It is upto you to decide which of the options you want to use.

Step #5: Run the application
As we mentioned, there are two different applications here. Depending on which application you want to use, the option passed to appclient command is slightly different as the name of the generated jar file is different.
To run the first application client:
$GLASSFISH_HOME/bin/appclient -client $GLASSFISH_HOME/domains/domain1/generated/xml/j2ee-apps/jpa_acc_option1/jpa_acc_option1Client.jar foo bar

To run the second application client (see different generated jar file name):
$GLASSFISH_HOME/bin/appclient -client $GLASSFISH_HOME/domains/domain1/generated/xml/j2ee-modules/jpa_acc_option2/jpa_acc_option2Client.jar foo bar

Use of Java2DB
Please see I don't have instructions to create tables etc. I like to use
a feature called Java2DB in my development environment. Although there are more than one way of using Java2DB, I like to use it by passing --createtables option to asadmin deploy command. See build.xml for more info. This feature is specific to Sun's app server.

Why injected field or method must be static in application client?
When we package the application client, we specified the main class name using Main-Class attribute in manifest file. The entry point for an Applicaiton Client component is the static main method of that main class, so there is no instance.
ACC does not create any instance of that class. So the injected fields or methods have to be static.

Software Required
An implementation of the Java Persistence API is being done in GlassFish project. GlassFish was supporting Java Persistence API in EJB and Web containers for quite some time now. Only recently, we have just integrated the Java Persistence API support in Application Client Container. As I am writing this blog, we still have not promoted a build that has this change. So you have to use one of the latest nightly builds to run this example.
Although I am using GlassFish to build and run this sample, atmost you have to do some minor confiuration to persistence.xml and build.xml to make this app build and run in any other application server that supports Java EE 5 specification. This sample also uses a proprietary feature called Java2DB. But that does not make this a non-portable application as I am using it only during deployment.

Hope you found this example useful.

More examples of



When can I use hibernate as EJB3 persistence provider in GlassFish

Posted by ss141213 on January 17, 2006 at 01:08 AM | Permalink | Comments (5)

Can I use Hibernate in GlassFish? is a question I have been asked several times in recent past? Well, the answer is Yes & No(as of now), depending on what you are trying to use it as. By the way I must clarify, it's a NO only temporarily. Let's understand why:

Yes:
If you want to use Hibernate as yet another persistence framework, there is already a nice and detailed posting about how to use hibernate in GlassFish. That article shows how to use Hibernate session APIs, hibernate O/R mapping XML files etc. It does not talk about using Hibernate as an EJB 3.0 persistence provider. That's the reason you find so many configuration steps mentioned in that article.

No:
If you are trying to use Hibernate as an EJB 3.0 persistence provider, it is right now not possible. I must say, it's only a temporary no because of the mismatch in interfaces between GlassFish and Hibernate. When I say using Hibernate as an EJB 3.0 persistence provider, what I mean is that user is using EJB 3.0 persistence API(javax.persistence) classes. e.g. using @persistenceContext to inject an EntityManager, @Entity to annotate POJO classes as entity beans, persistence.xml to configure a persistence units etc. as demonstrated in in this example as opposed to using Hibernate session management APIs, Hibernate O/R mapping XML file to convert their POJO class to an entity bean etc. As you probably know the EJB 3.0 (JSR 220) spec defines a Service Provider Interface(SPI) to plug in a compliant persistence provider to a Java EE 5 container like GlassFish. These SPI classes are part of javax.persistence.spi package. If you look at the revision history of the EJB 3 Persistence(a.k.a. Java Persistence API) spec, you will see that (unfortunately) the SPI has been changing quite a lot while the spec is being finalized. So it is hard for any two different projects to keep in synch with each other. Now that the final draft of the EJB 3 spec has been proposed, hopefully(!) we have a stable interface that both GlassFish and Hibernate can soon implement to achieve this pluggability.

EJB 3.0 Persistence SPI
The SPI classes are part of javax.persistence.spi package. Users don't have to know about this package while using Java Persistence API inside a container. It is used by the container and persistence provider to provide the necessary pluggability. This is indeed good news for developers as they can use a combination of their favorite Java EE container with their favorite persistence provider without sacrificing portability of their applications. Some other day I shall talk more the SPI and issues around it.

Some EJB 3.0 Persistence API related resources:

Introduction to using Java Persistence API in Java EE
Latest builds of GlassFish where an open source implementation of this spec is being done.
GlassFish persistence project

More articles about



Custom tags to use Java Persistence API in JSP

Posted by ss141213 on January 02, 2006 at 12:57 PM | Permalink | Comments (0)

In earlier articles we have discussed about using Java Persistence API in a web application and in a multi-tier Java EE application. In this article I shall talk about a few custom JSP tags (the links in that page are broken, but when you download the complete bundle it includes a page where links work.) that I have developed to use Java Persistence API in JSPs. Collectively the tags are referred to as jpa taglib here. It also shows how to inject persistence context into JSPs. A JSP tag library is a collection of custom tags where each tag abstracts out some functionality used by a JSP page. Not only allows a more natural use of that functionality within JSP pages, but also it allows separation of responsibilities.

Source code for the tag library and a sample web application that illustrates the use of the tag library as well as the binaries are available here. Downloaded bundle also include documentation about the tag library that is generated using tlddoc.

Detailed Steps:
Given below are the detailed steps to develop the tag library as well as a sample application that uses the same. Although I am using glassfish in this article, the tag library and the sample are completely portable and can be used in any Java EE 5 compatible application server with a little modification to the accompanying build.xml.

Step #1: Write custom tags

A tag library is a collection of tags. Prior to JSP 2.0, custom tags could only be developed using Java language, but JSP 2.0 allows custom tags to be developed using an Expression Language. I am using Java to develop custom tags. The source code for the tags are in jpa-tag-lib/src directory in package com.sun.jpatl package. of all the tags, jpa:tx tag is TryCatchFinally kind of tag. It is written such that it always ends the transaction, in case of no exception in the embedded JSP fragment, it commits the tx, else it rolls back the tx. All other tags are Simple Tags.

Step #2: Write a tag library descriptor jpa.tld

A tag library descriptor is an XML document describing the tags that are part of the library. Refer to the JSP Spec fpr mode details. As you can see from the tld file, I have given the URI as http://weblogs.java.net/ss141213/tags/jpa.

The tag classes along with tag library descriptor file(jpa.tld) are packaged in a file called jpa-tag-lib.jar which is bundled in WEB-INF/lib dir of the web application.

Step #3: Write a sample web application that uses jpa-tag-lib

Let's write a simple web application that uses these tags to do some database operation. The functionality of this web application is same as the one described in my earlier blog.

Step #3.1: Write entity bean UserCredential.java

Step #3.2: Define a persistence unit persistence.xml

The entity classes along with persistence.xml are packaged in entities.jar which is bundled in WEB-INF/lib dir of the web application.

Step #3.3: Write login.jsp

Points worth noting about this JSP are:
1) It expresses its dependency on jpa-tag-lib by using the following directive:

<%@ taglib uri="http://weblogs.java.net/ss141213/tags/jpa" prefix="jpa" %>

2) It uses custom tag called jpa:injectDefaultPC to inject a container managed entity manager. This entity manager instance is made available in a variable called em1.

3) It uses custom tag jpa:find passing it the entity manager that was earlier injected. Also note how it uses a request time expression to pass the value of the primary key. The searched object is stored in a variable called credential which is later on used by the JSP to compare password.

Step #3.4: Write registration.jsp

Points worth noting about this JSP are:

1) It uses jsp:useBean to initialise a bean called credential by reading attributes passed in request object.

2) It uses custom tag jpa:tx to mark the boundary of a transaction. Inside this transaction, it uses uses custom tag jpa:persist to persist the java bean.

Step #3.5: Write a couple of html files called login.html and registration.html. Note, there is no need to write any web.xml as it is optional in Java EE 5.

Step #4: Build using build.xml

This is a very simple build.xml just to demonstrate the compilation and packaging process. The build targets are:
build-jpa-tag-lib -- builds only the tag library.
build -- builds the tag library build/jpa-tag-lib.jar as well as the sample web app build/web-app6.war. The war file bundles the tag-lib.
clean -- cleans
doc-jpa-tag-lib -- generates documentation for the tag library using a free open source tool called tlddoc. To run this optional target, you need to download the tool from here.
verify -- verify uses a tool called verifier that checks compliance of the application against Java EE spec.
deploy -- deploys the ear file
undeploy -- undeploys the ear file

The last three targets are specific to Sun Java System Application Server 9 PE which is implementing Java EE 5 spec.

As you can see, to compile the sources, only library needed is javaee.jar which contains the Java EE 5 platform APIs.

Step #5: Set up a data source

By default in glassfish entity manager uses the default pre-configured data source with JNDI name jdbc/__default that glassfish comes with. This data source talks to a Derby database called sun-appserv-samples. Refer to the README where I have listed the command needed to start and stop the Derby database. Glassfish has a feature called Java2DB which can autocreate the database schema during deployment, so there is no need to create tables.

Step #6: See them in action
Type http://localhost:8080/web-app6/login.html in the browser. Replace localhost & 8080 by host and port as appropriate in your env.

Want to help?

This is my first attempt to write a tag library, so comments are most welcome. I plan to enhance the tag library and make them available in future. I am even thinking of starting an open source effort to make a production quality tag library for Java Persistence API. Interested readers are welcome to join me in this effort.

References:

Java Server Pages
Tutorial on developing custom tags by Qusay H. Mahmoud
Tutorial on how to use Java Persistence API in a web application
Tutorial on how to use Java Persistence API in a 3 tier (web->ejb->db) Java EE 5 application
Tag Library Documentation Generator Tool: A free open source tool in java.net.

More articles about .



Don't use @PersistenceContext in a web app...

Posted by ss141213 on December 19, 2005 at 12:18 PM | Permalink | Comments (9)

I wrote an example web application that uses Java Persistence API. My servlet code looked like this:

public class RegistrationServlet extends HttpServlet {
// inject default EntityManager
@javax.persistence.PersistenceContext private EntityManager em;
@Resource private UserTransaction utx;
public void service ( HttpServletRequest req , HttpServletResponse resp)
throws ServletException, IOException {
...
utx.begin();
em.persist(credential);
utx.commit();
...
}
...
}

This code worked, but only by chance. I did not realize that I have committed a horrible mistake in my servlet code. As the servlet spec suggests, unless explicitly mentioned in the deployment descriptor (web.xml) as SingleThreadModel, a single servlet instance by default can be shared to serve multiple requests concurrently. i.e. multiple threads can simultaneously enter the service() method of our servlet because we have not marked the service() as synchronized. As a result multiple threads will share the same PersistenceContext object via the instance variable em. A persistence context is not required to be thread safe as per the spec and is typically designed not to be used concurrently. Because the behavior is timing dependent and I had a tiny example, I did not see this issue during testing.

What is the fix

If we can't use @PersistenceContext to inject an EntityManager, what is the fix? The fix is to either
use @PersistenceUnit to inject an EntityManagerFactory and use it to get hold of an EntityManager,
or
declare a dependency on an EntityManager and use JNDI to look it up.
The former one is called application managed entity manager because application manages the life cycle (by calling EntityManagerFactory.create & EntityManager.close) where as the later one is called container managed entity manager because container manages life cycle. More discussion on differences between container managed vs. application managed will be done in a later article. Let's discuss the fix using both the approaches. Let's discuss each approach using code samples.

Container Managed Entity Manager
There are a couple of ways to use JNDI lookup of entity manager:
a) via annotation:

@PersistenceContext(name="persistence/LogicalName", unitName="ActualPUNameAsItAppearsInPersistence.xml")
public class RegistrationServlet extends HttpServlet {
@Resource private UserTransaction utx;
public void service ( HttpServletRequest req , HttpServletResponse resp)
throws ServletException, IOException {
Context envCtx = InitialContext().lookup("java:comp/env");
EntityManager em = (EntityManager) envCtx.lookup("persistence/LogicalName");
...
utx.begin();
em.persist(credential);
utx.commit();
...
}
...
}

Note that there is no injection going on here since the annotation @PersistenceContext appears at the class level. This is an alternative to declaring the persistence context dependency via a persistence-context-ref in web.xml as discussed below (in option #b).

b) via persistence-context-ref in web.xml

In web.xml, add an element like this:

 < persistence-context-ref>
< persistence-context-ref-name>
persistence/LogicalName
</persistence-context-ref>
< persistence-unit-name>
ActualPUNameAsItAppearsInPersistence.xml
</persistence-unit-name>
</persistence-context-ref>

Now do a JNDI lookup in your code as shown below:

public class RegistrationServlet extends HttpServlet {
@Resource private UserTransaction utx;
public void service ( HttpServletRequest req , HttpServletResponse resp)
throws ServletException, IOException {
Context envCtx = InitialContext().lookup("java:comp/env");
EntityManager em = (EntityManager) envCtx.lookup("persistence/LogicalName");
...
utx.begin();
em.persist(credential);
utx.commit();
...
}
...
}

While using container managed entity manager (whether option #a or #b is used), we did not call em.close() because container is managing the life cycle of underlying persistence context. We also did not have to call utx.rollback() because web container would automatically rollback a transaction at the end of http request processing if servlet does not end the tx.

Application Managed Entity Manager

public class RegistrationServlet extends HttpServlet {
// inject EntityManagerfactory
@javax.persistence.PersistenceUnit private EntityManagerFactory emf;
@Resource private UserTransaction utx;
public void service ( HttpServletRequest req , HttpServletResponse resp)
throws ServletException, IOException {
EntityManager em = emf.createEntityManager();
try {
...
utx.begin();
em.persist(credential);
utx.commit();
...
} catch (Exception e){
try {
utx.rollback();
} catch (Exception e) {}
} finally {
em.close();
}
}
...
}

See we call close() to close the EntityManager. More over note the use of try catch finally block. Since em.close() can not be called as long as the associated transaction is complete either by calling commit() or rollback(), we have to write those try catch finally.

Is it mentioned any where in the spec?

In Transaction Management chapter, section #4.2.3 of Java EE 5 proposed final draft spec, it is mentioned that:

In web components not implementing SingleThreadModel, transactional resource
objects should not be stored in class instance fields, and should be acquired
and released within the same invocation of the service method.

If you want to draw an analogy with JDBC world then EntityManager is like a Connection, where as EntityManagerFactory is like a DataSource. So EntityManager (or a PersistenceContext) which is a transactional resource should not be stored in a instance field and hence should not be injecte into a web app that does not implement SingleThreadModel.EntityManagerFactory is thread safe, so it can be injected into the servlet.

What is the performance over head?

Creation of a EntityManagerFactory is typically a costly operation. But creation of EntityManager is not. So creating an EntityManager is inside service() does not have negative impact on performance.

What about thread safety of UserTransaction?

If you see the code above, it still injects a UserTransaction object and stores in an instance field. That is not issue because it is a stateless object and can be shared across multiple threads. Looking at the javadocs for UserTransaction, it is clear that it by itself does not represent the transaction object, instead it is an interface to the underlying transaction manager to begin a new transaction and associate that with current thread; and end a transaction associated with current thread.

More articles about .



Using Java Persistence API in Java EE Platform - Part II

Posted by ss141213 on December 15, 2005 at 08:59 AM | Permalink | Comments (17)

The Java Persistence API is the standard API for the management of persistence and object/relational mapping in Java EE 5 platform. Every Java EE 5 compatible application server will support this API. Earlier I had written about how to use Java Persistence API in a web application. This time I shall extend the example to include EJBs and application client so that we have a multi-tier (web->ejb->db and appclient->ejb->db) Java EE app. The focus of this exercise is to show how simple it is to develop such complex multi-tier Java EE application in a portable way. We will see how to package such an application so that it is not only portable, but also efficient. It uses the library directory facility to package common classes. In the process we shall see various injections like @EJB and @PersistenceContext in use. Like last time, I will not use any kind of IDE because Java EE 5 is Easy to Use. More over IDEs tend to do things behind the screen and that hampers learning. Because of the walkthrough nature of this article, it's to be a long one, but don't get overwhelmed by the size! At each critical step , I shall try to explain why certain things are done the way they are. If you are impatient, you can download the complete sample, unzip and run 'ant deploy' to see the sample in action. The actual steps are very simple as you can see from this README.

What is the example?
The ear file has three modules: viz: a web module, an ejb module and an appclient module. The web module has a login page and a new user registration page. They internally use two servlets. The servlets talk to the ejb which uses Java Persistence API to access user details that are stored in a database. The appclient module also talks to the ejb module. The complete sample is available here.

Software Requirements
An implementation of the Java Persistence API is being done in glassfish project. You can download the latest promoted build and try out the sample yourself. Although I am using glassfish to build and run this sample, atmost you have to do some very minor changes to persistence.xml and build.xml to make this app build and run in any other application server that supports Java EE 5 specification. This sample also uses a proprietary feature called Java2DB. But that does not make this a non-portable application as it uses vendor extension section of persistence.xml to do this.

Structure of the ear file :

The final ear looks like this:

lib/entities.jar
lib/ejb-interfaces.jar
ejbs.jar
web-app2.war
appclient.jar

Point to note here are:
1) There is no application.xml in this ear file, as in Java EE 5, application.xml has become optional.

2) For sake of clarity, entity beans are packaged in entities.jar and EJB interface classes are packaged in ejb-interfaces.jar. All other modules depend on these two jar files. So sharing them is a challenge.

3) It uses lib directory to share entities.jar and ejb-interfaces.jar with other modules. lib directory is a special directory introduced in Java EE 5. By default its name is lib, but it can be overridden by using application.xml. The intended use is to place library jar files in this directory so that they can be made available to all other modules in the ear file without having to use Class-Path manifest attribute as explained in Bundled Optional Package Support in Java EE 5 platform spec chapter #8. So our entities.jar and ejb-interfaces.jar are automatically available to ejbs.jar, web-app2.war and appclient.jar. This way there is no duplication of classes in the ear.

Since entities.jar is placed in lib directory, not only is it available to all other module's class loader, but also the Persistence Unit defined in this jar file is visible to all other modules.

4) ejbs.jar only contains the session bean classes. There is no ejb-jar.xml inside it. Also note that ejbs.jar does not bundle entities.jar, yet it uses the persistence unit which is defined in lib/entities.jar. This is allowed as per the sharing rules of persistence units.

5) web-app2.war contains the servlet classes and html files.

6) In addition to example.client.Main.class appclient.jar contains a META-INF/MANIFEST.MF file.


Detailed Steps

Step #1: Write entity bean UserCredential.java

Points to note about this entity bean are:
1) This is a Plain Old Java Object (POJO): It does not extend any predefined class, nor does it implement any particular interface other than java.io.Serializable. An entity bean must implement java.io.Serializable interface if it is used in RMI-IIOP (EJB) interface. Since in this example it is being used in the EJB interface, we have to do so.

2) There is no deployment descriptor needed to specify that it is an entity bean. Instead the class has been annotated as @Entity as shown below:

@Entity public class UserCredential implements Serializable.

The persistence provider automatically determines whether we are annotating FIELDs or PROPERTIEs. In this case, we have decided to annotate fields.

3) Every entity bean must have an identity. In our case, it is specified using @Id as below. I have chosen to use @Id because we have a single field primary key. Other annotations like @IdClass, @EmbeddedId are typcally used for composite primary key.

@Id private String name;

4) Also note that we have not used @GeneratedValue along with @Id. When an id field is not annotated with @GeneratedValue, it means that user is responsible for setting the identity. Provider will not set the id field value.

5) Although it is possible to specify exact table name using @Table and column names using @Column for an entity bean, we can rely on the default mapping that the specification defines and yet expect the application to be portable because this default mapping rule is defined by the spec itself. UserCredential bean gets mapped to a table called USERCREDENTIAL, name & password fields get mapped to NAME and PASSWORD columns respectively.

Step #2: Define a persistence unit in persistence.xml

A Persistence Unit (PU) is a logical grouping of a set of related entity beans. A PU also contains configuration details about the entity managers that are going to manage these entity beans. Actually the configuration is applied to an EntityManagerFactory which in turn creates homogeneous EntityManager instances. But this is all taken care of by the container to persistence provider interaction. As a user to define a PU, we just need to write a node in persistence.xml file. Points to note about this persistence.xml are:

1) One persistence.xml can be used to define multiple PUs, but in this case we have defined only one PU by name pu1.

2) We need not specify any other elements/attributes, as the default values are just fine for most applications. e.g. by default the entity manager's transaction type is JTA.

3) There is no need to enumerate all the entity bean class names inside because we are defining only one PU in this persistence.xml and we will be packaging the entity classes along with this persistence.xml in a jar file, so container can discover all the entity beans.

Step #3: Write UserCredentialManagerBean.java

Points to note about this EJB 3 style stateless session bean are:
1) It is a Plain Old Java Object (POJO): It does not extend any predefined class, nor does it implement any predefined interface. It only implements its own business interface UserCredentialManager.

2) There is no deployment descriptor needed to specify that it is a stateless session bean. Instead the class has been annotated as shown below:

@Stateless @Remote

public class UserCredentialManagerBean implements UserCredentialManager {...

@Remote annotation is required b'cos the business interface UserCredentialManager is neither annotated as @Local nor as @Remote. So by default our session bean would have exposed a local business interface. Since we want the EJB to be accessible from an application client, having only local interface would not work. So we are using @Remote annotation. The other option would have been to have both local and remote interface, but let's postpone that discussion to some other time.

3) It talks to database using EntityManager API. It declares dependency on an EntityManager using @PersistenceContext annotation:

@PersistenceContext private EntityManager em;

Since there is only one Persistence Unit(PU) defined in the scope of this ejb, there is no need to specify the unitName in @PersistenceContext. Please also note that an injected variable in a servlet or ejb must not be declared static or final. In our example, em follows this rule as well.

4) The business method "createUser" creates a new object in the database by one line code:

em.persist(uc);

The business method "authenticate" uses the following code:

UserCredential uc = em.find(UserCredential.class, name);

to locates a matching UserCredential object in the database.

The business method "removeUser" first locates the named user credential and then calls

em.remove(uc);

to remove it from the database.

Unlike em.find(), em.remove() and em.persist() require an active transaction context. But as you can see none of the EJB methods starts a transaction. That is because by default the transaction management type is CONTAINER and the transaction attribute of business method is REQUIRED. So ejb container takes care of transaction management! This is unlike web container as discussed here.

There is no need to write an ejb-jar.xml because a Java EE 5 compatible container can identify ejbs.jar as an EJB module because it contains a class that is annotated as Stateless.

Step #4: Write LoginServlet.java

Points to note about this servlet are:
1) It declares dependency on the EJB using @EJB annotation:

@EJB private UserCredentialManager ucm;

Since there is only one bean that implements this business interface, there is no need to specify any of the attributes of @EJB.

2) When user tries to login using a user name and password, it calls the EJB method to authenticate as shown below:

ucm.authenticate(name, password);

Step #5: Write RegistrationServlet.java

Note it also uses an injected EJB. It also calls the createUser EJB method to create a new user.

Both the servlets do not do any transaction management, because that is handled by the EJB layer. They also do not explicitly depend on the Java Persistence API.

Step #6: Write web.xml

We are having to write an web.xml only because we have to define a couple of request path mappings to servlets.

Step #7: Write a couple of html files
Refer to login.html and registration.html inside the sample zip file. They are used to call the servlets.

Step #8: Write an appclient Main.java

Points to note about this appclient are that:

1) It declares dependency on the EJB using @EJB as shown below:

@EJB private static UserCredentialManager ucm;

Also note that, the field ucm is static. That's because unlike EJB or Servlets, injected fields in an application client must be static as Application Client Container (ACC) does not instantiate the class, instead it calls the static main().

Since in this ear file, there is only one session bean that implements UserCredentialManager interface, there is no need to specify any other attributes of the EJB.

2) It must be a public class because it will be used by ACC which does not belong to the package of this class.

3) We also need to write a manifest.mf file which must contain the name of the class containing the main() so that ACC knows which is the main class to look for injected fields and main(). Thsi file gets bundled in appclient.jar as META-INF/MANIFEST.MF file.

There is no need to write application-client.xml because it is optional. Java EE 5 compatible platform can discover appclient.jar's module type because it contains META-INF/MANIFEST.MF with a Main-Class attribute.

Step #9: Build using build.xml

This is a very simple build.xml just to demonstrate the compilation and packaging process.
The build targets are:
build -- This builds an ear file called blog5.ear.
clean -- cleans
verify -- verify uses a tool called verifier that checks compliance of the application against Java EE spec.
deploy -- deploys the ear file
undeploy -- undeploys the ear file
The last three targets are specific to Sun Java System Application Server 9 PE which is implementing Java EE 5 spec.

As you can see, to compile the sources, only library needed is javaee.jar which contains the Java EE 5 platform APIs.

The deploy target in build.xml uses a feature called Java2DB which can automatically create the tables during deployment. This is specific to Sun's app server, but such features are supported in many other commercial applications servers as well.

Hope you found this example useful.

More blogs about



An annotation processor to update your persistence.xml during javac

Posted by ss141213 on December 13, 2005 at 02:44 PM | Permalink | Comments (1)

When Java Persistence API is used in a managed environment (like Java EE container), there is often a deployment step and a notion of deployable module (an ear/war/jar) that represents the boundary of an application. During deployment container/persistence provider can discover managed persistence classes by introspecting .class files bundled in the application. But when Java Persistence API is used in Java SE environment, there is no such predefined deployment step, nor is there any deployable module. So a persistence provider does not know what are all the classes to introspect. Hence the spec requires users to specify the list of managed persistence classes in persistence.xml. A managed persistence class is a class that is either an Entity or Embeddable or EmbeddableSuperclass.

In this article, I shall show how to write an Annotation Processor that can be used along with J2SE's Annotation Processing Tool to automatically generate the list of managed persistence classes and update persistence.xml during compilation of entity source code. In the process I will also show how to use JAXB to read and write XML. I suggest you read this if you are not familiar with apt. The complete source code along with a build script is available here. There is also a README that tells you how to build and use the tool.

Overview of the source code:

1. AnnotationProcessorFactory: ListPersistenceClassApf.java

This is the entry point. It implements AnnotationProcessorFactory interface.

2. AnnotationProcessor: ListPersistenceClassAp.java
This is the real annotation processor. It implements AnnotationProcessor interface. ListPersistenceClassApf instantiates this class and hands over the declarations for annotation processing.

3. service provider configuration file: META-INF/services/com.sun.mirror.apt.AnnotationProcessorFactory

apt is a generic tool that comes with Sun's JDK. It does not know about our custom annotation processor factory. So it has to be told about our annotation processor factory. It can be done in a couple of ways: passing -factory option while invoking apt or by using service provider configuration file. I am using the later approach.

4. Marshalling and unmarshalling of persistence.xml XMLReaderWriter.java

As you can see from this source code, I am using JAXB 2.0 RI to read and write persistence.xml. The reason I use JAXB is because it generates the code that is responsible for reading and writing XML from a given schema. See the gen-src target in build.xml to see how we generate code using JAXB. Also take a look at the binding.xjb
if you are interested to know how to control code generation.

How to build?
Download latest build of glassfish from here.
set glassfish.home in build.xml and run 'ant build'.

The reason I use glassfish is because it implements Java EE 5 spec, which means both Java Persistence API 1.0 as well as JAXB 2.0.

How to use?
export GLASSFISH_HOME="Wherever you have installed glassfish"
apt -d samples/classes/ -classpath $GLASSFISH_HOME/lib/javaee.jar:$GLASSFISH_HOME/lib/appserv-ws.jar:`pwd`/build/apt.jar -Add=samples/persistence.xml samples/src/sahoo/*.java

See the above command is invoked just like you invoke javac to compile a set of java sources available in samples/src/sahoo/ dir and you directing the compiler to produce the classes in samples/classes dir.
In fact it does what ever javac does + more.
The only non-javac option used here is -Add which is used by our
annotation processor to know the input persistence.xml file location.

The above command picks up Java sources from samples/src dir and
persistence.xml from samples dir. It produces the new persistence.xml
in samples/classes/META-INF dir. It produces the classes in samples/build
directory.

Continue Reading...



Why do I not have to use .par file to bundle my EJB 3.0 entity beans?

Posted by ss141213 on December 06, 2005 at 11:38 PM | Permalink | Comments (7)

Public Review version of the Java Persistence API (JPA) spec suggested a new extension par be used to bundle EJB 3 persistence entity beans. It also suggested a new module type called persistence to be used in application.xml, if user uses an application.xml in their ear file containing persistence entity beans. (Note application.xml is optional starting with Java EE 5.)

Lot of developers still believe that .par is needed. Looking at the comments in theserverside.com to an earlier posted tutorial showing how to use JPA in web application it is very clear that user community do not want a proliferation of extensions used in Java EE platform. Here is a good news:
.par is not needed any more -- take a look at latest XML schema of application.xml posted in project glassfish web site. There is no mention of persistence module type.

Here is a simple convention (rule you may say) followed in Java EE platform from early days:
Any jar-format file that packages classes that can be directly loaded by a class loader ends with a .jar extension. e.g. jar files containing EJB classes, application client classes, utility classes all end with .jar extension (not even .zip). This is precisely why, bundled optional libraries must only be .jar files as mentioned in chapter #8 of the Java EE 5 platform spec available here .

As you can see .ear, .war and .rar do not fall into this category, as they do not package classes directly inside them which are used by a standard class loader. Note that although .war sometimes directly contains classes that are used by an applet, but the applet container is not given the .war file, instead it downloads the classes from the web server.

I must say having this convention prevented introduction of .par file and it is a relief. This kind of convention is also getting into Java SE, because I have heard in Java SE 6 (mustang) there is going to be a facility to specify a directory in the CLASSPATH environment variable and VM will look for all *.jar files in that directory and add it to CLASSPATH automatically.

So if you want to write portable applications, stick to these principles. Sun's next version of application server which is being develped in open sorce project named glassfish does not require any such extensions like .ejb3 or .par.

As a result of this not requiring .par files, the most notable simplification is:
You don't always need an .ear file to use EJB 3 persistece entity beans in Java EE platform. You can bundle them in .war files and deploy .war directly if you are developing such an app. e.g. see tutorial showing how to use JPA in web application. You could even take such a war file and use it in a Java web server, if that supports JPA. You can bundle the entity classes along with ejb classes in an ejb-jar and deploy the ejb-jar directly.


Similarly many developers think EJB 3 session beans have to be packaged in a jar file with extension .ejb3. Let me tell you, that was JBoss specific. I am not up-to-date with recent developments in JBoss, so not sure if they still require this and what are their plans.

Continue Reading...



EntityManager.persist() throws TransactionRequiredException in a servlet?

Posted by ss141213 on December 05, 2005 at 09:37 AM | Permalink | Comments (3)

In my last blog I discussed about using Java Persistence API in a web application. In this article I shall talk about a very common mistake that a web-app developer commits and how to fix it. Java Persistence API is part of Java EE 5 platform which is being reference implemented in open source project called glassfish.

Code that does not work:
Given below is the code snippet of a servlet which uses an entity bean called UserCredential using a container managed EntityManager.

public class RegistrationServlet extends HttpServlet {
// This injects the default persistence unit.
@PersistenceUnit private EntityManagerFactory emf;
public void service (HttpServletRequest req , HttpServletResponse resp)
throws ServletException, IOException {
try {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
...
String name = req.getParameter("name");
String password = req.getParameter("password");
UserCredential credential = new UserCredential(name, password);
EntityManager em = emf.getEntityManager(); // container managed em
// em.persist makes the new object as persistent and managed.
em.persist(credential);
out.println("Successfully created the new user. ");
} catch (Exception nse) {
throw new ServletException(nse);
}
}
// other servlet methods like init etc. are omitted for bravity.
}

Exception Details:
When the service() method gets executed, this servlet gets the following exception:
javax.persistence.TransactionRequiredException:
Exception Description: Error marking externally managed transaction for rollback

Why this exception occurs?
If you refer to persist() method in EntityManager.java you can see the javadocs clearly mention that persist throws javax.persistence.TransactionRequiredException if there is no transaction. Since we did not start a transaction in the service() method in servlet before calling em.persist(), the servlet got the exception.

What is the fix?
To fix this, update the servlet code as given below (new code is in bold face letter):

public class RegistrationServlet extends HttpServlet {
// This injects the default persistence unit.
@PersistenceContext private EntityManagerFactory emf;
// This injects a user transaction object.
@Resource private UserTransaction utx;
public void service (HttpServletRequest req , HttpServletResponse resp)
throws ServletException, IOException {
try {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
...
String name = req.getParameter("name");
String password = req.getParameter("password");
// we must begin a tx.
utx.begin();
UserCredential credential = new UserCredential(name, password);
EntityManager em = emf.getEntityManager(); // container managed em
// em.persist makes the new object as persistent and managed.
em.persist(credential);
// commit the transaction,
// b'cos web container rollbacks unfinished tx at the end of request
utx.commit();
out.println("Successfully created the new user. ");
} catch (Exception nse) {
throw new ServletException(nse);
}
}
// other servlet methods like init etc. are omitted for bravity.
}

Comparison with equivalent code in a Session Bean
Let's compare the difference in behavior between a servlet and an ejb.
Given below is a stateless session bean that has a business interface called PasswordManager which has a method of type "void createNewUser(String, String)".

@Stateless
class PasswordManagerBean implements PasswordManager {
@PersistenceContext private EntityManager em;
public void createNewUser(String name, String password) {
UserCredential credential = new UserCredential(name, password);
// em.persist makes the new object as persistent and managed.
em.persist(credential);
}
}

Let's analyse the differences between ejb and servlet code:
Of course ejb code does not have the HttpResponse related code. The other significant difference is that ejb uses @PersistenceContext to get hold of an EntityManager where as the servlet uses @PersistenceUnit to get hold of an EntityManagerFactory and then calls getEntityManager() on the injected EntityManagerFactory to get hold of an EntityManager. The reason why the servlet does not use @persistenceContext is discussed here. That's not the point I am trying to make here. See that the entity creation code and EntityManager interaction code is exacty same as it was in the original servlet code. Yet the servlet gets the exception where as the ejb works. You are wondering why?
For the EJB, default transaction management type is CONTAINER and default transaction attribute for a business method is REQUIRED. So even though we did not specify transaction attributes in our bean class, defaults took over. So even if the business method does not start a transaction, the EJB container starts a transaction if the business method is called in null transaction context and ends it at the end of business method. Hence em.persist() works. For servlet, web container does not implicitly starts a transaction. The web container is only required to roll back a transaction if service() method leaves behind an unfinished transaction.
Hope this helped!
Technorati Tags:
More blogs about glassfish.



Introduction to using Java Persistence API in a web application in Java EE environment

Posted by ss141213 on December 04, 2005 at 03:29 PM | Permalink | Comments (27)

The Java Persistence API is the standard API for the management of persistence and object/relational mapping in Java EE 5 platform. Every Java EE 5 compatible application server will support this API. In this entry I will show how to use this API from a web application in Java EE environment.
Since the public review version of Java Persistence API specification, there have been a number of significant changes about packaging of applications that use Java Persistence API. So I will also show how to package such an application in a portable way. In this exercise, I will not use any kind of IDE because I don't want any magic! This article is going to be a long one because I am trying to explain the steps in detail as well as why certain things are done the way they are. But the steps are very simple as you can see from the README.

What is the example?
It's a web application which has a login page and a new user registration page. It talks to a database where user details are stored. The complete sample is available here. There is a README inside that zip file as well.

Requirements
The Reference Implementation(RI) of the Java Persistence API is being done in glassfish project. You can download the latest promoted build and try out the sample yourself.
Although I am using the RI to build and run this sample, atmost you have to do some very minor changes to persistence.xml and build.xml to make this app build and run in any other application server that supports Java EE 5 specification.

Detailed Steps

Step #1: Write entity bean UserCredential.java

Points to note about this entity bean are:
1) This is a Plain Old Java Object (POJO): It does not extend any predefined class, nor does it implement any particular interface other than java.io.Serializable. An entity bean must implement java.io.Serializable interface if it is used in RMI-IIOP interface. Since in this example, RMI-IIOP is not used, technically this bean does not have to implement this interface. Never-the-less it is a good idea to make an entity bean RMI-IIOP ready, so I have done so.

2) There is no deployment descriptor needed to specify that it is an entity bean. Instead the class has been annotated as @Entity as shown below:

@Entity
public class UserCredential implements java.io.Serializable
.

The persistence provider automatically determines whether we are annotating FIELDs or PROPERTIEs. In this case, we have decided to annotate fields.

3) Every entity bean must have an identity. In our case, it is specified using @Id as below:

@Id private String name;

I have chosen to use @Id because we have a single field primary key. Other annotations like @IdClass, @EmbeddedId are typcally used for composite primary key.

4) Also note that we have not used @GeneratedValue along with @Id. When an id field is not annotated with @GeneratedValue, it means that user is responsible for setting the identity. Provider will not set the id field.

5) Although it is possible to specify exact table name and column names for the entity bean, we can rely on the default mapping that the specification defines. Because of the default mapping rules, UserCredential bean gets mapped to a table called USERCREDENTIAL, name & password fiels get mapped to NAME and PASSWORD columns respectively.

Step #2: Define a persistence unit

A Persistence Unit (PU) is a logical grouping of a set of related entity beans. A PU also contains configuration details about the entity managers that are going to manage these entity beans. Actually the ocnfiguration is applied to an EntityManagerFactory which in turn creates homogenious entity manager instances. To define a PU we need to write a node in persistence.xml file. Points to note about this persistence.xml are:

1) One persistence.xml can be used to define multiple PUs, but in this case we have defined only one PU by name em1.

2) We need not specify any other elements/attributes, as the default values are just fine for most applications. e.g. by default the entity manager's transaction type is JTA.

3) There is no need to enumerate all the entity bean class names inside because we are defining only one PU in this persistence.xml and we will be packaging the entity classes along with this persistence.xml in a jar file, so container can discover all the entity beans.

Step #3: Write LoginServlet.java

Points to note about this servlet are:
1) It talks to database using EntityManager API. It declares dependency on an EntityManagerFactory using @PersistenceUnit annotation:

@PersistenceUnit private EntityManagerFactory emf;

Since there is only one Persistence Unit(PU) defined in the scope of the web-app, there is no need to specify the unitName in @PersistenceUnit. Please also note that an injected variable in a servlet or ejb must not be declared static or final. In our example, emf follows this rule as well.

2) Also note that the servlet does not have an instance field of type EntityManager. This is because EntityManager is not thread safe. Since this servlet is not denoted as a SingleThreadModel servlet, one instance of servlet gets shared by mutiple clients and service method of servlet can be called by multiple threads concurrently. So we can't directly inject an EntityManager. Instead we inject an EntityManagerFactory which is thread safe.

3) In the service(), we create an EntityManager using the following code:

EntityManager em = emf.createEntityManager();

We also close the EntityManager in the finally block.

4) When user tries to login using a user name and password, it uses

UserCredential credential = em.find(UserCredential.class, name);

to find a matching UserCredential entity in the database.

5) Since EntityManager.find does not require a transaction to be started, the servlet does not have to begin a transaction before calling em.find().

Step #4: Write RegistrationServlet.java

Note:
1) It uses an injected EntityManagerFactory.

2) It uses

EntityManager.persist()

to create a new entity in the in the database .

3) Since EntityManager.persist() needs to be called in the context of a transaction, this servlet begins a transaction by calling

utx.begin()

and commits the tx before returning.

4) Also note that it uses an injected UserTransaction object as follows:

@Resource private UserTransaction utx;

Unlike EntityManager, UserTransaction is thread safe, so it is OK to inject it into a servlet.

5) Also see how we ensure that when we close the EntityManager there is no active transaction context, otherwise EntityManager.close() will throw an exception.

Step #5: Write web.xml

We are having to write an web.xml only because we have to define a couple of request path mappings to servlets.

Step #6: Write a couple of html files
Refer to login.html and registration.html inside the sample zip file. They are used to call the servlets.

Step #7: Build using build.xml

This is a very simple build.xml just to demonstrate the compilation and packaging process.
The build targets are:
build -- This builds the war file.
clean -- cleans
verify -- verify uses a tool called verifier that checks compliance of the application against Java EE spec.
deploy -- deploys the war file
undeploy -- undeploys the war file
The last three targets are specific to Java EE 5 Reference Implementation (a.k.a. Sun Java System Application Server 9 PE).

As you can see, to compile only library needed is javaee.jar which contains the Java EE 5 platform APIs.
Packaging is done in two steps:

a) build-entities target which compiles only entity beans, copies persistence.xml to output directory and make a jar file called entities.jar. See entities.jar contains persistence.xml in META-INF dir. This jar file is used during compilation of servlets. More over this is also bundled inside the war file's WEB-INF/lib directory.

b) build-web-app1 target which compiles the servlets, copies web.xml and html files to output directories amd makes a war file called web-app1.war. A few points worth noting here are:
in addition to javaee.jar, entities.jar is also used while compiling the servlets.
servlet classes are bundled in WEB-INF/classes directory.
entities.jar is bundled inside WEB-INF/lib directory

Another packaging option is to package META-INF/persistence.xml and entity classes in WEB-INF/classes. But I just feel having a separate jar file with entities in it keeps things clean. It improves reusability.

Step #8