Product Development in Brisbane

Archive for the ‘Java’ Category

Oracle SID != SERVICE_NAME

Friday, January 4th, 2008

… or how to setup your Oracle XE database so that JDBC database urls will work like they traditionally have.

For many years Oracle has been telling everyone Oracle SID != SERVICE_NAME.

Java Developers have always smiled and nodded with this statement as the oracle thin client jdbc url would always be something like:

jdbc:oracle:thin:@server:1521:SERVICE_NAME, or
jdbc:oracle:thin:@server:1521:SID 

which would work because databases always either had the SID and SERVICE_NAME as the same, or there was some magic that the Oracle listeners did to make this work.

Somewhere in the past couple of releases of Oracle this transparent mapping has ceased to exist. In particular Oracle 10G XE out of the box doesn’t support this sort of option.

It seems the new preferred way of doing Oracle JDBC URLs is:
jdbc:oracle:thin:@server:1521/SERVICE_NAME.

I discovered this information while working with making a WebSphere Portal instance use Oracle as it’s data repository. The documentation for doing this suggested using the old school SID style of url.  I tried this first as it felt familiar, but things didn't work.  Changing the url to use the PORT/SERVICE_NAME approach looked to mostly work, but didn’t quite spread the changes to everywhere required. I needed to run WPSConfig connect-database to update all the hidden bits of configuration around the portal installation. Unfortunately, this failed as the wpsconfig script calls out to programs that expect the url to follow the old school syntax (the stack trace show an index-out-of-bounds exception while parsing connect srings). I then had to go in and update the configuration on the database to enable connection via the old SID style approach.

This was done by working on the listener.ora file
(C:\oraclexe\app\oracle\product\10.2.0\server\NETWORK\ADMIN) to add in a SID_LIST_LISTENER entry for the database.

This was simply to add:
(SID_DESC =
    (GLOBAL_NAME = XE)
    (SID_NAME = XE)
    (ORACLE_HOME = C:\oraclexe\app\oracle\product\10.2.0\server)
)

to the SID_LIST of the SID_LIST_LISTENER

I ended up with a SID_LIST_LISTENER that looks like this:

SID_LIST_LISTENER =
    (SID_LIST =
        (SID_DESC =
            (SID_NAME = PLSExtProc)
            (ORACLE_HOME = C:\oraclexe\app\oracle\product\10.2.0\server)
            (PROGRAM = extproc)
        )
        (SID_DESC =
            (SID_NAME = CLRExtProc)
            (ORACLE_HOME = C:\oraclexe\app\oracle\product\10.2.0\server)
            (PROGRAM = extproc)
        )
        (SID_DESC =
            (GLOBAL_NAME = XE)
            (SID_NAME = XE)
            (ORACLE_HOME = C:\oraclexe\app\oracle\product\10.2.0\server)
        )
    )

This configuration works with an out of the box Oracle XE installation, and lets me use the jdbc:oracle:thin:@server:1521:SID.

Howto Keep Version History in a Single Table Using Hibernate

Friday, December 7th, 2007

 

Problem:

Keeping a history of data in a single table in hibernate, where all versions are treated as first class objects.

That is to say that every record in the database will be immutable. New records will be created with a new version number, but the old versions will never change. They are kept as the history of changes.

Solution:

When querying objects from hibernate ensure that they are initialised, and then detach them from the session:

Hibernate.initialize(result);
session.evict(result);

Then when saving the objects, ensure that the ID is null, and call thesession.save(businessObject) to save them.

//set the id to null to ensure that a new record is stored in the database.
businessObject.setId(null);
incrementVersion(businessObject);
session.save(businessObject);

The final part of the puzzle is to ensure that the class has it’s persistence properties set correctly, either by setting the annotations or configuring the xml file.

The important settings are:

  1. To help prevent updates, and improve performance set the mutable attribute on the class to false.
  2. The collection objects on the class have the lazy attribute set to false (ensuring that they are loaded when the object is retrieved, and the evicted object will work).

