Pages

Bytecode Enhancement contract in DataNucleus AccessPlatform v4.0

Sunday, April 20, 2014
Now in GitHub master, for DataNucleus AccessPlatform v4.0, we have changed the bytecode enhancement contract.

Since the days of JPOX we've always used the JDO bytecode enhancement contract as defined in the JDO spec. This has always been adequate to provide the necessary hooks into the object to allow for "transparent persistence". Saying that though, it does mean that anyone using DataNucleus would always have to have jdo-api.jar in their CLASSPATH, even when using JPA. This was clearly undesirable, but not a large price to pay for easy provision of JPA.

In v4.0 onwards we will enhance classes to implement org.datanucleus.enhancer.Persistable. This is very similar in terms of structure, just that methods are now prefixed "dn" instead of "jdo", and there is now a method to get the ExecutionContext that is managing the object (whereas before it was a PersistenceManager, which made very little sense for JPA usage).

Why the change?

Oracle is putting significant obstacles in the way of having further releases of the JDO standard, involving lawyers etc. Additionally, following the Apache way, the Apache JDO project has not exactly operated very efficiently in terms of getting releases out of the door. Moreover we want to remove the requirement of having to have jdo-api.jar in the CLASSPATH for JPA usage. This change will also mean that we can, in principle, improve the bytecode enhancement contract to make things more efficient or add on more information to enhance the persistence process without being restricted by what JDO has bothered to standardise.

What does this mean for a typical user?

It means very little in reality, and the majority of applications will work unchanged (apart from having to re-enhance the classes). Some minor things that will change

  • Wherever you use enhanced classes, you will need datanucleus-core.jar in the CLASSPATH
  • JPA users won't need to have jdo-api.jar in the CLASSPATH
  • Internally DataNucleus now uses its own builtin single-field identity classes, and if you refer to javax.jdo.identity.* classes (for JDO contexts) will auto-convert to our own class for internal use. See this package for the DN internal identity classes. There is really no need to use these JDO builtin classes directly since DataNucleus will always select the most appropriate id type when you have a single PK field.
  • You no longer check if a returned object is of type javax.jdo.spi.PersistenceCapable since it won't be, instead being a org.datanucleus.enhancer.Persistable.

Please register any concerns/queries in the comments section

6 comments:

  1. Hello.

    JDO as API far more mature and flexible than JPA (excluding Criteria API). In our company we choose JDO for it clearnes, strong lifecycle and power ORM. We use JDO in 4 projects and have very positive expirience with API. Also we make some minor contributions to Datanucleus in RDBMS area and want to make some more (OSGI and RDBMS). It's sad that Datanucleus is no more JDO implementation. Politics and Oracle win that buttle.

    JPA is not enough for our tasks for us: it not dynamic, transaction policy flexible, modular, ORM flexible. There is no simple thing - embedable inheritance and use it as map key. JPA is ugly...

    It seams that JDO is finaly dead.

    Just because:
    1. Without PersistenceCapable it is not JDO...
    2. Why I should depend in my core domain code on havy Datanucleus Core jar instead on JDO API?
    3. In dynamic OSGI container we use runtime modularity with class reloading. With JDO only API there is no need for Datanucleus jar at all if we not use persistence in current deployment profile (but use domain logic).

    Sad, very sad...

    Anyway, Andy, thank you very much for JDO promotion and support!

    ReplyDelete
    Replies
    1. I don't see where this means "drop support for JDO" and "no more JDO implementation". We have dropped the bytecode enhancement contract of JDO ... i.e binary compatibility. i.e the ability to use your enhanced classes in a different JDO implementation. And when did you last use your enhanced classes in a *different* JDO implementation???

      The JDO API remains. The JDO Metadata remains. The JDO Annotations remain. Users applications will work just as before, with the same JDO API.

      Good, very good.

      Delete
    2. FWIW DN 4.0.0-m3 (using the new enhancement contract) passes the JDO TCK. So everything is completely JDO compliant, just like it always has been.

      Final comment : If you or your company are concerned about having "datanucleus-core.jar" in the CLASSPATH (and can't see how it can be described as 'heavy' lol) you could contribute support for enhancing and running with EITHER bytecode enhancement contract; obviously that would mean work on your side, but then it's you with the requirement.

      Delete
  2. Andy, thanks for reply!

    Does it mean that we can cast to PersistenceCapable in our SPI code (in OSGI container for example)?

    Datanucleus core is far more havy than JDO API both in terms of class count and what is more importment in deps count. It's especially importment in envs with runtime dependencies checks. Depend in domain code on JDO API is not so clear. But depend on Datanucleus Core with in transitive deps is not good for us. Looks like our demands is exception...

    I think about some thin wrapper around Persistable and PersistenceCapable. Question is how thin it might be?

    ReplyDelete
    Replies
    1. The blog post states very clearly you cannot cast to PersistenceCapable, but then that is part of an SPI and should not be used by users anyway (only for the JDO implementation).

      While core is larger in terms of the jar being 1.8Mb, very few classes would be "loaded" if you instantiate an enhanced class, and this is the only sane measurement to use for "light"/"heavy" or whatever. The dependencies of core would NOT be loaded either (and it has very few).

      Whether you consider providing enhancement the old way and the new way is up to you and I have no time to spend on it, but you can look at "core" from just before the blog post date to see how the code was before. JDOAdapter/JPAAdapter could be used to hide PersistenceCapable/Persistable, but it would also need to hide the single-field id classes (since they go with the enhancement contract interface), also the StateManager (org.datanucleus.state .v. javax.jdo.spi), and likely the EnhancementNamer, and EnhancementHelper .v. JDOImplHelper. i.e it affects enhancement, but also runtime using the StateManager.

      Delete
  3. Andy, thanx for clarification. Looks like support for JDO enhancement contract cat not be implemented as thin wrapper.

    ReplyDelete