Stomp

How to Stomp a Java object.

 

Stomping a java object is the process of taking a normal class file, produced by jikes or javac, and enhancing it into something capable of being saved to and retrieved from a database.

 

Start: Java source + Stomp metadata à javac: class file + Stomp metadata à

Stomp enhancer: Stomp-aware class file with JDO metadata à jdo enhancer: database-ready class file(s)

 

This is a complicated build process, but can be greatly simplified with tools like Ant or by using Makefiles.  The biggest trick to Stomp is getting any simple object working once.  Almost every other object you write is going to work the exact same way.  This page will take you through the life of the following object:

 

 

 

import java.util.Iterator;

import stomp.jdo.JDOFactory;

 

public class TestObject

{

            private int _data = 0;

 

            public void setData ()

            {

                        _data++;

            }

 

            public int getData ()

            {

                        return _data;

            }

 

            public static void main (String[] args)

            {

                        Iterator databaseObjects = JDOFactory.singleton ().getReadOnlyPersistenceManager ().

getExtent (TestObject.class, true).iterator ();

                        if (databaseObjects.hasNext ())

                        {

                                    TestObject databaseObject = (TestObject) databaseObjects.next ();

                                    System.out.println (“Got a TestObject out of the database!  It has data ” + databaseObject.getData ());

                                    databaseObject.setData ();

                                    System.out.println (“Run this class again… the counter should increase by one.”);

                        }

                        else

                        {

                                    JDOFactory.singleton ().persistNewObject (new TestObject ());

                                    System.out.println (“Added a new TestObject to the database!”);

                        }

                        System.out.println (“Done.”);

                        System.exit (0);

            }

}

 

The goal is to run ‘java TestObject’ multiple times, and watch as a new object is created, put into the database, retrieved in a different JVM, and changed.   Here are the steps to get there:

 

Step 1: compile TestObject.java.  You can copy the code above or download it.  Now, compile it.  This will immediately expose any CLASSPATH problems you may have.  To get past this step, you’ll have to have installed Stomp correctly.   Once you succeed, you will have a new file, TestObject.class.

 

Step 2: Stomp the class file.  Stomp works by reading in metadata that identifies the objects that should be enhanced.  It simultaneously generates a package.jdo file, which is needed by your JDO vendor to do its own bytecode changing thing.  To navigate this step, you’ll need to add another file, named services.xml, with the following content:

 

<services>

            <TestObject/>

</services>

 

Place this services.xml file in the same directory you have your TestObject.java file.  You’ll have one of these services.xml files for each package that contains an enhanced class.  In addition, you need a single runtime.prefs file, located someplace on your CLASSPATH.  To get you started, download this minimal runtime.prefs file, and add it to the same directory you’ve put TestObject.java.

 

Now, it’s time to Stomp some bytecode.  Run ‘java –DPKG_HOME=<full-path-to-your-java-root-here> stomp.enhance.ServiceEnhancer services.xml’ in the same directory as all the other files.  The PKG_HOME environment variable is how Stomp determines the fully qualified java name of the objects in your services.xml file.  For this simple example, the full-path-to-your-java-root should be exactly where you’ve been putting all of these files.  If all goes well, you should see some output about TestObject being enhanced, and several new files should be created TestObject_.class, TestObject_Common.class, and package.jdo.  If you’ve gotten this far, you’re doing great.  Otherwise, check out the problems reported and try to fix them.  If you get stuck, return to the main page and look for someplace to send your questions.

 

Step 3: JDO enhance.  At this point, Stomp has done its work, and it’s time for your JDO vendor of choice to do their thing (making the object implement PersistenceCapable, etc).  This step varies from one vendor to the next, so check the documentation provided by your implementation.  You are trying to find out how to use the generated package.jdo file to enhance your class files, and to initialize the database.

 

Step 3: Kodo users.

For Kodo users, the process looks something like this:

1.      Enhance the object by running ‘java com.solarmetric.kodo.enhance.JDOEnhancer package.jdo

2.     Initialize the database schema by running ‘java com.solarmetric.kodo.impl.jdbc.schema.SchemaTool –action refresh package.jdo`

 

Of course, you’ll have to have downloaded Kodo first.  Note that you’ll need a kodo.properties file available on the CLASSPATH to make this step work correctly.  See Solarmetric’s documentation for more details on how to setup this software.

 

Step 4: Run the test. Run ‘java TestObject’ several times, verifying that the output is correct.  You should initially see that a TestObject is created and put in the database, and that subsequent runs find this object and change its data, incrementing the counter by one with every pass.  Kodo users: note that you need to alter your kodo.properties file a bit to describe your data caching plan and allow Kodo and Stomp to work together.

 

Step 5: Expand the test.  Try writing and enhancing another object of your own design.  Add a relation between TestObject and your object.  Keep in mind that you may have to alter the services.xml file to accommodate your changes.  It’s also not a bad idea to remove all the class files and auto-generated package.jdo files and rebuild everything from scratch with each change, although this is not strictly necessary.

 

That’s it.  Every object you write will work just like this.  Some objects may require a bit more metadata in the services.xml file, as required by the JDO specification.  Beyond that, it should all be just as easy as this example.  Once you feel comfortable with this example, you’ll want to move on to find out how Stomp works, and especially to find out how to configure Stomp to meet the particular needs of your application.  There are several important questions to answer, including how different JVMs are going to find out about data changes, whether transactions are optimistic or pessimistic, etc.  The good news is that while one person is tweaking Stomp, other developers can begin using it.  The exact performance characteristics of the persistence layer can be setup any time before you deploy to production, and of course can be changed as the demands of your application change, all without modifying a single source file.

 

As always, if you have any questions, see the main page.