Following these steps will provide you with a versioned business object. It will be possible to retrive, and store the object to the database using the Hibernate search functionality.

Storing Large Strings with Hibernate 3

Thursday, November 15th, 2007

If you want to store a large string in hibernate 3 in a relatively transparent way, the text mapping type is your friend.  This will allow you to map a java String type to a database clob type, and store arbitary length large content items.  In previous versions (according to google) this took a fair bit of fiddling around, and required custom types (which required much magic to work in a cross platform manner).  Thankfully the text mapping type exists, making life much easier.

 

So in the old school pre 1.5 annotation world, we can take the class with a long string and map it using the code and mapping below:

class Profile {
    ...  
  private String bio;
    ...  
  public String getBio(){
    return bio;
  }

  public void setBio(String bio){
    this.bio=bio;
  }

}

and the mapping file:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="Profile" table="profiles">
        …
        <property name="bio" type="text" length="
10485760"/>
    </class>
</hibernate-mapping>

This will let you store a large string in hibernate, automatically handling the mapping between clob data and string data.  The important parts of the xml snippet above are the type and length attributes.  Both are required to ensure that the clob will be created of the right length.  The default for the length is 255, which is great when you are storing shortish strings in a varchar, but not so good when you want a large string in a clob.

Todays Cool Keyboard Shortcut In IntelliJ…

Wednesday, October 24th, 2007

..is cmd-opt-F7 (in Mac)

CMD OPT-F7 displays a list of  usages of the currently item (var/method) throughout the project, listing them in a nice inline dropdown list.  This is great for navigating around the usages of a method finding how they are used in context, before applying an aggressive refactoring.  I discovered the short cut recently while performing one of the other find usages options in Intellij (cmd-F7) and getting fat fingered and hitting CMD-OPT F7.

Why Use a Sledgehammer When There is a Bulldozer Lying Around

Wednesday, October 17th, 2007

Or finding which websphere portal shared jar contains the class you need.

When trying to find which WebSphere portal jar file contains the PortletServiceHome class (for the unitiated there are 225 jars in the portal shared directory), I was pushing my very rusty shell scripting skills.  I pulled in Doug for some advice, and we were working through various sledgehammer approaches and talking to google about what to do.  We were playing with various combinations of pipes and shell commands to get the output of the find (or ls) to play with the jar tvf and grep.

AJ then piped in with just use grep, and he really meant.. just use grep, and take advantage of the fact that the contents of the jar will be listed in plain text in the jar.

The command I ended up with was (running in PortalServer/shared/app):

grep PortletServiceHome *.jar

Which returns:
Binary file wp.pe.api.standard.jar matches
Binary file wp.pe.rt.impl.jar matches

Then running jar -tvf across the first jar shows that this is what I need to compile against and work with when developing.

The bulldozer of a grep across jars is the best way to find which jar contains a class that you are looking for1.

1 - While this feels really inefficient, it is actually better than having to spawn off multiple the jar processes which other approaches would involve.

An AJAX Iteration

Friday, September 21st, 2007

I'm currently unwinding after only just managing to see all the cards1 move from the "this iteration" column2 to the "done" column3 on our XP storyboard.  While the estimates had us coming in at the same spot as earlier iterations, it ended up being quite a bit tighter than the earlier ones had been.  

There are a few reasons why, but the biggest cause would be the fact that we were moving from the comfortable world of Java actions into world of some heavy ajax ui.  I spent some time working with libraries and researching how to do things like JSON in Java, and AJAX popups.  It was a fun and stretching iteration, with plenty of prettiness to show for the work.

I learnt a lot including:

 AJAX with Prototype is great.  Prototype provides all the methods you want in the library.  I would consistently find the methods I would want in the library such as $('id') (to find an element with an id), and the serialize methods for forms are really nice. Kudos to the prototype team for a great library.

