I found what the issue is. This has to do with the sequence of loading of libraries/jars AND project supplied "annotation-api.jar" which declares PostConstruct annotation. The same set of annotations are also being supplied by Tomcat in an identically named JAR. Sometime during java/Tomcat startup these libraries are being loaded in a different order depending on the tomcat version. The order is reliably different and reproducible.
The conclusion is that Tomcat indeed implements Filter lifecycle annotation processing but it does not run when those annotations are loaded from the application supplied JAR. What's the recommendation on this? On Tue, Apr 5, 2022 at 11:17 AM Cherio <che...@gmail.com> wrote: > I did ran the diffs between versions. With my naked eye I didn't spot > anything obvious that in my mind would be directly related to this behavior > change. > > At the same time, when I toggle between the above mentioned Tomcat > versions the exact same application either starts successfully or fails on > PostConstruct. > > I am not stating this is a bug. It may or may not be one. Maybe it IS > supposed to process PostConstruct on filters (and maybe even other classes > and objects??) I can't classify it as a regression or a fix because I > can't find a clear description of how this should behave. > > On Tue, Apr 5, 2022 at 10:42 AM Rémy Maucherat <r...@apache.org> wrote: > >> On Tue, Apr 5, 2022 at 4:02 PM Cherio <che...@gmail.com> wrote: >> > >> > Yes, I confirm. For this project I download Tomcat from here: >> > >> https://archive.apache.org/dist/tomcat/tomcat-$MAJOR_VER/v$VER/bin/apache-tomcat-$VER.tar.gz >> > >> > BTW @PostConstruct doesn't have to do with dependency injection. It is >> > about lifecycle processing. >> > >> > The change in behavior was narrowed down to switching versions from >> 9.0.59 >> > to 9.0.60. >> >> Thanks to the effort to isolate the problem, but this is not likely: >> https://github.com/apache/tomcat/compare/9.0.59...9.0.60 >> No relevant changes, so Tomcat's annotation scanning behavior won't >> change. >> >> The DefaultInstanceManager is used, it seems it wasn't used before >> then. Since you're using Spring, maybe the problem could come from >> there ? >> >> > >> > The code that adds the filter is super simple: >> > >> > FilterRegistration.Dynamic filterName = >> > servletContext.addFilter(FILTER_NAME, filterObject); >> > >> sessionContextFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), >> > true, "/*"); >> > >> > The filter is a Spring an annotated class. in version 9.0.59 and >> > before @PostConstruct was only handled by Spring. Starting with version >> > 9.0.60, Tomcat attempts to handle PostConstruct. It produces an >> exception >> > (see below) and fails to start the application. >> > >> > 12:34:56.789 ERROR o.a.c.c.C.[.[.[/project-name] - Exception starting >> > filter [filterName] >> > java.lang.IllegalArgumentException: Invalid >> javax.annotation.PostConstruct >> >> Is the error message accurate (= is the annotation target funny ?). I >> understand that this is supposedly not Tomcat that should process the >> annotation (if you say so), but PostConstruct is from EE so there's >> likely a problem. Maybe it "used to work" but maybe that's a good hint >> too. >> >> Rémy >> >> > annotation >> > at >> > >> org.apache.catalina.core.DefaultInstanceManager.findLifecycleCallback(DefaultInstanceManager.java:719) >> > at >> > >> org.apache.catalina.core.DefaultInstanceManager.findPostConstruct(DefaultInstanceManager.java:693) >> > at >> > >> org.apache.catalina.core.DefaultInstanceManager.populateAnnotationsCache(DefaultInstanceManager.java:370) >> > at >> > >> org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:172) >> > at >> > >> org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:165) >> > at >> > >> org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:105) >> > at >> > >> org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4613) >> > at >> > >> org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5256) >> > at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) >> > at >> > >> org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396) >> > at >> > >> org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386) >> > at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) >> > at >> > >> org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) >> > at >> > >> java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) >> > at >> > >> org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919) >> > at >> > >> org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:835) >> > at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) >> > at >> > >> org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396) >> > at >> > >> org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386) >> > at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) >> > at >> > >> org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) >> > at >> > >> java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) >> > at >> > >> org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919) >> > at >> > >> org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:263) >> > at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) >> > at >> > >> org.apache.catalina.core.StandardService.startInternal(StandardService.java:432) >> > at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) >> > at >> > >> org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:927) >> > at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) >> > at org.apache.catalina.startup.Catalina.start(Catalina.java:772) >> > at >> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native >> > Method) >> > at >> > >> java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) >> > at >> > >> java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) >> > at java.base/java.lang.reflect.Method.invoke(Method.java:568) >> > at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:345) >> > at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:476) >> > >> > >> > On Sun, Apr 3, 2022 at 9:54 AM Peter Rader <p.ra...@gmx.net> wrote: >> > >> > > PostConstruct is for dependency-injection. A vanilla tomcat does no >> > > dependency injection. Can you confirm you have a vanilla tomcat? >> > > >> > > Kind regards >> > > >> > > Peter Rader >> > > -- >> > > Fachinformatiker AE / IT Software Developer >> > > Peter Rader >> > > Wilsnacker Strasse 17 >> > > 10559 Berlin - GERMANY >> > > Tel: 0049 (0)30 / 6 29 33 29 6 >> > > Fax: 0049 (0)30 / 6 29 33 29 6 >> > > Handy: 0049 (0)176 / 87 521 576 >> > > Handy: 0049 (0)176 / 47 876 303 >> > > >> > > >> > > >> > > Gesendet: Freitag, 01. April 2022 um 23:02 Uhr >> > > Von: "Cherio" <che...@gmail.com> >> > > An: users@tomcat.apache.org >> > > Betreff: PostConstruct annotation in a filter since version 9.0.60 >> > > I observed an announced change in behavior in version 9.0.60 (and >> later). >> > > >> > > My application has a Spring class loaded as a javax.servlet.Filter. >> It has >> > > a method annotated with a PostConstruct annotation. Up until Tomcat >> 9.0.59 >> > > the annotation was handled by Spring. Starting with Tomcat 9.0.60 >> behavior >> > > changed. Now Tomcat attempts to take action on that method. The >> attempt >> > > fails with "java.lang.IllegalArgumentException: Invalid >> > > javax.annotation.PostConstruct annotation" exception and that results >> in >> > > the whole application failing to start. >> > > >> > > I use PostConstruct in other Spring modules but it looks like Tomcat >> cares >> > > only about classes it deals with directly. >> > > >> > > I do not see this change documented anywhere so I assume this may be a >> > > regression or an undocumented bug fix or feature. >> > > >> > > Does anyone have more information about this? >> > > Thanks! >> > > >> > > --------------------------------------------------------------------- >> > > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org >> > > For additional commands, e-mail: users-h...@tomcat.apache.org >> > > >> > > >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org >> For additional commands, e-mail: users-h...@tomcat.apache.org >> >>