There's a cost, particularly with Graal, in calling AprLifecycleListener.isAprAvailable(), that you pay whether or not you're using APR. Per @fhanik, the Tomcat community are moving away from APR so it might be reasonable for us to stop configuring AprLifecycleListener at all and document how users can do so themselves if they want.
Comment From: wilkinsona
Reinstating the use of APR is 4 lines of code:
@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> aprCustomizer() {
return (factory) -> factory.addContextLifecycleListeners(new AprLifecycleListener());
}
Comment From: wilkinsona
The cost is unnoticeable on HotSpot so this becomes a trade-off between improving things with Graal and making things slightly worse for APR users.
Comment From: sdeleuze
If that's only relevant on native image, my proposal would be to remove it only for that use case at build time. Something like that would be enough:
public class TomcatServletWebServerFactory extends AbstractServletWebServerFactory implements ConfigurableTomcatWebServerFactory, ResourceLoaderAware {
private static final boolean IN_NATIVE_IMAGE = (System.getProperty("org.graalvm.nativeimage.imagecode") != null);
private static List<LifecycleListener> getDefaultLifecycleListeners() {
return !IN_NATIVE_IMAGE && AprLifecycleListener.isAprAvailable() ? new ArrayList<>(Arrays.asList(new AprLifecycleListener()))
: new ArrayList<>();
}
}
Comment From: wilkinsona
Thanks, @sdeleuze. That seems like a nice compromise. It benefits Graal users while not affecting those on the regular JVM. Note that the AprLifecycleListener must be created for isAprAvailable() to work correctly. I believe this will keep things working and meet Graal's needs:
private static final boolean IN_NATIVE_IMAGE = System.getProperty("org.graalvm.nativeimage.imagecode") != null;
private static List<LifecycleListener> getDefaultLifecycleListeners() {
if (IN_NATIVE_IMAGE) {
return new ArrayList<>();
}
AprLifecycleListener aprLifecycleListener = new AprLifecycleListener();
return AprLifecycleListener.isAprAvailable() ? new ArrayList<>(Arrays.asList(aprLifecycleListener))
: new ArrayList<>();
}
Comment From: sdeleuze
Yeah I confirm that would be effective for GraalVM native code removal.