Scriptaculous provides nice effects that build on prototype.  The Autocompleter is worth the price of admission.

The popup library by Stuart Rackham works really nicely.  He doesn't have access to Safari so hasn't tested it there, but now I have, and while not all the features work, it is possible to produce nice popups that work in Safari with this library.  He has built this on top of Scriptaculous and prototype and he has done a great job.

JSON for passing around data is cool.  The whole eval on the client thing is a bit scary, but (almost as I expect now) at least prototype provides a nice evalJSON method to help alleviate a little my security paranoia. Of the millions of JSON libraries available, the standard java one works ok. (what's not to like about a library with a license that includes the text "The Software shall be used for Good, not Evil."  Mightier JSON libraries exist that do all kinds of magic, but the simple approach is working to start us off.

 

The biggest missing piece in my JavaScript Development is the fact that it isn't TDD. There seem to be bits and pieces out there, but nothing that is jumping out and saying "use me I just work.". The main reasons I am wanting to do Test Driven Javascript are for quality and pleasure. Doug spent some time researching options for acceptance testing of E2 front to back (including the javascript), which will definately help out the quality, but it still would be great to have a viable TDD option.

I never would have expected to say this, but it has been fun doing the JavaScript and AJAX in the past iteration. It really is much better than in the past, and I can see it only getting better.

1 - The card contains a unit of work

2 - The list of cards we are planning on getting done in the iteration, but haven't started working on yet

3 - The list of things we have finished this iteration.

Deploying A Portlet to Jetspeed 2

Friday, August 3rd, 2007

This page exists primarily as a note to self regarding deployment of Portlets to a development version of Jetspeed.

The key is simple. 

When deploying a webapp to Jetspeed you need to put it into ${TOMCAT_HOME}/webapps/jetspeed/WEB-INF/deploy/. This information is available in the article on Jetspeed-2 Deploy tools jetspeed site, which (when I looked) wasn't on the google search for jetspeed deployment, which is instead littered with many references to maven (which still ranks as one of the most disappointing open source projects in my mind).

Knowing this information is important because (for someone who has experience in hacking with webapps), it is tempting to just drop a war into ${TOMCAT_HOME}/webapps and assume that things will just work.  This really doesn't work, and gives errors like:

"Title Error: Cannot pass a null PortletDefinition to a PortletEntity" 

Unfortunately (again at time of develpment) google didn't really make it clear that this error can be caused by the fact that Jetspeed can't load your class.

After getting the portlet deployed, you'll also want to hack up a psml file and put it in ${TOMCAT_HOME}/webapps/jetspeed/WEB-INF/pages.  

Something like this forms a half decent starting point.

<page id="simple"
    xmlns="http://portals.apache.org/jetspeed"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://portals.apache.org/jetspeed http://portals.apache.org/jetspeed-2/2.1/schemas/psml.xsd">

    <defaults skin="orange" layout-decorator="tigris" portlet-decorator="tigris"/>
    <title>This is the simplest portlet in the world</title>
    <metadata name="title" xml:lang="fr">La plus simple portlet du monde</metadata>

    <fragment id="simplest" type="layout" name="jetspeed-layouts::VelocityTwoColumns">
        <fragment id="simplest-first" type="portlet" name="E2::PortletWrapper">
            <property layout="TwoColumns" name="row" value="0" />
            <property layout="TwoColumns" name="column" value="0" />
        </fragment>
    </fragment>

    <security-constraints>
        <security-constraints-ref>public-view</security-constraints-ref>
    </security-constraints>
</page>

Of course if you want you can use various jetspeed tools to try and make this bit easier, but for the old skool guys who want to be in control, this is a pretty decent option.

TDD With JackRabbit

Friday, June 29th, 2007

… tips on Apache JackRabbit configuration for Test Driven Development. 

As AJ mentioned, we are currently working with Apache JackRabbit for an internal project.  It has been an interesting voyage of discovery, with some very interesting stops along the way. One of the first steps was to build some tests around the JCR.  I started with some simple exploratory tests around the API.  These helped build my understanding of the JCR and how it works.

The next step was to begin really working out our persistence API with TDD.  As a part of this, I wanted to be able to have a predominantly memory based repository to work with.  This is possible to do, as per the attached memoryRepository.xml file.

The key is to use a org.apache.jackrabbit.core.fs.mem. MemoryFileSystem for all file system elements, and a org.apache.jackrabbit.core.persistence.mem. InMemPersistenceManager for all persistence manager elements.  Unfortunately, with the attached config the file system is still used to store Lucene search indexes.  This means that the file system is still used, and needs to be cleaned up in the tests.

The attached JcrRepositoryTestBase.java file has the setup and teardown code that handles the cleanup of the search index directories.  This combination of code combines to allow the 35 JCR tests that we have run in about 10 seconds, and gives 100% coverage of all non exception handling code1.

1 - i.e. not including code that does nothing but catch (Exception e) {throw Wrapper(e) }, which while is testable is not currently tested by us.

First Rule of Enterprise Java Development

Thursday, June 28th, 2007

The first rule of Enterprise Java Development is:

……

any unexpected behaviour is caused by a classpath problem

Todays instance of this rule is a particularly fun one, given the line of code that exposed the problem.

I am using Apache Jackrabbit  as an embedded JCR repository, mostly following the Jackrabbit embedded mode instructions. I saw mostly because the Jackrabbit website doesn't actually match the 1.3 released version of JackRabbit (this is most annoying when following the "First Hops", but that is a digression).

So I've got a nice little webapp with an embedded repository that is accessed via JNDI.  The repository is responsible for shutting itself down which it does via a shutdown hook (BindableRepositories do this).  Unfortunately the shutdown hook gets called after the web app class loader has started unloading, and things are beginning to cleanup.  The first symptom of this problem is a null pointer exception when logging a message12. After isolating that the log message (in org.apache.jackrabbit.core.RepositoryImpl.doShutdown) really was causing a NPE, I commented out he line of code, redeployed and confirmed the nasty problems, getting the following exception:

org.apache.catalina.loader.WebappClassLoader loadClass
INFO: Illegal access: this web application instance has been stopped already. Could not load org.apache.commons. collections.map.AbstractReferenceMap$ReferenceValuesIterator. The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.

So while I am not yet in a position to report a fix this problem, I have been able to isolate it, and identify yet another instance of the first rule of enterprise development.

1 - When I first saw that this line of code was causing the problem, I thought that it would end badly — either the source code I had didn't match the binary or I was getting a null pointer exception while logging.

2 - This is particularly ironic given the raison d’être3 of SL4J is to remove problems like this.

3 - like my attempt at culture?4  

4 - sorry about the footnote overkill.

Example of a Good Open Source Project Website

Wednesday, June 13th, 2007

Open Source projects are known for dodgy websites, and rubbish documentation. I was overjoyed to see a project that got it right (URL Rewrite Filter). There are a number of things that I really appreciated with this site, and in the hope that people might take notice, I’m going to list the good bits here.

The landing home page has a nice concise description of what the project is all about. When I get to the front page, I can read the overview of the project, and get an understanding of what problems it was created for, and the goals of it. The front page told me enough to want to see more, but didn’t overwhelm me. I got a good feeling from the front page.

The other nice thing about the front page is the navigation structure. The side navigation bar provides the links which I am most interested in. One click to get to a download link (which has a direct link to the files). One click to the source code page (with instructions on svn access via http and the commandline). One click to the documentation. One click to get to the community support.

The documentation is excellent, and provides a good baseline for what documentation of a project this size should look like.

There are good examples of what the configuration file looks like, annotated in a way that makes it easy to understand what the code is there for.

The documentation provides a good reference for how to do the configuration.

It is a great site and provides a good example of what most open source project websites should look like.