[wildfly-dev] duel between JPA use of ClassFileTransformer and CDI implicit/explicit Bean Manager (why can't we just get along)...

Scott Marlow smarlow at redhat.com
Sun Jun 9 10:22:28 EDT 2013


More inline below.  Here is part of JPA 2.1 section 3.5.1 Entity Listeners:

"
Entity listener classes in Java EE environments support dependency 
injection through the Contexts and Dependency Injection API (CDI) when 
the containing archive is a bean archive. An entity listener class that 
makes use of CDI injection may also define lifecycle callback methods 
annotated with the PostConstruct and PreDestroy annotations. These 
methods will be invoked after injection has taken place and before the 
entity listener instance is destroyed respectively.

The persistence provider is responsible for using the CDI SPI to create 
instances of the entity listener class; to perform injection upon such 
instances; to invoke their PostConstruct and PreDestroy methods, if any; 
and to dispose of the entity listener instances.

An entity listener is a noncontextual object. In supporting injection 
into entity listeners, the persistence provider must behave as if it 
carries out the following steps involving the use of the CDI SPI.

*  Obtain a BeanManager instance.

*  Create an AnnotatedType instance for the entity listener class.

*  Create an InjectionTarget instance for the annotated type.

*  Create a CreationalContext.

*  Instantiate the listener by calling the InjectionTarget produce method.

*  Inject the listener instance by calling the InjectionTarget inject 
method on the instance.

*  Invoke the PostConstruct callback, if any, by calling the 
InjectionTarget postConstruct method on the instance.


When the listener instance is to be destroyed, the persistence provider 
must behave as if it carries out the following steps.

*  Call the InjectionTarget preDestroy method on the instance.

*  Call the InjectionTarget dispose method on the instance.

*  Call the CreationalContext release method.

Persistence providers may optimize the steps above, e.g. by avoiding 
calls to the actual CDI SPI and relying on container-specific interfaces 
instead, as long as the outcome is the same.

Entity listeners that do not make use of CDI injection are stateless. 
The lifecycle of such entity listeners is unspecified.

When invoked from within a Java EE environment, the callback listeners 
for an entity share the enterprise naming context of the invoking 
component, and the entity callback methods are invoked in the 
transaction and security contexts of the calling component at the time 
at which the callback method is invoked.
"


On 06/08/2013 12:59 PM, Jason Greene wrote:
> I haven't reviewed the JPA spec changes but don't entity listeners fire on instantiation or association and not during instrumentation? If so then it seems like there shouldn't be a problem?

If Hibernate waited until the application persists/loads an entity to 
create the CDI injection targets, would that be too late for CDI to do 
its magic?

The entity listeners fire pre/post events on { persist, remove, update, 
load}.

If a CDI bean manager is available, PostConstruct and PreDestroy events 
are fired on the entity listener class. 
https://gist.github.com/scottmarlow/5743641 shows a deployment time call 
stack for hibernate invoking 
org.jboss.weld.manager.BeanManagerImpl.createInjectionTarget for an 
entity listener class.

>
> The new rules say that CDI, by default, scans only classes which have been annotated as having a scope or an EE component that has a scope. So at least entities would normally be excluded. If someone does set an attribute in beans.xml to scan all resources then it definitely would attempt to load them. At some point we should update Weld to do more up front scanning before loading (it might already do some of that). Although I don't think this is the solution, it's just something I felt like noting.

I think that we should also adopt a (JPA) two phased approach to 
bootstrapping the persistence unit (use of datasources + bean manager, 
would only be allowed in the second phase).

We might partially, solve this by using Hibernate extensions (in 
JipiJapa for using the two phase bootstrap).  However, I'm hoping for 
something better to come out of the discussion on the JPA 2.1 EG 
discussion just raised.

>
>
>
> On Jun 7, 2013, at 11:19 AM, Scott Marlow <smarlow at redhat.com> wrote:
>
>> For application deployments that use ClassFileTransformer to
>> enhance/rewrite entity classes, we start the persistence unit service
>> (PersistenceProvider.createContainerEntityManagerFactory()) during the
>> Phase.FIRST_MODULE_USE (before any application classes have been loaded).
>>
>> For application deployments that have an explicit CDI Bean Manager,
>> there is a beans.xml that means the ClassFileTransformer will not work,
>> since the CDI Bean Manager will scan all of the application classes
>> (loading them), before the persistence unit service is started (so that
>> the persistence provider can use CDI in entity listeners).
>>
>> The same is also true for implicit CDI Bean manager support [1], expect
>> all application deployments that contain an ejb3 module, will be wired
>> for CDI (meaning JPA ClassFileTransformer support will work even less).
>>
>> I raised this on the JPA 2.1 EG [2] in response to an earlier
>> discussion, about switching to a two phase approach to address problems
>> like this (didn't discuss CDI implicit support then but am raising that
>> now).
>>
>> [3] talks about why we don't create the CDI bean managers before the
>> Install phase (would cause all application classes to be read which
>> breaks JPA ClassFileTransformer use).
>>
>> [4] is for adding implicit CDI support but is blocked currently by [5].
>>
>> We can add persistence unit flags (jboss.as.jpa.classtransformer=false)
>> for disabling JPA ClassFileTransformer support as a workaround but that
>> doesn't help enough since many deployments will have implicit CDI
>> support enabled (since they contain EJB modules).  We could add a way to
>> disable implicit CDI support as another workaround for deployments that
>> want to use ClassFileTransformer.
>>
>> I'm not yet seeing a proper fix for this.  Anyone else?
>>
>> Scott
>>
>> [1] http://docs.jboss.org/cdi/spec/1.1/cdi-spec.html#bean_archive
>> [2]
>> https://java.net/projects/jpa-spec/lists/jsr338-experts/archive/2013-06/message/0
>> [3] https://issues.jboss.org/browse/WFLY-1322
>> [4] https://issues.jboss.org/browse/WFLY-476
>> [5] https://issues.jboss.org/browse/WFLY-1463
>> _______________________________________________
>> wildfly-dev mailing list
>> wildfly-dev at lists.jboss.org
>> https://lists.jboss.org/mailman/listinfo/wildfly-dev



More information about the wildfly-dev mailing list