Skip to content

Support tomcat-coyote-ffm for native ssl with embedded Tomcat #50100

@philsttr

Description

@philsttr

Enhancement Request

I would like for Spring Boot to provide first-class support for autoconfiguring tomcat-coyote-ffm for native ssl without using APR or tomcat-native.

Background

Setting up APR and tomcat-native is somewhat complicated, and difficult to "get right".

Tomcat recently introduced a new tomcat-coyote-ffm module, which allows using native ssl without requiring APR or tomcat-native. Internally tomcat-coyote-ffm uses Java's Foreign Function & Memory API to directly call libssl.

Spring Boot currently has first-class autoconfiguration support for native ssl using APR and tomcat-native, but does not offer first-class support for tomcat-coyote-ffm.

Currently, it is possible to enable tomcat-coyote-ffm in a Spring Boot app with embedded Tomcat, but it is not intuitive or documented anywhere.

It would be great if Spring Boot provided first-class support for using tomcat-coyote-ffm.

The current situation

Enabling tomcat-coyote-ffm in a Spring Boot app with embedded Tomcat today is not intuitive.

The typical way to enable tomcat-coyote-ffm module is by registering a OpenSSLLifecycleListener lifecycle listener on Tomcat's Server object (as described in the tomcat docs).

Spring Boot does not provide direct access to embedded Tomcat's Server object, so subclassing TomcatServletWebServerFactory is required.

public class FfmOpenSslTomcatServletWebServerFactory extends TomcatServletWebServerFactory {

	@Override
	protected Tomcat createTomcat() {
		Tomcat tomcat = super.createTomcat();
		tomcat.getServer().addLifecycleListener(new OpenSSLLifecycleListener());
		return tomcat;
	}
}

Then, declare the FfmOpenSslTomcatServletWebServerFactory bean:

@Configuration(proxyBeanMethods = false)
public class TomcatFfmOpenSslConfig {

	@Bean
	public TomcatServletWebServerFactory tomcatServletWebServerFactory() {
		return new FfmOpenSslTomcatServletWebServerFactory();
	}
}

And also add a dependency on tomcat-coyote-ffm, while excluding the non-embedded Tomcat transitive dependencies (side note: this Tomcat feature request should help this situation).

		<!--
			tomcat-coyote-ffm provides the FFM/panama-based OpenSSL integration
			(org.apache.tomcat.util.net.openssl.panama.*) used by
			org.apache.catalina.core.OpenSSLLifecycleListener (which lives in
			tomcat-embed-core). This replaces tomcat-native / APR for OpenSSL.
			Its transitive deps (tomcat-coyote / tomcat-juli / tomcat-util) are
			excluded because tomcat-embed-core already ships those classes under
			the same FQCNs; keeping both would put duplicate classes on the
			classpath.
		-->
		<dependency>
			<groupId>org.apache.tomcat</groupId>
			<artifactId>tomcat-coyote-ffm</artifactId>
			<version>${tomcat.version}</version>
			<exclusions>
				<exclusion>
					<groupId>org.apache.tomcat</groupId>
					<artifactId>tomcat-coyote</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.apache.tomcat</groupId>
					<artifactId>tomcat-juli</artifactId>
				</exclusion>
				<exclusion>
					<groupId>org.apache.tomcat</groupId>
					<artifactId>tomcat-util</artifactId>
				</exclusion>
			</exclusions>
		</dependency>

Desired solution

I'd like Spring Boot to be able to auto-configure tomcat-coyote-ffm if it is available on the classpath. Specifically, if org.apache.tomcat.util.net.openssl.panama.OpenSSLLibrary is on the classpath, then add a OpenSSLLifecycleListener to Tomcat's Server object.

Perhaps add a tomcat.server.use-ffm property, parallel to tomcat.server.use-apr.

Alternatively, if direct support for tomcat-coyote-ffm cannot be provided... at least provide the ability to register a lifecycle listener on Tomcat's Server object, so that subclassing TomcatServletWebServerFactory is not required. (Note that it is currently possible to access the Context object to add a lifecycle listener, but not the Server object).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions