by Rob 06 Apr 21:07
Non-eclipse users and changes to Bytecode enhancement/weaving

I am thinking of changing the bytecode enhancement approach for 0.9.8.

Currently at runtime Ebean uses its own class loader to create a sub class of the entity beans.

I'm thinking of changing this to essentially follow the toplink approach which uses a java agent (for load time weaving) or static compile (where a post compile process modifies the .class on the file system).

The downside to this change is that you can't just save/compile and then run. Well, you can but you need to have a IDE plugin to perform the enhancement post compile or use a java agent.

I'm looking at providing an eclipse plugin to perform the post compile enhancement but other IDE users may be initially left out :(

WHY DO THIS?
I'm pretty sure we should always be using field level interception.
This will simplify that enhancement and simple is GOOD. There are other benefits including the possibility of annotated transaction demarcation.

The only downside is that realistically we need IDE support for the post compile (or use an ant task which is ok but not the same as immediate save-run which is what you want during development). Using a java agent is OK but the mechanism is generally pretty slow.

I'm keen to hear questions thoughts etc... to make sure this is an acceptable change.

Thanks, Rob.

14 Apr 23:32
by Rob

Just to reiterate...

Field Access (rather than Property access) is what we want. There is *NO* known benefit of property access that I am aware of. We *WANT* the flexibility of field access.

We also want to play nicely in the OSGi playground...

There are some myths about Field vs Property Access such as performance and getting Id properties - these are not an issue either way. The reason for field access is for flexibility such as not requiring a setter, and for the ability to add logic to your entity beans without strange consequences.

I am VERY tempted to actually drop property access altogether.

Thoughts, ideas, issues?

Thanks, Rob.

14 Apr 23:51
by Tibor Mlynarik

To support WebStart deployment there should exists alternative to java agent as it's not allowed in WebStart/Applet environment.
Kudos for prompt AutoFetch implementation !

Tibor

15 Apr 06:45
by Rob

Interesting, thanks...

There are 3 real options that I am aware of to get around passing a javaagent.

1. jdk6 Sun JVM specific VirtualMachine attach API which can load agents dynamically into a running JVM.
http://java.sun.com/javase/6/docs/jdk/api/attach/spec/com/sun/tools/attach/VirtualMachine.html

2. Using an ANT task to enhance the classes prior to them being loaded.

3. An IDE plugin that enhances the classes as they are saved/compiled via the IDE (basically the same as 2 really).

I'm hoping that people developing a WebStart app would be happy for the enhancement to occur via an ANT task. Hmmm...

21 May 22:09
by johan

The requirement for javaagents or bytecode enhancements are the reasons why I always favor Hibernate+EntityManager over any other JDO or JPA implementation.

Why do you want to change the bytecode enhancement process at all? I can't see any arguments in your posts above. Also I don't understand how field vs. property access relates to this decision.

Even if you change the process, can't you simply support all of the strategies? javaagent, compile-time enhancement and runtime subclassing?

23 May 10:38
by Rob

>> are the reasons why I always favor Hibernate+EntityManager
Yes, I hear you... that's why its a very big decision. For example openJPA has done the reverse of what I'm suggesting for Ebean - they have tried to additionally adopt the Hibernate approach to enhancement.

>> Why do you want to change the bytecode enhancement process at all?
It is all about field vs property access. I need to be a lot more explicit in this so I'll detail this at the end with a separate post.

>> ... can't you simply support all of the strategies?
Yes'ish. The issue with this revolves around runtime subclassing (what Ebean does currently and Hibernate does mostly) and how that works for field access with inheritance hierachies (aka thats the hard/messy bit).

As I see it you are suggesting something along the approach taken by openJPA. They got so much stick due to difficulties with their enhancement process that they wanted to provide subclassing based enhancement like Hibernate (and Ebean up to 0.9.7).

From my perspective they have ended up with something that runs different ways in different environments which I think it confusing.

The technical issue/difficulty here is that this gets hard/messy if you want field access with an inheritance hierarchy. If you look at section 2.4 Omitting the JPA Enhancer in the openJPA docs you may see that they too found this hard (they don't do it).

So if you stick to property access or never use an inheritance hierarchy then yes what I'm suggesting is a potentially a BIG detraction for current Ebean users.

23 May 10:58
by Rob

FIELD ACCESS
============
Field access gives us a number of advantages.
1. You don't need setters (say for version columns).
2. You can put business logic into your entity beans and it will work as you expect (Generally not the case for Property access).

Specifically with 2 and Property access, if you put any logic into a getter or setter that accesses any other field other than the one being set or get then you could get strange behaviour depending on the loaded state of the entity bean (NullPointerExceptions, invalid logic etc).

// where firstName and lastName are persistent properties...
// this may not work with Property access depending on
// the state of the entity bean
public String getName() {
return firstName + " " + lastName;
}

// assuming firstName and status are persistent properties
// this logic may not work with Property access
public String getFirstName() {
if (status == UserStatus.NEW) {
...
}
return firstName;
}

This all just works as you would expect with Field access and you can model and code your entities pretty much as you like. You don't need to strictly have getters and setters etc and can add any logic.

With Property access the above code is buggy. It will work on fully loaded beans but it *may* not on references or partially loaded beans. depending on the logic and state.

23 May 11:23
by Rob

LONG TERM:
For me there is no question that Field access is the way to go long term (or even now). Property access is far more limited and I suspect will lead to confused and unhappy developers.

Enhancement via javaagent or ant task is not inheritantly hard. I recognise there have been issues with openJPA and Toplink but that doesn't mean it will be so for Ebean.

I guess I'm trying to take a long term view and optimistic that the javaagent and ant task approach will work well for people.
NB: I am using this now (0.9.8) and it is working very well.

23 May 11:53
by Rob

Getting back to your question...
>>
Even if you change the process, can't you simply support all of the strategies? javaagent, compile-time enhancement and runtime subclassing?
<<
Currently when developing the field access support via the "subclassing" approach it got difficult with an Inheritance Hierarchy. There was a thought/approach that I felt would be possible but I did not pursue it (it was going to be hard / I got lazy). I don't believe openJPA have a "subclassing" approach supporting Field access so I'm guessing they think it's hard too.

I am not sure when I'll get back to looking at this problem again, so it is very likely that I put out Ebean 0.9.8 without the "subclassing" approach.

The million dollar question is whether I can convince people that Field access is the approach they need in the long term, and that they are prepared to put up with some glitches along the way to get there.

Create a New Topic

Title:
Body:
 
Introduction User Guide (pdf) Install/Configure Public JavaDoc Whitepapers
General Database Specific Byte Code Deployment Annotations Features
Top Bugs Top Enhancements
woResponse