1

We've been using the tomcat jvmroute property to support session affinity (yes, we hope to move away from this sometime).

When I use spring boot 1.3.7, the jvmroute value is appended to the jsessionid (still with tomcat 8.x). But for some reason spring boot 1.4.0 doesn't.

I'm pretty sure this is not a tomcat issue because this still doesn't work even when I downgrade to tomcat 7. Also, I've debugged the apache StandardEngine class and can see the jvmroute property being applied in tomcat 8.x. Yet somehow the jseesionid cookie isn't getting the correct value in spring boot 1.4.0.


@SpringBootApplication
@RestController
public class TomcatJvmrouteApplication {

public static void main(String[] args) {
    System.setProperty("jvmRoute", "testjvmroute");
    SpringApplication.run(TomcatJvmrouteApplication.class, args);
}

@RequestMapping("/info")
public String getInfo(@Value("${jvmRoute}") String route, HttpSession session,
        @CookieValue("JSESSIONID") String cookie) {
    String jsessionId = cookie == null ? "" : new String(cookie.getBytes());
    return "Jvmroute should be: " + route + " <br/> Jsessionid is:" + jsessionId;
}

}

Project pom:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>demo.tomcat</groupId>
    <artifactId>jvmroute-demo</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>tomcat-jvmroute</name>
    <description>demo jvmroute issues</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.0.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>
gyoder
  • 4,530
  • 5
  • 29
  • 37

2 Answers2

1

This is a bug in spring boot 1.4.0, see this issue: https://github.com/spring-projects/spring-boot/issues/6679

Here's the 1.4.0 workaround posted by Andy Wilkinson. Just add this bean to your application context.

@Bean
public EmbeddedServletContainerCustomizer tomcatCustomizer() {
    return (container) -> {
        if (container instanceof TomcatEmbeddedServletContainerFactory) {
            ((TomcatEmbeddedServletContainerFactory) container).addContextCustomizers((context) -> {
                context.addLifecycleListener((event) -> {
                    if (event.getType().equals(Lifecycle.START_EVENT)) {
                        ((Context) event.getSource()).getManager().getSessionIdGenerator()
                                .setJvmRoute(((ManagerBase) context.getManager()).getJvmRoute());
                    }
                });
            });
        }
    };
}
gyoder
  • 4,530
  • 5
  • 29
  • 37
0

I'm using Spring Boot 2.0.4. I had to do it this way:

@Bean
public WebServerFactoryCustomizer<TomcatServletWebServerFactory> servletContainer() {
    return (tomcat) -> {

        tomcat.addContextCustomizers((context) -> {
            Manager manager = context.getManager();
            if (manager == null) {
                manager = new StandardManager();
                context.setManager(manager);
            }

            ((ManagerBase) context.getManager()).getEngine().setJvmRoute("tomcatJvmRoute");

        });
    };
}

My original answer

FourtyTwo
  • 734
  • 8
  • 19