Let me clarify after the recent posts. I am talking about how to
solve the problem generally for all JPA providers. I still believe that we need a custom
integration point (2-phase etc) for Hibernate because the spec SPIs have always been
insufficient to meeting our needs.
So basically what I am saying is that we can make it all work generically by doing the
following:
1. The deployers pre-construct the module classloader which will support the new bytecode
loaded by the transformers as we already do today. (The CL returned by the JPA SPI
getClassloader).
2. JPA providers can still use getTempClassloader to preload classes for analysis
purposes *BEFORE* the CDI bean manager loads
3. To satisfy 2 and the new SPIs that allow obtaining a BM prematurely, we instead
provide a proxied, lazy-loading BM
4. The JPA provider adds all necessary transformers via the JPA SPIs *before* using the
BM
One issue is that the application persistence units can be deployed from
different concurrent threads. So, we would have to ensure that the BM
isn't used, until after all threads have registered their transformers.
5. After the transformers are added, the BM is called to initialize entity listeners, and
the BM lazily initializes itself using the module class loader in 1.
On Jun 10, 2013, at 6:16 PM, Jason Greene <jason.greene(a)redhat.com> wrote:
> Well it just needs to load it after the transformer is added, and from the non-temp
class-loader. So basically I was saying the spec forces the JPA provider to follow that
kind of order.
>
>
> On Jun 10, 2013, at 5:35 PM, Stuart Douglas <stuart.w.douglas(a)gmail.com>
wrote:
>
>> The thing is that the CDI specification *requires* us to load the entity classes,
there is simply no way around it. Because we have to fire a ProcessAnnotatedType<T>
for the entity class (with T being the entity class) there is no way to fire this event
without loading the entity class. Any CDI implementation will run into this, it is not
specific to Wildfly.
>>
>> The only way to get around this is basically making sure that entities are not
made into CDI beans, so vetoing them as Jozef said, or packing them into their own JAR,
neither of which is a good solution.
>>
>> Basically the JPA spec is broken, it can't deal with both CDI and class
transformation, and we need to hack around it somehow.
>>
>> Stuart
>>
>>
>>
>> Steve Ebersole wrote:
>>> So you'd like JPA providers to read the JPA spec in a special
"WildFly
>>> light" wrt these quoted sections? Put aside your understanding that
>>> WildFly suffers from this particular problem and point out the JPA spec
>>> passages that say I need to delay using that BeanManager. In fact, I'd
>>> argue the wording implies that the BeanManager should be usable
>>> immediately upon being passed to the JPA provider.
>>>
>>> On the flip side, is it possible that other containers might *only*
>>> make the BeanManager available during bootstrap?
>>>
>>> As for WildFly+Hibernate, I have already provided hooks to make sure
>>> this can be done properly (albeit in non-spec way) as outlined in
>>> earlier response.
>>>
>>>
>>> On Mon 10 Jun 2013 04:54:22 PM CDT, Jason Greene wrote:
>>>> Right but my point is if the entities aren't instantiated, there is
nothing for the listener to listen for, and it can be delayed up until that point in the
deployment process.
>>>>
>>>> It seems that the only hard ordering, is that the bean manager be created
on top of PersistenceUnitInfo.getClassLoader().
>>>>
>>>> On Jun 10, 2013, at 4:41 PM, Steve Ebersole<steve(a)hibernate.org>
wrote:
>>>>
>>>>> We are talking about entity listeners, not entities. Entities can be
annotated with callback methods as well, but those are not supported (by spec) for CDI
injection.
>>>>>
>>>>> BTW, for those maybe not familiar... The relevant sections in the JPA
spec are:
>>>>>
>>>>> 9.1 Java EE Deployment. In this section, it discusses the
expectations of the container. In the part that discusses the call to
createContainerEntityManagerFactory (aka, bootstrapping an EntityManagerFactory) it says:
>>>>>
>>>>> <quote>
>>>>> If CDI is enabled, a BeanManager instance must be made available by
the container. The
>>>>> container is responsible for passing this BeanManager instance via
the map that is passed as
>>>>> an argument to the createContainerEntityManagerFactory call. The map
key
>>>>> used must be the standard property name
javax.persistence.bean.manager.
>>>>> </quote>
>>>>>
>>>>> And then, 3.5.1 Entity Listeners, as partially quote by Scott
earlier.
>>>>>
>>>>>
>>>>> On Mon 10 Jun 2013 03:46:01 PM CDT, Jason Greene wrote:
>>>>>> I guess the point I am still not clear on is exactly when the
entities are instantiated. My understanding is that the earliest a user can cause a JPA
impl load them is inside a PostConstruct method. That is unless JPA providers load
instances for some kind of caching purposes?
>>>>>>
>>>>>> On Jun 10, 2013, at 12:25 PM, Steve
Ebersole<steve(a)hibernate.org> wrote:
>>>>>>
>>>>>>> As Scott stated, Hibernate is doing the CDI calls as part of
the
>>>>>>> EntityManagerFactory bootstrap (however that translates to
WildFly
>>>>>>> deployment phases...). There is a difficulty with delaying
these CDI
>>>>>>> calls. Getting around that would require either:
>>>>>>> 1) a 2-phase bootstrap process for the EntityManagerFactory.
Even
>>>>>>> though that proposal was not accepted into the JPA spec, I
went ahead
>>>>>>> and broke out Hibernate's bootstrapping into a 2-phase
process, so
>>>>>>> WildFly (via jipijapa) could leverage that.
>>>>>>> 2) Creating proxies of the listeners that delegate to the
real listeners
>>>>>>> and perform the init on first call. Ugh. Proxies calling
proxies
>>>>>>> calling proxies... not a recipe for great performance. Not
to mention
>>>>>>> don't call me to debug through that mess
>>>>>>>
>>>>>>> There is a third option. How entity listeners are built is
hidden
>>>>>>> behind an interface (called ListenerFactory oddly enough). I
can expose
>>>>>>> that as an integration point for WildFly to be able to plug
in whatever
>>>>>>> "delayed init" scheme it deems appropriate. The
only reason I'd suggest
>>>>>>> this is if y'all feel strongly about option 2 above
(I'm not comfortable
>>>>>>> implementing that in the Hibernate code base). But my vote
would be for
>>>>>>> the first option.
>>>>>>>
>>>>>>> I am open to other suggestions.
>>>>>>>
>>>>>>>
>>>>>>> On 06/10/2013 02:10 AM, Jozef Hartinger wrote:
>>>>>>>> Weld can be started before a JPA impl without a risk of
suppressing
>>>>>>>> ClassFileTransformers under condition that all entities
are annotated
>>>>>>>> with @Vetoed. We could document that as a requirement.
>>>>>>>>
>>>>>>>> On 06/07/2013 06:20 PM, Scott Marlow 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/m...
>>>>>>>>> [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(a)lists.jboss.org
>>>>>>>>>
https://lists.jboss.org/mailman/listinfo/wildfly-dev
>>>>>>>> _______________________________________________
>>>>>>>> wildfly-dev mailing list
>>>>>>>> wildfly-dev(a)lists.jboss.org
>>>>>>>>
https://lists.jboss.org/mailman/listinfo/wildfly-dev
>>>>>>> _______________________________________________
>>>>>>> wildfly-dev mailing list
>>>>>>> wildfly-dev(a)lists.jboss.org
>>>>>>>
https://lists.jboss.org/mailman/listinfo/wildfly-dev
>>>>>> --
>>>>>> Jason T. Greene
>>>>>> WildFly Lead / JBoss EAP Platform Architect
>>>>>> JBoss, a division of Red Hat
>>>>>>
>>>> --
>>>> Jason T. Greene
>>>> WildFly Lead / JBoss EAP Platform Architect
>>>> JBoss, a division of Red Hat
>>>>
>>> _______________________________________________
>>> wildfly-dev mailing list
>>> wildfly-dev(a)lists.jboss.org
>>>
https://lists.jboss.org/mailman/listinfo/wildfly-dev
>
> --
> Jason T. Greene
> WildFly Lead / JBoss EAP Platform Architect
> JBoss, a division of Red Hat
>
>
> _______________________________________________
> wildfly-dev mailing list
> wildfly-dev(a)lists.jboss.org
>
https://lists.jboss.org/mailman/listinfo/wildfly-dev
--
Jason T. Greene
WildFly Lead / JBoss EAP Platform Architect
JBoss, a division of Red Hat
_______________________________________________
wildfly-dev mailing list
wildfly-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/wildfly-dev