On Thu, Nov 24, 2022 at 6:15 PM Romain Manni-Bucau <rmannibu...@gmail.com> wrote: > > Le jeu. 24 nov. 2022 à 16:58, Rémy Maucherat <r...@apache.org> a écrit : > > > On Thu, Nov 24, 2022 at 10:19 AM Romain Manni-Bucau > > <rmannibu...@gmail.com> wrote: > > > > > > Le jeu. 24 nov. 2022 à 10:13, Rémy Maucherat <r...@apache.org> a écrit : > > > > > > > On Wed, Nov 23, 2022 at 11:10 AM Romain Manni-Bucau > > > > <rmannibu...@gmail.com> wrote: > > > > > > > > > > Well, it is not that simple. > > > > > > > > > > Two notes on that: > > > > > > > > > > 1. One point is the API, injector and instance manager are the exact > > same > > > > > API if you want a generic API so not sure it should be duplicated > > with > > > > > different names (or said otherwise the Injector API is not generic > > enough > > > > > to be worth a tomcat "core" change IMHO) > > > > > > > > This is indeed the same API. > > > > Tomcat standalone handles Jakarta Annotations here: > > > > > > > > > > https://github.com/apache/tomcat/blob/main/java/org/apache/catalina/core/DefaultInstanceManager.java#L174 > > > > The owb integration is supposed to do the CDI annotations on the same > > > > spot. AFAIK, it works. Except that the PostConstruct will be done > > > > later. > > > > I don't want to duplicate DefaultInstanceManager since there are a lot > > > > of privileged actions and code in there. So adding the callback on > > > > line 174 does seem fine to me. > > > > > > > > > 2. the post construct is a conflict between tomcat world and cdi > > world > > > > > there but you have the same "conflict" (= concurrent world/handling) > > for > > > > > injections, i.e. tomcat handles persistence context, persistence > > unit, > > > > > webservice ref etc but CDI can also handle it so the injector is > > either > > > > > incomplete in one case (cdi without these handling) and should be > > > > combined > > > > > between tomcat and injector OR it is done twice, potentially > > differently. > > > > > > > > > > So at the end it looks like you don't have the choice to just own the > > > > > instance manager to ensure it is done properly so making it easier to > > > > > instantiate is likely the way to go but adding an abstraction which > > is > > > > not > > > > > generic is maybe not helping as much as it can look like upfront. > > > > > > > > > > Side note: meecrowave does a more cdi instantiation: > > > > > > > > > > > https://github.com/apache/openwebbeans-meecrowave/blob/master/meecrowave-core/src/main/java/org/apache/meecrowave/tomcat/CDIInstanceManager.java > > > > > and it is very few lines so not sure the injector would help much > > more > > > > for > > > > > a tomcat-cdi integration. > > > > > > > > Sure, but the problem is that I have to keep DefaultInstanceManager > > > > around, and I won't replace everything with a CDI implementation. > > > > > > > > > > Well, in the owb module you will have to - previous impl is more about > > > letting cdi handling the postconstruct but lack the JNDI support to be > > > complete - to solve the double/conflict injection point anyway. The > > > *Injector* API does not solve it so not sure there is much space for this > > > invalid by design API :s. Did you find a way to solve it? > > > > I don't understand everything in this area. > > I tried a Servlet with a @PostConstruct. Tomcat's > > DefaultInstanceManager invokes that method. > > If OWB is active through the listener on that webapp, and processes > > that Servlet instance for injection (there's nothing to inject of > > course), then it does not invoke that @PostConstruct. Why is that ? > > Does it only do it on beans where it actually did some injection ? > > > > If you speak of the tomcat/module impl it is because it uses owb.inject > only and not the unmanaged API (or injectiontarget which is equivalent). > The issues start when you have such a bean (whatever component it is, a > servlet, filter, listener): > > public class FooComponent ... { > @Inject MyBean service; > @Resource DataSource dataSource; // from web.xml for ex > @Resource(lookup = "entries/conf)" String conf; // from context.xml for > ex > @PostConstruct void onInit() {} > @PreDestroy void onDestroy() {} > } > > Here you want: > > 1. newInstance somehow > 2.a. inject cdi instances > 2.b. inject tomcat instances > 3. postconstruct > .... > 4. predestroy > 5. release creation context if relevant (not normal scoped bean mainly) > > 2.a and b only work if you have 2 injectors (or chain the injections in > instance manager since it is equivalent) but the trick is that OWB can > handle tomcat injections - it has API/plugins for part of that - or tomcat > can handle OWB injections. > You also have the hybrid case: @Inject @Resource Foo bar; is not forbidden > by the spec and is a valid CDI case - where an extension can make @Resource > a qualifier. > So at the end, the only proper way to make this working is to make the > tomcat injections handled properly either by making tomcat aware of the CDI > model (using annotated type for ex and using it to filter out injections to > not do) or to just let CDI handle all injections importing the tomcat JNDI > support in CDI - that's what TomEE does.
Ok, so I understand the argument "not really much better". So I'll leave things as they are right now for cdi and only rework metadata-complete. Rémy > But in all cases, Injector API does not solve the injection issue and it is > likely than solving the injection issue you will end up with a > postconstruct handling which would be a one liner (thanks CDI injection > target for ex) and then just trivial to do in instance manager. > > Another not well defined case would be the exact same but using the > constructor to get injection, this is fine for CDI but guess spec > integration is vague enough to not handle it explicitly. > > > > > > Rémy > > > > > > > > > > > > > > > > Rémy > > > > > > > > > > > > > > Romain Manni-Bucau > > > > > @rmannibucau <https://twitter.com/rmannibucau> | Blog > > > > > <https://rmannibucau.metawerx.net/> | Old Blog > > > > > <http://rmannibucau.wordpress.com> | Github < > > > > https://github.com/rmannibucau> | > > > > > LinkedIn <https://www.linkedin.com/in/rmannibucau> | Book > > > > > < > > > > > > https://www.packtpub.com/application-development/java-ee-8-high-performance > > > > > > > > > > > > > > > > > > > > Le mer. 23 nov. 2022 à 10:56, Rémy Maucherat <r...@apache.org> a > > écrit : > > > > > > > > > > > On Tue, Nov 22, 2022 at 6:08 PM Romain Manni-Bucau > > > > > > <rmannibu...@gmail.com> wrote: > > > > > > > > > > > > > > Hmm, how is your injector different from an InstanceManager? ( > > > > > > > > > > > > > > > > > > > https://github.com/apache/tomcat/blob/main/java/org/apache/tomcat/InstanceManager.java > > > > > > > ) > > > > > > > Only by not having all `newInstance` flavors? > > > > > > > > > > > > The plan is to keep on using DefaultInstanceManager since OWB only > > > > > > needs a callback for injection (before PostConstruct) and destroy > > (to > > > > > > remove the instance from the map). Otherwise the whole > > InstanceManager > > > > > > has to be replaced (and done better than the current one since the > > > > > > PostConstruct calls cannot be in the right order otherwise). > > > > > > > > > > > > > Will also need the backgroundProcess (cache cleanup, same as > > instance > > > > > > > manager) and similarly the calling context (new instance > > params), in > > > > > > > particular the classloader. > > > > > > > This is why I said it sounds more like a single API and more > > hooking > > > > the > > > > > > > default instance to enable what you want or just redo it is > > likely > > > > > > simpler > > > > > > > _on an API standpoint_. > > > > > > > Guess postConstruct() method as in TomEE impl - but using tomcat > > in > > > > place > > > > > > > method, just exposing it - can be sufficient and keep the API > > clean > > > > if > > > > > > you > > > > > > > don't want to reimpl anything. > > > > > > > > > > > > This is only a callback for injection with DefaultInstanceManager. > > > > > > Implementing your own InstanceManager in TomEE is still needed and > > > > > > since it is not using DefaultInstanceManager this callback API is > > not > > > > > > available at all. Also it will not break existing InstanceManager > > > > > > implementations (even ones that extend DefaultInstanceManager), so > > > > > > that's another thing I had to consider. > > > > > > > > > > > > The user who got me into this is here: > > > > > > https://lists.apache.org/thread/1g4bpj3jnmmmxkh37qvwzoplqo65ldot > > > > > > This is about Weld, but after having a look the > > > > > > OpenWebBeansInstanceManager does the same thing. Then I realized > > > > > > unless the InstanceManager was fully replaced there would be no > > way to > > > > > > implement the proper ordering. > > > > > > > > > > > > > About JSP hack, it is more general but hits mainly JSP: it is > > about > > > > > > tomcat > > > > > > > specific JNDI injections, the workaround and wiring used > > elsewhere > > > > for > > > > > > > beans didn't work properly for JSP. Guess you don't have this > > issue > > > > but > > > > > > > something making it easier to handle can also probably be > > welcomed by > > > > > > > consumers. > > > > > > > > > > > > Ok. > > > > > > > > > > > > Rémy > > > > > > > > > > > > > > > > > > > > > > > > > > > Le mar. 22 nov. 2022 à 17:26, Rémy Maucherat <r...@apache.org> a > > > > écrit : > > > > > > > > > > > > > > > On Tue, Nov 22, 2022 at 4:30 PM Romain Manni-Bucau > > > > > > > > <rmannibu...@gmail.com> wrote: > > > > > > > > > > > > > > > > > > Hi Rémy, > > > > > > > > > > > > > > > > > > I put a few comments inline hoping it helps > > > > > > > > > > > > > > > > > > > > > > > > > > > Le mar. 22 nov. 2022 à 16:11, Rémy Maucherat < > > r...@apache.org> a > > > > > > écrit : > > > > > > > > > > > > > > > > > > > Hi, > > > > > > > > > > > > > > > > > > > > Following a post on the user list, I have looked into CDI > > and > > > > > > > > > > injection processing in Tomcat standalone (or standalone > > > > extended > > > > > > by > > > > > > > > > > CDI) and found the following issues: > > > > > > > > > > > > > > > > > > > > a) metadata-complete is done wrong. The spec got retconned > > some > > > > > > time > > > > > > > > > > ago and metadata-complete only means Servlet spec defining > > > > > > metadata, > > > > > > > > > > such as @WebServlet (= the ones that require scanning all > > > > classes > > > > > > just > > > > > > > > > > in case). So in practice inside DefaultInstanceManager the > > > > > > > > > > ignoreAnnotations flag shouldn't be used at all and it > > should > > > > > > simply > > > > > > > > > > be removed. I am ok on only doing this in 11 ;) > > > > > > > > > > > > > > > > > > > > b) CDI is not intertwined with the DefaultInstanceManager. > > > > > > Basically > > > > > > > > > > as the user said, injections should be done *before* > > > > > > @PostConstruct, > > > > > > > > > > and it . There's a (minor) problem with the > > > > DefaultInstanceManager > > > > > > > > > > API, a method needs to be protected and then integrations > > will > > > > > > then be > > > > > > > > > > able to hack inside the DefaultInstanceManager. You can see > > > > this > > > > > > here > > > > > > > > > > in the OWB integration: > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > https://github.com/apache/tomcat/blob/main/modules/owb/src/main/java/org/apache/webbeans/web/tomcat/OpenWebBeansInstanceManager.java#L102 > > > > > > > > > > (basically, first call newInstance, because there's no > > other > > > > way, > > > > > > then > > > > > > > > > > inject, but newInstance will have already invoked > > > > @PostConstruct). > > > > > > To > > > > > > > > > > fix this, I plan to add an Injector interface to > > > > > > > > > > DefaultInstanceManager since this is pretty much the only > > way > > > > to do > > > > > > > > > > this cleanly in Tomcat standalone (taking over the whole > > > > > > > > > > DefaultInstanceManager is clearly not the best idea). > > > > > > > > > > > > > > > > > > > > > > > > > > > > Yeah, TomEE ([1]) had some hard time with JSP due to that > > and its > > > > > > > > > re-implementation of the instantiation. > > > > > > > > > Basically the idea was to implement it aside Tomcat default > > impl > > > > but > > > > > > for > > > > > > > > > some classes it was not convenient enough. > > > > > > > > > That said I have to admit I'm not sure it needs a new concept > > > > > > (injector) > > > > > > > > > because basically it will copy the instance manager API > > (inject, > > > > > > release > > > > > > > > or > > > > > > > > > something like that since it is not only about the inject > > phase > > > > so > > > > > > either > > > > > > > > > you define the lifecycle or you store a Runnable you call at > > > > release > > > > > > time > > > > > > > > > too - isnt the abstraction too complex then?). > > > > > > > > > > > > > > > > For EE or some other similar embedded, the assumption was that > > > > > > > > InstanceManager would be fully reimplemented. But this is more > > work > > > > > > > > for a lighter weight integration, ok. > > > > > > > > > > > > > > > > The change to add the API to DefaultInstanceManager would be: > > > > > > > > --- a/java/org/apache/catalina/core/DefaultInstanceManager.java > > > > > > > > +++ b/java/org/apache/catalina/core/DefaultInstanceManager.java > > > > > > > > @@ -109,6 +109,7 @@ public class DefaultInstanceManager > > implements > > > > > > > > InstanceManager { > > > > > > > > new ManagedConcurrentWeakHashMap<>(); > > > > > > > > private final Map<String, String> postConstructMethods; > > > > > > > > private final Map<String, String> preDestroyMethods; > > > > > > > > + private Injector injector = null; > > > > > > > > > > > > > > > > public DefaultInstanceManager(Context context, > > > > > > > > Map<String, Map<String, String>> injectionMap, > > > > > > > > @@ -172,6 +173,9 @@ public class DefaultInstanceManager > > implements > > > > > > > > InstanceManager { > > > > > > > > Map<String, String> injections = > > > > > > > > assembleInjectionsFromClassHierarchy(clazz); > > > > > > > > populateAnnotationsCache(clazz, injections); > > > > > > > > processAnnotations(instance, injections); > > > > > > > > + if (injector != null) { > > > > > > > > + injector.inject(instance); > > > > > > > > + } > > > > > > > > postConstruct(instance, clazz); > > > > > > > > } > > > > > > > > return instance; > > > > > > > > @@ -193,6 +197,9 @@ public class DefaultInstanceManager > > implements > > > > > > > > InstanceManager { > > > > > > > > @Override > > > > > > > > public void destroyInstance(Object instance) throws > > > > > > > > IllegalAccessException, > > > > > > > > InvocationTargetException { > > > > > > > > + if (injector != null) { > > > > > > > > + injector.destroy(instance); > > > > > > > > + } > > > > > > > > if (!ignoreAnnotations) { > > > > > > > > preDestroy(instance, instance.getClass()); > > > > > > > > } > > > > > > > > @@ -828,4 +835,16 @@ public class DefaultInstanceManager > > implements > > > > > > > > InstanceManager { > > > > > > > > return loadClass(className, classLoader); > > > > > > > > } > > > > > > > > } > > > > > > > > + > > > > > > > > + public void setInjector(Injector injector) { > > > > > > > > + if (injector == null) { > > > > > > > > + this.injector = injector; > > > > > > > > + } > > > > > > > > + } > > > > > > > > + > > > > > > > > + public interface Injector { > > > > > > > > + void inject(Object instance); > > > > > > > > + void destroy(Object instance); > > > > > > > > + } > > > > > > > > + > > > > > > > > } > > > > > > > > > > > > > > > > Simply allowing inject and destroy callbacks on the main > > > > > > > > DefaultInstanceManager, which is what the OWBInstanceManager > > > > > > > > integration does (except it cannot do it in the right order for > > > > > > > > injection, which is what the user complained about). > > > > > > > > > > > > > > > > > Another issue there is that newInstance assumes a "new" which > > > > means > > > > > > you > > > > > > > > can > > > > > > > > > not use a CDI instance generally speaking, only a banalised > > > > instance > > > > > > > > which > > > > > > > > > gets injections so it means you can just impl yourself a > > > > > > > > > newInstance+whatever you want+postconstruct call (this is > > light > > > > > > > > actually). > > > > > > > > > This is where setting ignoreAnnotations would be quite fancy > > in > > > > your > > > > > > own > > > > > > > > > instance manager and wouldnt need any new API. > > > > > > > > > > > > > > > > Here it clearly relies on the behavior of > > DefaultInstanceManager. > > > > > > > > OTOH, maybe it's good to keep ignoreAnnotations as a real > > "ignore > > > > all > > > > > > > > annotations I know what I am doing", but decouple it from the > > > > > > > > matadata-complete from EE. > > > > > > > > > > > > > > > > > That said, enabling to use a CDI instance would be way more > > > > powerful > > > > > > and > > > > > > > > is > > > > > > > > > not against the spec - it is actually not specified AFAIK. > > > > > > > > > Indeed it would need a toggle on the OWBIM of Tomcat > > integration > > > > but > > > > > > it > > > > > > > > > would also open way more doors in terms of usage because your > > > > servlet > > > > > > > > > (filter, ...) is now a CDI beans with a connection to its > > bus and > > > > > > > > > interceptors. > > > > > > > > > I know it can already be done by using a container > > initializer > > > > which > > > > > > gets > > > > > > > > > beans injected and the instances directly passed to the > > > > addServlet() > > > > > > > > > (instead of the class) but it would also be a very valuable > > > > addition > > > > > > to > > > > > > > > the > > > > > > > > > module if the instantiation is reworked so I'm just > > mentionning > > > > it > > > > > > as an > > > > > > > > > opportunity. > > > > > > > > > > > > > > > > > > > > > > > > > > > [1] > > > > > > > > > > > > > > > > > > > > > > > > > > > > > https://github.com/apache/tomee/blob/main/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/JavaeeInstanceManager.java > > > > > > > > > > > > > > > > Looking at the code, it seems reasonable to have a custom > > instance > > > > > > > > manager for TomEE as it does more than simply inject. About JSP > > > > > > > > specifically, I'm not sure I understand the problem but that's > > ok. > > > > > > > > > > > > > > > > Rémy > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > The impact of fixing these for users should be > > non-existent: > > > > it is > > > > > > > > > > really a Tomcat standalone only thing impacting users with > > some > > > > > > very > > > > > > > > > > precise EE needs. A full EE integration will simply take > > over > > > > the > > > > > > > > > > whole annotation processing and instance manager from > > Tomcat, > > > > and > > > > > > > > > > hopefully do The Right Thing already. > > > > > > > > > > > > > > > > > > > > Although this is not super critical, I plan to address > > these > > > > > > issues in > > > > > > > > > > the OWB integration (after adding the needed API change in > > > > Tomcat's > > > > > > > > > > DefaultInstanceManager). > > > > > > > > > > > > > > > > > > > > Comments ? > > > > > > > > > > > > > > > > > > > > Rémy > > > > > > > > > > > > > > > > > > > > > > > > > > > > --------------------------------------------------------------------- > > > > > > > > > > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org > > > > > > > > > > For additional commands, e-mail: > > dev-h...@tomcat.apache.org > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > --------------------------------------------------------------------- > > > > > > > > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org > > > > > > > > For additional commands, e-mail: dev-h...@tomcat.apache.org > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > --------------------------------------------------------------------- > > > > > > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org > > > > > > For additional commands, e-mail: dev-h...@tomcat.apache.org > > > > > > > > > > > > > > > > > > > > --------------------------------------------------------------------- > > > > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org > > > > For additional commands, e-mail: dev-h...@tomcat.apache.org > > > > > > > > > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org > > For additional commands, e-mail: dev-h...@tomcat.apache.org > > > > --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org