David R. Heffelfinger

  Ensode Technology, LLC

 

Thoughts on Distributed Version Control



Nowadays, distributed version control systems such as Mercurial, Git and Bazaar are all the rage. Lately, for a couple of my projects I have been using Mercurial.

Some frequently mentioned advantages of distributed version control are that it is not necessary to be connected to the network to commit your changes, and that all repositories are "equal".

Now that I've been using Mercurial for a while, I don't care that much about these advantages, however, there is one thing in Mercurial that I really, really like and that I miss very much when using other, centralized version control systems. What I love about Mercurial is that branching and merging is very simple and trivial (other distributed version control systems like Git and Bazaar probably share this advantage, however I don't have any experience with them).

When using traditional, centralized version control systems such as Subversion or CVS (or, $DEITY forbid, Harvest), many times I have found myself making some changes that will potentially introduce major breakage to the project. In cases like this I am "forced" to work without version control until all the kinks are ironed out, since committing my changes would prevent my coworkers from having a buildable source tree to work from.

The ideal solution for these cases is to create a branch in which I would make my changes safely, without affecting other developers, then when my changes are done merge my branch into the trunk. The problem with this is that for some reason branching and merging are not something "mere mortals" can do with centralized version control system. In order to do this, I would have to talk to a "CM" person to create the branch for me, which would probably take at least a few hours (if not days), then when I'm done the procedure to merge my changes would be just as painful.

When using Mercurial (and, I assume, other distributed version control systems as well), I can create a branch with ease, in Mercurial, all I have to do is use the hg clone command, passing the path of the repository to clone as a parameter. After doing this I would have my own, private branch that I can work with, without fear of breaking the build and preventing anyone else from making progress.

When I am done, all I have to do is an hg push to merge my changes back into the "trunk" (or my main branch).

If it turns out that I don't want to make the changes after all, all I need to do is delete my cloned repository using standard operating system commands (rm -rf in Linux/Unix), and the branch "never existed". This capability of easily making branches for experimental features and simply "nuking" them if it turns out to be a bad idea is what really makes Mercurial great for me. It is a very liberating feeling that I don't think can be expressed in words, you need to experience it to know what I mean.

 
 
 
 

Solving JasperReports Dependencies with Ivy


Lately, I've been doing some work with JasperReports. On my previous JasperReports projects, I've either used Maven, which automatically takes care of resolving dependencies, or I have simply downloaded the project's dependencies by hand.

Using Maven is nice, since it resolves dependencies, however, JasperReports comes with a series of useful ANT tasks to compile reports, preview them etc. I wanted access to these tasks and I also wanted dependency management.

There were a couple of ways I could achieve both. I know ANT targets can be called from Maven, this could be one approach. Also, there is a dependency manager for ANT called Ivy. I had briefly used Ivy before, I thought I would try this approach.

Ivy works by adding a series of custom ANT tasks, installing Ivy is very simple, all that needs to be done is to copy the Ivy jar file to ${ANT_HOME}/lib. Once Ivy is installed, custom Ivy tasks are available in our ANT build files.

Some additional configuration needs to be done in an Ivy specific XML file, named ivy.xml. In this file is where we actually specify our dependencies.

I set up my project to depend on JasperReports and tried to have Ivy automatically download all of JasperReports dependencies, unfortunately the build failed, complaining about some missing dependencies, specifically mondrian and commons-javaflow.



[ivy:retrieve] 		::::::::::::::::::::::::::::::::::::::::::::::
[ivy:retrieve] :: UNRESOLVED DEPENDENCIES ::
[ivy:retrieve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:retrieve] :: commons-javaflow#commons-javaflow;20060411: not found
[ivy:retrieve] :: mondrian#mondrian;2.3.2.8944: not found
[ivy:retrieve] ::::::::::::::::::::::::::::::::::::::::::::::
[ivy:retrieve]
[ivy:retrieve] :: USE VERBOSE OR DEBUG MESSAGE LEVEL FOR MORE DETAILS


After some googling, some head scratching (and some hair pulling and banging on the table for good measure), I found out what was going on.

JasperReports has some optional dependencies declared in its pom.xml, these dependencies are not downloaded by default when using Maven, however Ivy attempts to download them. For some reason these dependencies do not exist in the repository, because of this the ANT build fails.

After some research, I found out the necessary modifications to ivy.xml to make the build succeed:



<ivy-module version="2.0">
    <info organisation="ensode" module="mymodule"/>  
    <dependencies>
        <dependency org="jasperreports" name="jasperreports" rev="3.1.2" conf="*->default"/>
    </dependencies>
</ivy-module>

What I had to do was to  use the conf attribute of the <dependency> tag to specify that I wanted that configuration for this particular dependency. The *-> default means that all your module configurations depend on the 'default' configuration of JasperReports, as explained by Xavier Hanin in this message of the Ivy users mailing list.

After making this change, Ivy was able to successfully download all JasperReports dependencies.

[ivy:retrieve]     commons-beanutils#commons-beanutils;1.8.0 by [commons-beanutils#commons-beanutils;1.7.0] in [runtime]
    ---------------------------------------------------------------------
    |                  |            modules            ||   artifacts   |
    |       conf       | number| search|dwnlded|evicted|| number|dwnlded|
    ---------------------------------------------------------------------
    |      runtime     |   14  |   12  |   12  |   2   ||   11  |   11  |
    ---------------------------------------------------------------------

I figured I would document this procedure in case others are having similar issues.

 
 
 
 

Yet another "My Favorite Firefox Extensions" Post


It seems like every other day there is a link on DZone about someone listing their own favorite Firefox extensions.

Well, I didn't want to be left out, so here are mine:

  1. Web Developer, provides a lot of functionality useful when developing web applications. One of my favorite features is the ability to outline elements on the page, very useful.

  2. Firebug, I can't live without the ability to edit Javascript in real time, and see the results on the page immediately. Also, the Firebug console is invaluable when debugging Javascript, freeing us from the awful alerts(); we used to have to use all the time in the past. Working with Javascript without firebug is like working with a hand tied behind your back.
  3. iMacros, when developing web applications, we often have to go through tedious, repetitive steps to get to the page we are developing. iMacro allows us to record macros to go through the repetitive boring stuff for us, a real time saver and sanity preserver.
There you have it. If you develop web applications for a living, the above Firefox addons will make your life a lot easier, and will also make you a lot more productive.


 
 
 
 

Common JPA Questions



  1. How can I have a composite primary key in JPA?

    There are several ways to do it, this page explains them.

  2. How can I prevent users from overwriting each other's changes to the database?

    Use the @Version annotation.

  3. Is there a way to do bulk updates and/or deletes with the Java Persistence Query Language (JPQL)?

    Yes.

Upgraded to Roller 4.0.1


Since I just upgraded JavaDB, I figured this was a good time to upgrade to the latest version of roller as well. I was using roller 4.0, which is fairly up to date, but I figured it wouldn't hurt to upgrade to the latest, 4.0.1.

I simply downloaded roller 4.0.1, created a war file from the roller directory and deployed it to GlassFish, but for some reason the upgrade didn't go smoothly, I kept getting a "Roller Weblogger has not been bootstrapped yet" error.

I tried various ways of deploying, using asadmin, copying the war file to the autodeploy folder, etc, but I kept getting the same error. I restarted GlassFish several times, I restarted the database (JavaDB/Derby) several times, nothing seemed to solve the problem.

I then decided to reinstall roller 4.0 (thank goodness I made a backup), and it came back up successfully. After doing this, I then redeployed roller 4.0.1 using a different temporary context root, and this time, it installed successfully, asking me to upgrade the database. I did upgrade the database (the only thing that needs to be done when going from roller 4.0 to roller 4.0.1 is change the version number), and I had both roller 4.0 and 4.01 running in parallel with different context roots.

I then undeployed roller 4.0, and changed the context root of 4.0.1 to match the one I had in 4.0 (/roller), I am now in business.

Why wouldn't roller 4.0.1 just install over 4.0 is anyone's guess, however I was glad I was able to work around the issue.

Java DB / Apache Derby Upgraded


Like I mentioned in My very first entry in this blog, I am running Apache Roller to run this blog.

I'm using GlassFish and Java DB, which isn't much more than a rebranded version of Apache Derby.

The setup was working OK, but every now and then Roller would throw some weird errors, valid URLs would 404, and sometimes it would go completely "out to lunch", generating error 500's.

I started looking through the GlassFish logs and noticed some entries similar to the following:


Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at org.apache.derby.client.net.NetCursor.findExtdtaData(Unknown Source)
at org.apache.derby.client.net.NetCursor.getClobColumn_(Unknown Source)
at org.apache.derby.client.am.Cursor.getString(Unknown Source)

I googled around and found out this issue is caused by a bug on JavaDB/Derby version 10.3.2.1 and earlier. I happened to be running 10.3.2.1. I just upgraded to version 10.3.3.0 of JavaDB/Derby. I expect the weird errors I've been seeing to go away now.

 
 
 
 

Running Graphical Applications on a remote server


Like many, I host my web site on a remote server, it is a Virtual Private Server, running Linux (Cent OS 5).

I have full SSH access to my server, which provides me with full access to the bash shell to do anything my heart desires, well, almost anything, or so I thought.

One thing I couldn't do was to run graphical applications on the server, since it doesn't have an X server such as X.org. This didn't bother me too much, since there weren't too many graphical applications there I wanted to run remotely, with one exception, the GlassFish update tool.

I remember back in the good old days when Unix ruled, you could set the DISPLAY environment variable to run an application on one workstation or server while displaying it on another, I tried setting the DISPLAY variable to the display of my local Linux laptop, but it didn't work.

A few days ago while browsing Slashdot, I ran into a comment that explained how to achieve this:

ssh -YtC user@myserver.com /path/to/graphical_app

I tried the above with the correct credentials, server and path and lo and behold, I was able to run the GlassFish update tool on my server while displaying it on my laptop.

Thanks Doug!

 
 
 
 

Installing Ubuntu Intrepid Ibex in an old laptop


I have an old Averatec 3250H1 laptop that is still being used (2200+ 32 bit AMD processor, 60GB hard disk, 512MB RAM). This laptop was running Ubuntu 5.04 (Hoary Hedgehog).

I wanted to upgrade the version of Ubuntu to a more modern version. I downloaded the 32 bit version of the Intrepid Ibex install ISO, burned it into a CD and got to work.

Unfortunately the installer CD wasn't running properly, early into the install process it would just dump me into a command line and the install would abort.

I tried googling around but most information out there for this laptop is from around circa 2005, seems like nobody is trying to install a modern version of Linux on this specific laptop model.

After some messing around, I started to suspect that what was making the install abort was lack of drivers for the video card on this machine (S3 Unichrome Integrated Graphics with 64MB Shared Memory). I tried looking for an alternate way to install, the only way I could find was to download an alternate install ISO. So I downloaded this alternate install CD and proceeded to install Ibex on this "classic" laptop, unfortunately, the installer froze again at 25% of the "Select and Install Software" stage, in the "Preparing gnome-icon-theme" step. At this point I had to abort the installation, by forcibly turning off the laptop, which became unbootable after this mishap.

At this point I tried the Ubuntu alternate install CD once again, this time choosing the "command line system" (or something along those lines) option. I figured I could try and hack my way into installing X later, after all, it was running when the laptop had Hoary Hedgehog. This time, the install finished successfully, and I had a fully functional (albeit text only) system.

I booted up to my new install and upgraded all the software by running "apt-get update", followed by "apt-get upgrade" (thank goodness I am a Debian veteran and a few years of graphical only package management in Ubuntu didn't make me forget how to update software from the command line). At this point I had a fully updated, command line only system.

After some more googling around, it became obvious that I wasn't the only one having problems with the included Unichrome integrated video card included in the laptop. Thankfully, I was able to figure out that I needed the "openchrome" X driver, and I found a usable xorg.conf that I could just download and use.

After figuring out how to configure the video card, I was able to successfully run X, however saying that it was ugly doesn't even begin to describe it, all I had was a terminal window and a gray background, of course, GNOME wasn't yet installed.

I did an "apt-get install gnome", which resulted in approximately a million packages being downloaded and installed, after a very long wait I tried to boot to X again, this time running GNOME, but for some reason it seemed to be running a Debian theme, as opposed to the default Ubuntu "brown" theme.

At this point I have the laptop almost fully functional. The only thing that is not working yet is the wireless. I'm pretty sure I'll be able to get it to work, after all it was working in Hoary, however life got in the way and I had to stop setting it up. To be continued, I guess.

 
 
 
 

Java EE 5 Reference Material




My Books

Two of my books cover Java EE 5, one focuses on GlassFish deployment, the other focuses on developing using NetBeans.

  • Java EE 5 Development using GlassFish Application Server - free chapter on JSF
  • Java EE 5 Development with NetBeans 6 - free chapter on JSF
  • Java EE 

    The Java EE 5 Tutorial covers most aspects of Java EE 5. Examples can be downloaded as NetBeans projects.

  • Java EE 5 Tutorial
  • Java EE 6 (JSF 2.0, EJB 3.1)
  • JSF

    JavaServer Faces is the standard component framework for Java EE 5.

  • JSF HTML Tag reference
  • JSF Custom Conversion and Validation
  • JSF Phase Listeners
  • Facelets
  • JSF Component Library Matrix
  • JSF Localization
  • JPA

    The Java Persistence API is the standard Object Relational Mapping (ORM) tool for Java EE 5. It takes the best ideas from Hibernate and other ORM tools and incorporates them into the standard.

  • JPA Composite Primary Keys
  • JPA Optimistic Locking using @Version annotation
  • JPQL Reference

  •  
     
     
     
     

    « February 2009 »
    SunMonTueWedThuFriSat
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    17
    18
    19
    23
    24
    25
    27
           
           
    Today

     
    © David R. Heffelfinger