[hibernate-dev] Centralized access to "bootstrap only" resources

Sanne Grinovero sanne at hibernate.org
Tue Aug 30 07:26:50 EDT 2016

On 30 August 2016 at 10:09, Emmanuel Bernard <emmanuel at hibernate.org> wrote:
> I am not sure if that is still relevant but in the past, either HSEARCH
> or HV were keeping the ReflectionManager around to use it at runtime
> (either because metadata was loaded lazily or because of a reboot of the
> factories due to a configuration change.
> So we need to check that losing access to ReflectionManager after SF is
> created won't be problematic for these projects.

In the "dynamic reconfiguration" case we create our own
ReflectionManager instance:
 - https://github.com/hibernate/hibernate-search/blob/fd4acb5d8f396201f5dccc89ba3cbc07becea08a/engine/src/main/java/org/hibernate/search/engine/impl/IncrementalSearchConfiguration.java#L26-L35

Steve, we had a similar notion of "boot only available components" in
Search but over time we started to have various "special needs" of
various other components holding a reference on these.
When I later tried to re-instate order, it was too late and we got in
arguments like the API's intent not having been clear enough and too
much entanglement had happened.

So while I think it's a good idea, and also Search should try this
again, I think we'd need to design it from day 1 to be defensive
against future code attempting to hold on these services.
Not sure what would be the best approach for ORM, but I guess that
simply invalidating/closing these components after bootstrap and
having these throw an exception after that would be a good start.

However, please allow some flexibility for the case in which someone
really needs one of the services you're dooming at runtime.
For example Search might need to re-read configuration properties at
runtime; we can of course make a copy, but then we'd need a way to be
able to make such a copy (We currently actually make such a copy of
the cfg Properties).
Configuration properties being just an example, maybe we need a
generic way to be able to declare which services should not be cleaned
up after bootstrap?

In practice, the services you've listed should be fine today but the
need for us to make a copy (or to invoke some API to ask for a life
extension) might show up in future.

Rough proposal :

interface BootService {
  void flagForUsageBeyondBootstrap();

Such an approach would allow you to move many services into this
category quite aggressively, and extension modules beyond core could
request for the services they need for longer retention. Those who
fail to do so, would receive an exception at usage attempt beyond
bootstrap, this would hopefully trigger early awareness of design
issues during development.


> Emmanuel
> On Sun 2016-08-28 14:34, Steve Ebersole wrote:
>> We have a number of resources whose references are valid only during
>> bootstrap.  This includes things like:
>>    - ClassmateContext
>>    - JPA temp ClassLoader
>>    - Scanner and related
>>    - HCANN ReflectionManager (eventually Jandex)
>>    - etc
>> The problem is that as currently handled (via
>> MetadataBuilder/MetadataBuildingOptions) these resources actually are
>> available at runtime as well, since the MetadataBuildingOptions lives on as
>> part of the SessionFactory.
>> The idea of a "bootstrap only" ServiceRegistry has been discussed a few
>> times as a way to solve this.  That would work, except that it would
>> potentially get confusing in regards to being sure we are passing the
>> correct ServiceRegistry all the time IMO.
>> Lately I started thinking of an alternative solution: splitting up
>> MetadataBuildingOptions
>> into 2 distinct contracts: one with the same idea/scope as now, and another
>> whose lifecycle is scoped to the bootstrap process.  I am tentatively
>> calling this org.hibernate.boot.spi.BootstrapContext.
>> For the most part these changes are isolated internally.  Currently I
>> have MetadataBuilderImpl
>> building both the MetadataBuildingOptions and this new BootstrapContext.
>> Some of the applyXYZ calls on MetadataBuilder are now directed to
>> BootstrapContext instead of the MetadataBuildingOptions.
>> MetadaBuildingContext was changed to add exposing the BootstrapContext in
>> addition to the MetadataBuildingOptions.  For the most part this works very
>> well, and like I said is pretty well isolated internally.  However, it does
>> affect any existing usages of those methods removed
>> from MetadataBuildingOptions.  The biggest disconnect there so far is in
>> JpaIntegrator which tries to access the HCANN ReflectionManager during its
>> JpaIntegrator#integrate call to process entity callbacks/listeners.  With
>> JPA support being integrated into hibernate-core, we could probably work
>> around that one by consuming that bit-of-logic into the transformation of
>> InFlightMetadataCollector -> MetadataImpl.  IMO this is a "win" anyway as
>> it would allow users to leverage JPA entity callbacks/listeners in native
>> Hibernate apps as well; so this change would not necessarily be a "bad
>> thing".  Another option would be to change the signature of
>> Integrator#integrate.  To be honest it was probably always a mistake to not
>> use a "parameter object" to pass in to #integrate.
>> This also has a tie-in with the 3-phases for TypeConfiguration discussed on
>> HipChat.  To recap, TypeConfiguration (see 6.0 type system design if
>> unfamiliar with TypeConfiguration) has the following "phases":
>>    1. TypeConfiguration initialization - this is initialization of the
>>    TypeConfiguration itself.  During this phase no "context" is available to
>>    the TypeConfiguration.
>>    2. Metadata building - essentially this is the time spent transitioning
>>    from MetadataSources to Metadata.
>>    3. live SessionFactory - from the point we instantiate the
>>    SessionFactory.
>>  The first discussion here is exactly how to handle the period from the end
>> of phase 2 to the beginning of phase 3.  Ideally (from an OO encapsulation
>> perspective) we'd end the second phase after we have built the MetadataImpl
>> from the InFlight variety.  However that leaves a "gap" in terms of the
>> TypeConfiguration having any context.  The other option is to carry the
>> BootstrapContext along into the MetadataImpl, along into the
>> SessionFactoryBuilder and to release the BootstrapContext and scope the
>> TypeConfiguration to the SessionFactory only after the SF is built.  So
>> we'd still not carry that information in the SessionFactory, but we'd keep
>> it around until the SessionFactory is built.  Basically this allows types
>> and descriptors access to the scoped context (MetadataBuildingContext here
>> specifically) during that small gap of transitioning from Metadata -> SF.
>> This is what I propose we do; just want to make sure no one has objections.
>> A last part I want to consider is integrations with other Hibernate
>> projects.  Initially I spoke with Gunnar about this a lot in terms of OGM.
>> I think it is important that we allow the same paradigm we do now for
>> bootstrapping for the sake of continuity.  However I do wonder if, in terms
>> of integrations, it might also be beneficial to allow an alternate way to
>> bootstrap as well.  Gunnar, back when we developed this you had mentioned a
>> central "bootstrap delegate builder" contract.  That also could fit really
>> nicely with these new changes.  Is that something that would help OGM at
>> this point?  Or should we stick with what we have for the sake of
>> continuity?
>> Sorry this got so long, but there is a lot of discuss here :)
>> _______________________________________________
>> 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