Sunday, March 11, 2007

JPA + J2SE Servlet Containers = Impossible

Well, somewhat impossible depending on what you need to do.

If you need dynamic weaving of your classes at runtime, give up. It won't work, not with a J2SE servlet container.

The problem seems to be that the javaagent (for both OpenJPA and for Toplink Essentials) is incapable of coping with classes that are loaded by a different classloader. If you manage to get your javaagent JVM argument to work (which will require annoying experiments with quotation marks and adding stuff to your classpath), then all of your Entity classes will fail to load because the agent can't find them. They don't exist as far is it is concerned, because they are loaded by a different classloader.

So if you want to use lazy loading of 1:1 fields with a J2SE container, you must either do static weaving or give up hope. Your other option is to use a full-blown J2EE container in all its bloated glory.

Screw this. I'm going to bed.

Labels: , , , , ,

Well, I'm here to share your sentiment. I'm working in a JSE environment (fat client).

First I wanted to reverse engineer an existing database, use @MappedSuperclass for the generated class and then have a editable class that extends this.

Hibernate did not like this and won't run.

So I switched to Toplink and it does work as advertised, so then I started testing lazy loading.

It simply won't do. Forced weaving (manual or ANT) simply is not present in the agent.jar.

Soooo. OpenJPA you say?
Your other choice is to use static weaving (at compile time). This means not specifying -javaagent on the command line to the JVM and using the weaving as part of your build process. There should be a way to do it using toplink-essentials-agent.jar. I did an experiment with this and found that it worked, unless there are spaces in your classpath when you run the static weaver.

(It's a bug in Toplink. They should have called .toURI().getPath() on the URL they get from the Classloader; because they don't, any classpath entry with a space in it becomes %20 and stays that way.)
I seem to be treading in your same footsteps: after the initial sheen of JPA has worn off, I'm left quite dissapointed with the whole javaagent fiasco. I'm using Spring and had to watch annoyingly as I fell back first from SimpleLoadTimeWeaver, then to ReflectiveLoadTimeWeaver and then finally to the javaagent InstrumentationLoadTimeWeaver.

Okay, so I got Toplink JPA to work, and for a while it was doing the job. I did have quite a few issues getting Compass annotations integrated, but for a while there, I achieved that very hard to find rock of stability in this integration hell. Then I just found a nasty bug in Toplink... which was a final straw in a list of oddities forcing me to break apart my transactions in a less then ideal way.

So, from Toplink to OpenJPA, and it hasn't been an easy road. I think I'm almost there. Almost. But not quite. After having to pull out Compass temporarily and strip down the annotations on many of my classes, it almost looks like it's working. Now I've just got a bizarre error with pcGetManagerFieldCount breaking.

I'm pretty close to reverting back to Toplink and making my applications transactions structured in a less then optimal way. What is annoying me about all this is that JPA itself is frustratingly simple: it's just the integration is a nightmare. Toplink at least has pretty good forums... OpenJPA just has mailing lists, yet it doesn't look like there's a good search facility which takes out a huge part of their usability.

And don't think that J2EE containers like Tomcat have it any easier... you've been having hell with a regular fat client process: I've been working with Tomcat 5.5.X and I've still had very similar issues.

I think I'm going to try using the static weaving, since it actually seems easier then all this.
Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?

Subscribe to Posts [Atom]