By deploying Kodo into a J2EE environment, you can maintain the simplicity and performance of Kodo, while leveraging J2EE technologies such as container managed transactions (JTA/JTS), enterprise objects with remote invocation (EJB), and managed deployment of multi-tiered applications via an application server. This tutorial will demonstrate how to deploy Kodo-based J2EE applications and showcase some basic enterprise JDO design techniques. The tutorial's sample application attempts to model a basic garage catalog system. While the application is relatively trivial, the code has been constructed to illustrate simple patterns and solutions to common problems when using Kodo in an enterprise environment.
This tutorial assumes that you have installed Kodo and setup your classpath according to the installation instructions appropriate for your platform. In addition, this tutorial requires that you have installed and configured a J2EE-compliant application server, such as JBoss, WebSphere, WebLogic, Borland Enterprise Server, JRun, or SunONE / Sun JES. If you use a different application server, this tutorial may be adaptable to your application server with small changes; refer to your application server's documentation for any specific classpath and deployment descriptor requirements.
This tutorial assumes a reasonable level of experience with Kodo and JDO. We provide a number of other tutorials for basic Kodo and JDO concepts, including enhancement, schema mapping, and configuration. This tutorial also assumes a basic level of experience with J2EE components, including EJB, JNDI, JSP, and EAR/WAR/JAR packaging. Sun and/or your application server company may provide tutorials to get familiar with these components.
In addition, this tutorial uses Ant to build the deployment archives. While this is the preferred way of building a deployment of the tutorial, one can easily build the appropriate JAR, WAR, and EAR files by hand, although that is outside the scope of this document.
Every application server has a different installation process for installing J2EE components. Kodo can be installed in a number of ways, each of which may or may not be appropriate to your application server. While this document focuses mainly upon using Kodo as a JCA resource, there are other ways to use Kodo in a J2EE environment.
				JCA:  Kodo implements the 
				JCA 1.0 spec, and the kodo-jdo.rar file that comes in the 
				jca directory of the distribution can be 
				installed as any other JCA connection resource.  This is the 
				preferred way to integrate Kodo into a J2EE 
				environment.  It allows for simple installation 
				(usually involving uploading or copying kodo-jdo.rar 
				into the application server), guided configuration 
				on many appservers, as well as dynamic reloading 
				for upgrading Kodo to a newer version.  The drawback 
				is that older application servers have flaky or non-
				existent JCA support as the spec is relatively new.
				
				PersistenceManagerFactoryImpl: This 
				remains the most compatible way to integrate Kodo 
				into a J2EE environment, though this is not seamless 
				and can require a fair bit of custom application server 
				code to manually bind an instance of 
				PersistenceManagerFactoryImpl into the 
				JNDI tree.  This is somewhat offset by avoiding JCA 
				configuration issues as well as being able to tailor the 
				binding and start-up process.
				
Section 8.1.4, “Kodo JDO JCA Deployment” goes over the steps to install Kodo on your application server of choice via the Java Connector Architecture (JCA). If your application server does not support JCA, see Section 8.1.5, “Non-JCA Application Server Deployment” and Section 8.1.1, “Standalone Deployment” for other installation options.
Installing the sample application involves first compiling and building a deployment archive (.ear) file. This file then needs to be deployed into your application server.
			Navigate to the samples/jdo/j2ee directory 
			of your Kodo installation.  Compile the source files in place 
			both in this base directory as well as the nested 
			ejb directory:
			
