[hibernate-dev] Using Hibernate ORM as automatic JPMS modules

Gunnar Morling gunnar at hibernate.org
Thu Dec 28 13:24:07 EST 2017


2017-12-28 19:10 GMT+01:00 Steve Ebersole <steve at hibernate.org>:

>
>    - Main-Class is fine afaik.  It was requested previously by users and
>    added accordingly.  I'm not going to change it unless you can show me
>    concrete reason to.
>
> Seeing now that Version indeed defines a main() method, didn't expect
that. No reason to change it indeed.

   - Specification-* - I had considered that.  TBH its not important
   afaik.  And Hibernate defines a specification as well (its API) that is a
   super set of JPA.  And its not like I just added this.  Those have been
   generated into the manifest at least as far back as the move to Gradle.
   I've yet to hear a compliant besides yours today

Not important for sure, and I can get behind your reasoning about
Hibernate's public API being the "specification" here. All good then, not
sure who'd be consuming those headers anyways.

>
> On Thu, Dec 28, 2017 at 11:58 AM Gunnar Morling <gunnar at hibernate.org>
> wrote:
>
>> Automatic-Module-Name looks good.
>>
>> While unrelated, those look odd:
>>
>> * Main-Class: I don't think ORM - as a library - should declare this
>> * Specification-Title, Specification-Version: should these rather relate
>> to JPA title and version (as opposed to the Implementation-* ones)?
>>
>>
>> 2017-12-28 16:06 GMT+01:00 Steve Ebersole <steve at hibernate.org>:
>>
>>> After tweaking this, here is what I have...
>>>
>>> Manifest-Version: 1.0
>>> Created-By: 1.8.0_121 (Oracle Corporation)
>>> Main-Class: org.hibernate.Version
>>>
>>> Specification-Title: hibernate-core
>>> Specification-Version: 5.3
>>> Specification-Vendor: Hibernate.org
>>>
>>> Implementation-Title: hibernate-core
>>> Implementation-Version: 5.3.0.SNAPSHOT
>>> Implementation-Vendor-Id: org.hibernate
>>> Implementation-Vendor: Hibernate.org
>>> Implementation-Url: http://hibernate.org
>>>
>>> Automatic-Module-Name: org.hibernate.orm.core
>>>
>>> Bundle-ManifestVersion: 2
>>> Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version=1.8))"
>>> Tool: Bnd-3.4.0.201707252008
>>>
>>> Bundle-SymbolicName: org.hibernate.orm.core
>>> Bundle-Version: 5.3.0.SNAPSHOT
>>> Bundle-Name: hibernate-core
>>> Bundle-Description: A module of the Hibernate O/RM project
>>> Bundle-Vendor: Hibernate.org
>>> Bundle-DocURL: http://www.hibernate.org/orm/5.3
>>> Bnd-LastModified: 1513615321000
>>>
>>> Import-Package: ...
>>> Export-Package: ...
>>>
>>>
>>> Which looks great to me...
>>>
>>> On Wed, Dec 27, 2017 at 3:39 PM Steve Ebersole <steve at hibernate.org>
>>> wrote:
>>>
>>> > I had intended this for 5.3 which hasn't even gone Beta yet (we wont
>>> have
>>> > an Alpha).
>>> >
>>> > On Wed, Dec 27, 2017 at 3:38 PM Brett Meyer <brett at hibernate.org>
>>> wrote:
>>> >
>>> >> +1 from me on making them consistent.  In practice,
>>> Bundle-SymbolicName
>>> >> isn't used for much, other than a guaranteed unique identifier.  One
>>> of
>>> >> the Karaf guys pointed out that Bundle-SymbolicName is used to link a
>>> >> fragment bundle to its host bundle, but we've been able to avoid
>>> >> fragments like the plague on purpose.
>>> >>
>>> >> In practice, most users should be pulling in and interacting with our
>>> >> bundles purely through Maven artifacts or our features.xml, so a
>>> change
>>> >> would largely be unnoticed.
>>> >>
>>> >> We still might consider holding off doing that until at least a minor
>>> >> version change, since there is a potential issue for any tooling that
>>> >> might be relying on that (logging/auditing, etc.)...
>>> >>
>>> >>
>>> >> On 12/23/17 11:38 PM, Steve Ebersole wrote:
>>> >> > Another thing I was noticing was an annoying minor difference
>>> between
>>> >> the
>>> >> > OSGi bundle name and the Java 9 module name:
>>> >> >
>>> >> > Automatic-Module-Name: org.hibernate.orm.core
>>> >> > Bundle-SymbolicName: org.hibernate.core
>>> >> >
>>> >> > Does it make sense to adjust the OSGi bundle name to follow the
>>> module
>>> >> > naming?
>>> >> >
>>> >> > On Sat, Dec 23, 2017 at 8:47 AM Steve Ebersole <steve at hibernate.org
>>> >
>>> >> wrote:
>>> >> >
>>> >> >> I already did a PR for the `Automatic-Module-Name` yesterday and
>>> added
>>> >> you
>>> >> >> as a reviewer.  when you get a chance...
>>> >> >>
>>> >> >>
>>> >> >>
>>> >> >> On Sat, Dec 23, 2017 at 8:36 AM Gunnar Morling <
>>> gunnar at hibernate.org>
>>> >> >> wrote:
>>> >> >>
>>> >> >>> 2017-12-22 23:07 GMT+01:00 Steve Ebersole <steve at hibernate.org>:
>>> >> >>>
>>> >> >>>> I created a Jira to track this:
>>> >> >>>> https://hibernate.atlassian.net/browse/HHH-12188
>>> >> >>>>
>>> >> >>>> On Fri, Dec 22, 2017 at 5:33 AM Steve Ebersole <
>>> steve at hibernate.org>
>>> >> >>>> wrote:
>>> >> >>>>
>>> >> >>>>> Thanks for investigating this Gunnar.
>>> >> >>>>>
>>> >> >>>>> Some thoughts inline...
>>> >> >>>>>
>>> >> >>>>> On Wed, Dec 20, 2017 at 3:54 PM Gunnar Morling <
>>> >> gunnar at hibernate.org>
>>> >> >>>>> wrote:
>>> >> >>>>>
>>> >> >>>>>
>>> >> >>>>>> * JDK 9 comes with an incomplete JTA module
>>> (java.transaction), so
>>> >> a
>>> >> >>>>>> complete one must be provided via --upgrade-module-path (I'm
>>> using
>>> >> the
>>> >> >>>>>> 2.0.0.Alpha1 version Tomaz Cerar has created for that purpose)
>>> >> >>>>>>
>>> >> >>>>> Do you know if there is a plan to fix this in Java 9?  Seems
>>> bizarre
>>> >> >>>>> that Java 9 expects all kinds of strict modularity from
>>> libraries
>>> >> and
>>> >> >>>>> applications when the JDK itself can't follow that..
>>> >> >>>>>
>>> >> >>> The "java.transaction" module of the JDK is marked with
>>> >> >>> @Deprecated(forRemoval=true) as of Java 9, but I don't know when
>>> the
>>> >> >>> removal will happen. There's JEP 320 for this (
>>> >> >>> http://openjdk.java.net/jeps/320), which also describes why the
>>> >> module
>>> >> >>> exists in its current form. It's not scheduled for Java 10
>>> currently,
>>> >> and
>>> >> >>> given the latter is in rampdown already, I wouldn't expect this
>>> >> removal to
>>> >> >>> happen before Java 11.
>>> >> >>>
>>> >> >>>
>>> >> >>>>>> * hibernate-jpa-2.1-api-1.0.0.Final.jar can't be used as an
>>> >> automatic
>>> >> >>>>>> module, as the automatic naming algorithm stumples upon the
>>> numbers
>>> >> >>>>>> (2.1)
>>> >> >>>>>> within the module name it derives; I'm therefore using my
>>> ModiTect
>>> >> >>>>>> tooling (
>>> >> >>>>>> https://github.com/moditect/moditect/) to convert the JPA API
>>> JAR
>>> >> >>>>>> into an
>>> >> >>>>>> explicit module on the fly
>>> >> >>>>>>
>>> >> >>>>> We actually no longer use that artifact as a dependency.  Since
>>> JPA
>>> >> >>>>> 2.2, the EG publishes a "blessed" API jar which is what we use
>>> as a
>>> >> >>>>> dependency.
>>> >> >>>>>
>>> >> >>> Ah, yes, very nice. That one already defines an explicit module
>>> name
>>> >> >>> ("java.persistence") via the Automatic-Module-Name manifest entry.
>>> >> >>>
>>> >> >>>>>> * When using ByteBuddy as the byte code provider, a reads
>>> >> relationship
>>> >> >>>>>> must
>>> >> >>>>>> be added from the user's module towards hibernate.core
>>> ("requires
>>> >> >>>>>> hibernate.core"). This is due to the usage of
>>> >> >>>>>> org.hibernate.proxy.ProxyConfiguration within the generated
>>> proxy
>>> >> >>>>>> classes.
>>> >> >>>>>> Ideally no dependence to the JPA provider should be needed when
>>> >> solely
>>> >> >>>>>> working with the JPA API (as this demo does), but I'm not sure
>>> >> whether
>>> >> >>>>>> this
>>> >> >>>>>> can be avoided when using proxies (or could we construct
>>> proxies
>>> >> in a
>>> >> >>>>>> way
>>> >> >>>>>> not requiring this dependence?).
>>> >> >>>>>>
>>> >> >>>>> I'm not sure what a decent solution would be here.  Ultimately
>>> the
>>> >> >>>>> runtime needs to be able to communicate with the generated
>>> proxies
>>> >> - how
>>> >> >>>>> else would you suggest this happen?
>>> >> >>>>>
>>> >> >>> Not sure either. Maybe we could generate a dedicated interface
>>> into
>>> >> the
>>> >> >>> user's module and then inject a generated implementation -- living
>>> >> within
>>> >> >>> the ORM module -- of that interface into the entities. Worth some
>>> >> tinkering
>>> >> >>> I reckon.
>>> >> >>>
>>> >> >>>>> * When using ByteBuddy as the byte code provider, I still
>>> needed to
>>> >> have
>>> >> >>>>>> Javassist around, as it's used in
>>> ClassFileArchiveEntryHandler. I
>>> >> >>>>>> understand that eventually this should be using Jandex, but I'm
>>> >> >>>>>> wondering
>>> >> >>>>>> whether we could (temporarily) change it to use ASM instead of
>>> >> >>>>>> Javassist
>>> >> >>>>>> (at least when using ByteBuddy as byte code provider, which is
>>> >> based on
>>> >> >>>>>> ASM), so people don't need to have Javassist *and* ByteBuddy
>>> when
>>> >> >>>>>> using the
>>> >> >>>>>> latter as byte code provider? This seems desirable esp. once we
>>> >> move to
>>> >> >>>>>> ByteBuddy by default.
>>> >> >>>>>>
>>> >> >>>>> Yes, Sanne brought this up in Paris and it is something I will
>>> look
>>> >> at
>>> >> >>>>> prior to a 5.3.0.Final
>>> >> >>>>>
>>> >> >>> Excellent.
>>> >> >>>
>>> >> >>>>> * Multiple methods in ReflectHelper call setAccessible() without
>>> >> >>>>>> checking
>>> >> >>>>>> whether the method/field/constructor already is accessible. If
>>> we
>>> >> >>>>>> changed
>>> >> >>>>>> that to only call setAccessible() if actually needed, people
>>> would
>>> >> >>>>>> have to
>>> >> >>>>>> be a little bit less permissive in their module descriptor.
>>> It'd
>>> >> >>>>>> suffice
>>> >> >>>>>> for them to declare "exports com.example.entities to
>>> >> hibernate.core"
>>> >> >>>>>> instead of "opens com.example.entities to hibernate.core",
>>> unless
>>> >> they
>>> >> >>>>>> mandate (private) field access for their entities.
>>> >> >>>>>>
>>> >> >>>>> Can you open a Jira for that?
>>> >> >>>>>
>>> >> >>> Done: https://hibernate.atlassian.net/browse/HHH-12189.
>>> >> >>>
>>> >> >>>
>>> >> >>>>>> The demo is very simple (insert and load of an entity with a
>>> lazy
>>> >> >>>>>> association). If there's anything else you'd like to try out
>>> when
>>> >> >>>>>> using ORM
>>> >> >>>>>> as JPMS modules, let me know or just fork the demo and try it
>>> out
>>> >> >>>>>> yourself
>>> >> >>>>>>
>>> >> >>>>> IIUC for jars targeting both Java 8 and Java 9 we cannot
>>> include a
>>> >> >>>>> module-info file.  But we need to set the module names - you
>>> >> mentioned
>>> >> >>>>> there was a "hinting" process.  From what I could glean from
>>> >> searching
>>> >> >>>>> (which was oddly not many hits), this is achieved by adding a
>>> >> >>>>> `Automatic-Module-Name` entry in the JAR's MANIFEST.MF.
>>> Correct?
>>> >> >>>>>
>>> >> >>> Yes, exactly that's the mechanism. Jason Greene is working on a
>>> >> document
>>> >> >>> with recommendations around naming patterns, I hope it'll be
>>> >> published soon.
>>> >> >>>
>>> >> >>>
>>> >> >>>>> Also, IIRC we agreed with `org.hibernate.orm` as the base for
>>> all
>>> >> ORM
>>> >> >>>>> module names, so we'd have:
>>> >> >>>>>
>>> >> >>>>>     - org.hibernate.orm.c3p0
>>> >> >>>>>     - org.hibernate.orm.core
>>> >> >>>>>     - ...
>>> >> >>>>>
>>> >> >>>>>
>>> >> >>>>>
>>> >> >>>>>
>>> >> >>>>>
>>> >> > _______________________________________________
>>> >> > hibernate-dev mailing list
>>> >> > hibernate-dev at lists.jboss.org
>>> >> > https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>> >>
>>> >>
>>> >> _______________________________________________
>>> >> hibernate-dev mailing list
>>> >> hibernate-dev at lists.jboss.org
>>> >> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>> >
>>> >
>>> _______________________________________________
>>> hibernate-dev mailing list
>>> hibernate-dev at lists.jboss.org
>>> https://lists.jboss.org/mailman/listinfo/hibernate-dev
>>>
>>
>>


More information about the hibernate-dev mailing list