April 01, 2008

JPA not ready for desktop applications

Ever since JPA was released I wanted to use it. Since I'm working on a desktop application in my free time that needed some offline storage I immediately thought about using JPA for this.
All I needed was a small database to bundle with my application, HypersonicSQL (HSQLDB) is the all-java database I've been using with great success for integration testcases for the past few years. It's only 640KB in size and doesn't require an installation. This means it can be used as a library in a WebStart or Applet application.
For my needs HSQLDB + JPA is great, no more messing around with serializing objects to disk or using the Properties API. Using POJOs for user settings and caching online resources sounds great.
However when looking for examples of using JPA in a desktop application I found very few and I soon figured out why...
First I looked at the JPA provider I was familiar with from the J(2)EE world: Hibernate. After getting all it's dependencies I soon figured out why nobody uses JPA in a desktop application. Although the JPA API is lightweight, the JPA Providers aren't as you can see in the graph on the side. The thing that shocked me the most is that all the providers (including dependencies) are at least 4 times the size of the SQL database. Too bad, because the API was designed to also be used in desktop applications and it could be a huge productivity boost, but these outrageous sizes don't make it good candidates for web-deployment.
JPA Provider developers should really think about the desktop application platform and make a serious effort to reduce it's library size and required dependencies!


  1. Can you tell me the actual user impact of the download size. We are talking about 5 Mo for Hibernate. It's translated into how many seconds?

    I can grant you that Hibernate is not ready for mobile, but desktop. I download videos and other high size files and quite frankly 5 Mo is not a problem.

    maybe a Pack200 version will do the trick.

  2. I did a quick test on the hibernate3 jar:
    Pack200 reduce it to 600k (from 2.3Mo) so we should target a 1.2Mo total

    Another approach will be possible in Hibernate 3.3: Steve has split Core into several submodules. this will of course reduce the footprint if you ditch the part you don't use.

  3. 5MB is about 10 seconds on a regular DSL connection. People do download larger files in case of video or music, but that's somehow more acceptable.
    Add 5MB up to the already "large" JRE (even the upcoming modular JRE will be at least 5MB including Swing etc.), adding some more graphics libraries like SceneGraph and/or JavaFX and you quickly get to 10 to 15MB. Translate all this into startup time and you are staring for at least 30 seconds to a "blank" screen even before Java is bootstrapping. This is not a favorable situation say for an applet, and I'm expecting to see more of those in the near future. This is not a Hibernate problem per-se, but if it adds 30% to the total

    Why are Sun and Adobe targetting their runtimes at 3MB!? All the same reason IMHO, because consumers these days don't want to wait.

    Hibernate has a lot to offer but my request is to minimize the core and to extract only the parts from the dependencies that are actually used. I think Toplink Essentials does this already.
    The thing that bothers me the most is that the HSQLDB is about 600KB and basically holds all the same type of data structures and does all the same SQL parsing, querying, etc. I would expect a JPA Provider to be roughly the same size.

    You're right on Pack200, but it merely hides the problem that Hibernate was developed with the server in mind and it would be great to have a lightweight version for use in web-deployed applications.
    Looking forward to the splitted core! :)

  4. TL Essentials is small but if you look at EclipseLink (TL), the core is about 5 Mo not including some extensions. Of course if the product does less, it's smaller.

    I understand the user experience problem, but the JRE is loaded only once for all apps, so you cannot count it as you did.

  5. Hi,

    I pasted your code into my program:

    InitFobs(); // Register plugin + load lib
    Manager.setHint(Manager.LIGHTWEIGHT_RENDERER, true);
    Player mediaPlayer = Manager.createRealizedPlayer(url);

    I'm using the InitFobs from:

    I'm getting the following error:

    Fobs4JMF - Native shared library found
    OpenError: File open error
    OpenError: File open error
    OpenError: File open error
    OpenError: File open error
    Unable to handle format: AVC1, 1280x720, FrameRate=29.9, Length=213218
    Unable to handle format: mp4a, 48000.0 Hz, 16-bit, Stereo, BigEndian, Signed, FrameSize=32 bits
    Failed to realize: com.sun.media.PlaybackEngine@c01e99
    Error: Unable to realize com.sun.media.PlaybackEngine@c01e99
    Exception in thread "main" javax.media.CannotRealizeException
    at javax.media.Manager.blockingCall(Manager.java:2005)
    at javax.media.Manager.createRealizedPlayer(Manager.java:528)
    at GemVident.FrameAccess.main(FrameAccess.java:446)

    I'm using Eclipse with jre1.6.0_05


  6. (Replied to the wrong topic but anyway...)

    The error message states that it doesn't support AVC1 codec. Which is probably because an old build of FFMPEG is included. I'm not sure if FFMPEG is supposed to support that codec. Did you try another video format, DIVX for example? Those should work pretty well.
    But instead of looking at FOBS4JMF, using the latest Sun Java video libs (Java Media Components) from the JavaFX runtime you should be able to play anything you have installed a codec for on your machine.
    Kirill has posted on how to do this here:

    Good luck!

  7. This comment has been removed by a blog administrator.

  8. Thoughtful blog thanks for sharing.