javac *.java ejb/*.java
Enhance the Car class.
kodoc -p jdo.properties package.jdo
			Run the mapping tool; make sure that your 
			META-INF/jdo.properties file includes the 
			same connection information (e.g. Driver, URL, etc.) as your 
			installation:
			
mappingtool -p jdo.properties package.jdo
			Configure options in samples.properties 
			to match your JCA installation, most notably the JNDI 
			name to which you have bound Kodo (it defaults to kodo).
			
![]()  | Warning | 
|---|---|
				This step (editing  
				Be sure that the setting you put for
				 
				JBoss, for example, will prefix
				the JNDI name with   | 
			Build an J2EE application archive by running Ant against the 
			build.xml.  This will create 
			samplej2ee.ear.  This ear can now be 
			deployed to your appserver.
			
ant -f build.xml
			Place the ear file in the deploy 
			directory of your JBoss installation.  You can use the 
			above hints to view the JNDI tree to see if 
			samples.jdo.j2ee.ejb.CarHome was 
			deployed to JNDI.
			
			Place the ear file in the applications
			directory of your WebLogic domain.  Production mode (see your 
			startWebLogic.sh/cmd file) should be set to false to enable 
			auto-deployment.  If the application was installed correctly, 
			you should see sample-ejb listed 
			in the Deployments/EJB section of the admin console.  
			In addition you should find CarHome listed in 
			the JNDI tree under 
			myserver->samples->j2ee->ejb
			.
			
			Create a new directory named samplej2ee.ear
			in the applications directory of
			your WebLogic domain.  Extract the EAR file (without copying
			the EAR file) to this new directory:
			
applications> mkdir samplej2ee.ear applications> cd samplej2ee.ear samplej2ee.ear> jar -xvf /path/to/samplej2ee.ear
			Deploy the application by using the admin console
			(Deployments -> Applications -> Deploy a new Application.
			Select samplej2ee.ear and deploy
			to the proper server targets.  If you have installed the
			application correctly, you should find CarHome
			listed in the JNDI tree under
			myserver->samples->j2ee->ejb
			.
			
			Browse to the admin console in your web browser. Select 
			Applications/ Enterprise Applications
			 from the left navigation panel.  Select 
			Deploy...  and in the 
			following screen upload the samplej2ee.ear 
			file to the server.  Apply your changes by selecting the 
			link in the upper right portion of the page.  You should 
			now see samplej2ee listed 
			in the Enterprise Applications folder of the navigation panel.
			
			Browse to the admin console in your web browser. Select 
			J2EE Components
			 from the left navigation panel.  Select 
			Add under the
			Enterprise Applications
			heading. Select the samplej2ee.ear 
			file and hit Deploy.
			You should now see Sample-KodoJ2EE
			listed in the top-level folder of the navigation panel.
			Select it, and then select the
			sample-ejb.jar#CarEJB
			component under
			Enterprise JavaBeans
			section, then change the JNDI Name
			for the bean from the default value to
			samples.jdo.j2ee.ejb.CarHome and 
			hit Apply.
			
			If the Kodo resource adapter and the sample EAR are both
			configured correctly, you should now be able to access
			your sample application at JRun's deploy URL (e.g.,
			http://localhost:8100/sample/).
			
			Browse to the admin console in your web browser.  Select 
			Applications / Install New Application
			 from the left navigation panel.  Select 
			the path to your samplej2ee.ear file 
			and press Next.
			
			On the following screen, leave the options at the default 
			and select Next.  On the following
			screen (Install New Application->Step 1
			), ensure that the Deploy EJBs
			 option is checked.  Leave other options at their 
			defaults.
			
			Move on to Step 2.  On this screen enter 
			samples.jdo.j2ee.ejb.CarHome as the JNDI name for the 
			Car EJB.  Continue through the 
			remaining steps leaving options at the defaults.  Select 
			Finish and ensure that 
			the application is deployed correctly.
			
			Save the changes to the domain configuration by either 
			selecting the Save link 
			that appears after the installation is complete or by 
			selecting Save from the top menu.
			
			To verify your installation, select Applications 
			/ Enterprise Applications from the left 
			navigation panel.  Sample-KodoJ2EE 
			should be listed in the list.  If the application has not 
			started already, select the checkbox next to 
			Sample-KodoJ2EE
			and select Start.  
			
			Deploy the EAR file using iastool or the console.  Note
			that you may have to include the JDO library in your
			stub generation process.  Also be sure that you have 
			followed the JCA instructions for
			BES as well as editing the samples.properties to
			point to serial://kodo JNDI location.
			You should be able to see the CarEJB located in JNDI
			located at the home classname.
			
		The sample application installs itself into the web layer at the 
		context root of sample.  By browsing to 
		http://yourserver:yourport/sample
		, you should be presented with a simple 
		list page with no cars.  You can edit, add, delete car instances.
		In addition, you can query on the underlying Car
		PersistenceCapable instance by 
		passing in a JDOQL query into the marked form (such as
		model=="Some Model").
		
The garage application is a simple enterprise application that demonstrates some of the basic concepts necessary when using Kodo in the enterprise layer.
The core model wraps a stateless session bean facade around a persistence capable instance. Using a session bean provides both a remote interface for various clients as well as providing a transactional context in which to work (and thus avoiding any explicit transactional code).
		This session bean uses the Data Transfer Object pattern
		to provide the primary communication between the
		application server and the (remote) client. The Car
		 instance will be used as the primary object upon
		which the client will work.
		
		This model can be easily adapted to using entity beans.  
		See our sample ejb directory and 
		JDOEntityBean 
		for more details on how to using JDO to power your entity beans.
		
				samples/jdo/j2ee/Car.java:
				The core of the sample application.  This is the 
				persistence capable class that Kodo will use to persist the 
				application data.  
				Instances of this class will also fill the role of 
				data transfer object (DTO) for EJB clients.  
				To accomplish this, Car implements 
				java.io.Serializable 
				so that remote clients can access cars as parameters
				and return values from the EJB.
				
				samples/jdo/j2ee/package.jdo:
				The JDO metadata file for the package.
				Note that some appservers have a problem with the
				way we include an internal DTD.  If you see a lot
				of illegal/malformed character exceptions, uncomment
				out the DTD declaration in this file.
				
				samples/jdo/j2ee/SampleUtilities.java:
				This is a simple facade to aggregate some core 
				JDO functionality into some static methods.  
				By placing all of the functionality into a single 
				facade class, we can reduce code maintenance, as 
				well as having the added advantage of being able 
				to access Kodo from other portions of the 
				application such as a servlet or JSP (though this 
				functionality is not demonstrated in this sample).  
				In addition, some simple utility functions such as 
				JNDI helper methods are also in this class.
				
				samples/jdo/j2ee/ejb/Car*.java:
				The source for the CarEJB session bean.  
				Clients can use the CarHome 
				and CarRemote interfaces to 
				find, manipulate, and persist changes to 
				Car transfer object 
				instances.  By using J2EE transactional features,
				the implementation code in CarBean.java 
				can be focused almost entirely upon business and 
				persistence logic without worrying about transactions. 
				
				samples/jdo/j2ee/jsp/*.jsp:
				The web presentation client.  These JSPs are not aware of JDO;
				they simply use the CarEJB session 
				bean and the Car transfer object to do 
				all the work.
				
				samples/jdo/j2ee/resources/*:
				Files required to deploy to the various appservers, 
				including J2EE deployment descriptors, WAR/ EJB/ EAR 
				descriptors, as well as appserver specific files.
				
				samples/jdo/j2ee/build.xml:
				A simple Ant build file to help in creating a J2EE EAR file.
				
				samples/jdo/j2ee/samples.properties:
				A simple .properties file to tailor the 
				sample application to your particular appserver and 
				installation.
				
				Persistence capable instances are excellent 
				candidates for the Data Transfer Object Pattern.   
				This pattern attempts to reduce network load, as well 
				as group business logic into concise units.  
				For example, CarBean.edit allows you 
				to ensure that all values are correct before committing a 
				transaction, instead of sequentially calling getters and 
				setters on the session facade.  This is especially true when 
				using RMI such as from a Swing based application 
				connecting to an application server.
				
				CarEJB works as a session bean facade 
				to demarcate transactions, provide finder methods, and 
				encapsulate complex business logic at the server level.
				
				Persistent instances using datastore identity 
				lose all identity upon serialization (which happens 
				when they are returned from an EJB method).  While 
				there are numerous ways to solve this problem, the 
				sample uses the clientId field of 
				Car to store the stringified 
				datastore id.  Note that this field is 
				not persistent.  This field ensures 
				that the client and EJB always share the same 
				identity for a given car instance.
				
![]()  | Note | 
|---|---|
Note that this situation is slightly different for application identity. While persistent instances under application-identity still lose their id instance, recreating it from the server side is trivial as the fields on which it is based are still available.  | 
Other ways of solving this problem include:
Transmitting the object id first or otherwise storing identity with the client:
Object oid = dogRemote.findByQuery ("// some query");
Dog dog = dogRemote.getDogForOid (oid);
// changes happen to dog
dogRemote.save (oid, dog);
Wrapper objects that store the persistent instance, object id instance, as well as potentially other application-specific data:
public class DogTransferObject
{
    private Dog dog;
    private Object oid;
    private String authentication; // some application specific client data
}
				PersistenceManager.close 
				should be called at the end of every EJB method.  
				In addition to ensuring that your code will not attempt to 
				access a closed PersistenceManager, it 
				allows the JDO implementation to free up unused resources.
				Since a PersistenceManager is created 
				for every transaction, this can increase the scalability
				of your application.
				
				You should not use 
				PersistenceManager.currentTransaction or any 
				javax.jdo.Transaction methods.  
				Instead, use the JTA transactional API.
				SampleUtilities includes a helper method 
				to obtain a UserTransaction instance 
				from JNDI (see your application server's documentation on
				the proper JNDI lookup).
				
While serialization of PC instances is relatively straightforward, there are several things to keep in mind:
						Collections and iterators returned from 
						Query 
						instances become closed and inaccessible upon method 
						close.  If the client is receiving the results of a 
						Query, such as in 
						CarBean.query, the results 
						should be transferred to 
						another fresh collection instance before being returned
						from the server.
						
						While "default fetch group" values will always be 
						returned to the client upon serialization, lazily 
						loaded fields will not as the 
						PersistenceManager will 
						have been closed before those fields attempt to 
						serialize.  One can either simply access those fields 
						before serialization, or one can use the persistence
						mangaer's retrieve and 
						retrieveAll methods to make
						sure object state is loaded. Note that these methods 
						are not recursive.  If you need to go through multiple 
						relations, you must call retrieve
						 at each relational depth.  This is an 
						intentional limitation in the specification to prevent 
						the entire object graph from being serialized and/or 
						retrieved.
						
				It is not necessarily required that you use EJBs and 
				container-managed transactions to demarcate transactions, 
				although that is probably the most common method.  
				In EJBs using bean managed transactions, you can control
				transactions through either the javax.jdo.Transaction
				 or the
				javax.transaction.UserTransaction.
				Furthermore, outside of EJBs you can access the JDO layer with 
				either transactional API.
				
				The Kodo distribution includes source code for some convenient 
				base classes that encapsulate much of the code that is 
				laid out in this example for clarity.  
				JDOBean, JDOSessionBean,
				and JDOEntityBean include most of the 
				functionality of SampleUtilities, and
				handle common EJB interface methods such as 
				setEntityContext.  To use these 
				classes, we recommend placing Kodo's jars into the system 
				classpath and not into the ear.  Ear deployment can cause 
				classloader problems due to the multiple locations that these 
				classes could be loaded from.
				
				PersistenceManagers are allocated on a 
				per-Transaction basis. 
				Calling getPersistenceManager from 
				the same PersistenceManagerFactory 
				within the same EJB method call will always return the same 
				instance.  
				
SamplesUtilities.getPersistenceManager () 
    == SampleUtilities.getPersistenceManager (); // will always be true