Product Development in Brisbane

Archive for the ‘Java’ Category

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.

Pretty URLs for any J2EE framework

Wednesday, June 13th, 2007

Making the browser location work like a command prompt is a good goal for any web application, and is possible for any J2EE web framework, even Struts 1.

To do this, having Rails style friendly urls is required. Traditionally J2EE frameworks and applications have not done a good job of providing friendly urls. It is easy to wander around the net and guess at what framework people used by the urls (e.g. anything .do is probably struts, .action’s are probably webwork etc.)

Of course one doesn’t have to be tied to this world. Pretty much anything is possible with Apache and mod-rewrite. This is handy when you are behind Apache, but that isn’t always the case. From time-to-time you may want to dot his completely within your J2EE application, making it independant of where you are running. The Servlet spec is powerful enough to make this possible, but for the lazy (like me) it is nice to know that someone has already done the hard work. The URL Rewrite library provides a filter which does the heavy lifting for you. There is a simple XML configuration file, which provides a rich language for customising your redirects using the Java Regex library, or a familiar directory traversal wildcard style syntax.

The library makes it possible to easily map urls like: products/1 to products.do?productId=1 or from: /australia/queensland/brisbane to: worldMap.jspa?country=australia&state=queensland&city=brisbane. There is a rich syntax for specifying the url rewrite conditions, as described in the comprehensive manual, and shown in the samples.

Automated Building and Releasing With Ant

Tuesday, May 1st, 2007

This blog post was initally started in January 2005.  I've learnt some more since then, and I'm including some of the lessons I've learnt from automation at Ephox and InvoicePlace in this post.

It is well documented that having your build automated is a good thing.

I would extend this, saying that  the automated deployment of applications is important too. The big benefits in my experience are repeatabilty (that is ensuring that deployments always happen in the same way), and consistency of deployments. Automating the process helps to fulfill the import goal of laziness as well.

Often getting this right can take a while. The hard work starts by analyzing the deployment process,  iteratively looking for bits of work that can be automated.

This can usually be done with a combination of custom ant tasks, external program calls, and console utilities. For all ant's wrinkles, it is a relatively useful tool, and there are a number of useful tasks available.

Here are some of the tasks that I have found useful in getting the build working.

The ant SQL task is great. It makes it possible to build/update databases, from simple flat files containing SQL statements.

The CVS task is good. In combination with Paegent from Putty, repositories requiring ssl access can be accessed easily as well.

IBM has a custom version of ant that can be used to deploy to WebSphere. I have found that with a combination of ant tasks, and tcl scripts any task that is required for deployment can be performed. This is best done in a build file that is seperate to the main build.xml, isolating the Websfear dependencies.  

A combination of ant (exec task), wget (command line http client), and phpmyadmin(php based admin tool for mysql databases) can be mangled together to interact with mysql databases in ways that aren't easily possible with the ant sql task (the sql exported by myphpadmin isn't compatible with the sql task).

The buildnumber task is useful. It gets the current build number from a properties file, makes it available as a property, then increments the property.

The moral of the story is that it is there is no good reason not to automate building and deployment.  It possible to do many great things with the large number of ant tasks available.  Writing your own isn't that hard, and calling out to external programs is easy as well.  Really it is hard to find any excuses for not automating a build.  The only excuse is time and effort, and the savings gained can almost certainly offset this.