2009-12-29

Plea to Maven repository managers

Thank you, library developers who provide a Maven repository, or push to the main repository. You make my life as a developer a lot easier by doing that.

I have a few small requests, which would in my opinion serve both you, and your developer users.

1. Please make your repository fast. Serve the files as straight-up static files, not through a Subversion HTTP repository interface, nor from the horrible depths of java.net.

2. Please make your repository rsyncable. While the lack of middle men has contributed greatly to the success of the Maven model, many organizations would like to, for various reasons, provide their developers with golden mirrors of the good stuff.

Since Maven repositories consist of directory entries, and plain files, providing a rsync read interface to the repository would probably lower your bandwidth costs and theirs, as well as allow the simple creation of second-level public mirrors.

3. Please use separate repositories for releases, milestones, and snapshots. If you push to the main repository, please don't push milestones or snapshots there.

4. Occasionally you will want to refactor the package structure of your product. Currently, it is a common sight in the public repository, for a popular library to have obsolete artefacts cluttering up the namespace, and it might be quite an adventure to try to find out which artefacts are in fact up to date, and which should absolutely not be used.

When you do major refactorings of this kind for a major release, please don't be afraid to break backwards compatibility by cleaning up the old, obsolete packages, or preserve compatibility through a clean break, by creating a new sub-namespace for the new generation of package architecture.

Your users are developers who can restore compatibility, after deciding whether to upgrade or to stay with the old version, by making a small change to pom.xml, pushing it to version control, after which compatibility is restored for all the developers.

2009-12-24

Spring to Java EE 6 porting gotchas

JSF/Facelets:
  • Don't use JSTL tags with Facelets. Just don't do it. Substitute <ui:repeat> for <c:foreach>, and <f:subview rendered="#{expression}"> for <c:if>.
  • If you're wondering why your JavaScript can't access the document variable on the Google Chrome browser in a Facelets application, it's because the default Facelets content-type is application/xml+xhtml which doesn't sit well with some browsers. <f:view contenttype="text/html> will help.
JPA/EclipseLink:
  • GlassFish has a directory called domains/domain1/lib/databases, but won't find your JDBC driver from there. Put the JAR in domains/domain1/lib.
  • Getting EclipseLink to do JOINs instead of N+1 or even 2N+1 queries is sometimes challenging. query.setHint(QueryHints.BATCH, "user.emails") to the rescue.
  • Using Postgresql sequences with default settings all around will lead to problems when trying to insert several new entities in a session, because by default JPA will assume that once it has acquired an identity number from the sequence, it can freely use 50 numbers up from there before having to re-acquire a new identity number from the sequence.
    The workaround is to configure either your JPA @SequenceGenerator to have the parameter @SequenceGenerator(allocationSize=1) or to modify your database sequence to have a step of 50 instead of 1. I'm going with the JPA configuration, although if I'd be inserting large batches regularly, I'd rather reconfigure the database sequences to avoid the roundtrip.
    Or just use IDENTITY instead of SEQUENCE, if you're also using the SERIAL datatype.
JAX-RS/Jersey:
  • If you've mapped your Jersey servlet to, say, "/jersey/*" in web.xml, your class-level resource path is @Path("jersey") and your method-level resource path is @Path("users/{id}"), you need to do the HTTP request to http://server/jersey/jersey/users/123, because the servlet starts interpreting paths from its own root, and not from the context root.

2009-12-13

Generating JPA 2.0 Criteria canonical metamodels with Maven and NetBeans

Updated on August 23, 2011: Hibernate, OpenJPA and DataNucleus documentation links.

Java EE 6 and JPA 2.0 bring us a neat feature from Hibernate: Criteria queries, which allow you to construct complex database queries in a safe manner, instead of trying to append pieces of SQL or JQL together, and hoping that the result doesn't allow injection attacks.

That's all well and good, but JPA 2.0 adds a wrinkle: instead of using simple strings to construct Criteria queries, one must generate metamodel classes, out of the entity classes. This is done by using the Java 6 APT annotation pre-processor.

Unfortunately, Maven doesn't support this kind of generation process very well out of the box. There are, however, various plugins such as the maven-annotation-plugin and apt-maven-plugin to help with this process.

I am still in the process of figuring out which way of generating the classes is the best, where they should go, and how to handle the process in a way which doesn't tie one to a specific JPA provider.

NetBeans has its own opinion on how the generated classes should be handled, as well.

Meanwhile, these are the best resources I've found for generating metamodels for various JPA implementations:

EclipseLink

org.eclipse.persistence.internal.jpa.modelgen.CanonicalModelProcessor
http://wiki.eclipse.org/UserGuide/JPA/Using_the_Canonical_Model_Generator_(ELUG)

Hibernate

org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor
http://docs.jboss.org/hibernate/stable/jpamodelgen/reference/en-US/html_single/

OpenJPA

org.apache.openjpa.persistence.meta.AnnotationProcessor6
http://openjpa.apache.org/builds/2.1.0/apache-openjpa-2.1.0/docs/manual/ch13s04.html

DataNucleus

http://www.datanucleus.org/products/accessplatform/jpa/jpql_criteria_metamodel.html

Edit: this works for me with EclipseLink.

2009-12-11

My Windows 2008 Server trial is over, but my 2008R2 trial has just begun...

For the last 6 months, I've been test-driving Windows 2008 Server on my home Windows machine.

The upgrade from XP to W2K8 was painless. I did a full re-install on a new hard drive. The W2K8 installation experience almost rivals the ease of Ubuntu and Redhat Linux installations, but still required a few reboots. I also added 4GB of memory for the price of 40€, so I chose the 64-bit version of Windows to be able to use the full range of 6GB.

W2K8 is much, much more stable than XP was. I've started to trust my Windows computer a lot more after the upgrade. A typical source of flakiness under XP was my KVM. If I accidentally switched out of my Windows computer when it was booting up, the least of my problems would be that I'd have to restart the whole powerup cycle yet again. W2K8 feels much more fault-tolerant.

What seems almost miraculous to me is that the NVIDIA graphics drivers have flaked out a few times during the six months during gameplay, but the only real consequence of that, under W2K8, is that the screen goes dark for a few seconds, while the operating system reloads the drivers. Under XP, that usually meant a power button full reset.

Thumbs up for Windows 2008 from me! The trial period ran out, however, so now I installed Windows 2008 R2 Server, which shares most of its core with Windows 7, over the old installation. The process was quite painless, and since my games are from Steam, I simply had to re-install Steam, and move my steamapps folder under the new Steam directory. Easy as that.

I'm happy with this product. Corporate sysadmins, please, please, upgrade your users to Windows 7 or W2K8R2.