Issue
I have a web application based on Spring boot (2.1.9.RELEASE) and using Redis server (Redis-x64-3.2.100 running as service) for Session attributes storage
The deployment in Eclipse as Spring Boot App goes well, the application can connect to Redis server and we can store/retrieve Session attributes
But when I wanted to deploy in Tomcat (version 9), I faced a problem linked to redis api in springframework :
Caused by: java.lang.LinkageError: loader constraint violation:
when resolving method "io.reactivex.Flowable.fromPublisher(Lorg/reactivestreams/Publisher;)Lio/reactivex/Flowable;"
the class loader (instance of org/apache/catalina/loader/ParallelWebappClassLoader) of the current class,
org/springframework/core/ReactiveAdapterRegistry$RxJava2Registrar, and the class loader (instance of java/net/URLClassLoader)
for the method's defining class, io/reactivex/Flowable, have different Class objects for the type org/reactivestreams/Publisher used in the signature
Given that I have set all required configuration in Tomcat server, in context.xml:
<ResourceLink name="bean/redisson"
global="bean/redisson"
type="org.redisson.api.RedissonClient" />
<Manager className="org.redisson.tomcat.JndiRedissonSessionManager"
readMode="REDIS"
jndiName="bean/redisson" />
<!-- Uncomment this to disable session persistence across Tomcat restarts -->
<!--
<Manager pathname="" />
-->
<Manager className="org.redisson.tomcat.RedissonSessionManager"
configPath="${catalina.base}/conf/redisson.yaml"
readMode="REDIS" updateMode="DEFAULT" broadcastSessionEvents="false"/>
Change in server.xml:
<Resource name="bean/redisson"
auth="Container"
factory="org.redisson.JndiRedissonFactory"
configPath="${catalina.base}/conf/redisson.yaml"
closeMethod="shutdown"/>
The redisson.yaml contains:
singleServerConfig:
idleConnectionTimeout: 10000
connectTimeout: 10000
timeout: 3000
retryAttempts: 3
retryInterval: 1500
password: null
subscriptionsPerConnection: 5
clientName: null
address: "redis://127.0.0.1:6379"
subscriptionConnectionMinimumIdleSize: 1
subscriptionConnectionPoolSize: 50
connectionMinimumIdleSize: 24
connectionPoolSize: 64
database: 0
dnsMonitoringInterval: 5000
threads: 16
nettyThreads: 32
codec: !<org.redisson.codec.FstCodec> {}
transportMode: "NIO"
And I put redisson-all-3.11.6.jar and redisson-tomcat-9-3.11.6.jar in Tomcat lib folder
Is the problem about redis vs Tomcat compatibility ? Did I miss something ? Thanks for your help in advance.
Solution
After a long examination of the issue, discovered that there are conflicts between Redis libraries and Tomcat server internal libraries
At the end, I decided to switch the session storage to JDBC and discard completely Redis :
In application.properties file
- Set the app property spring.session.store-type=jdbc
- Set the app property spring.session.jdbc.table-name=SPRING_SESSION
- Set the app property spring.jpa.hibernate.ddl-auto=none (create schema directly from an sql script)
In schema.sql file
Add two tables managing the session:
CREATE TABLE IF NOT EXISTS SPRING_SESSION (
PRIMARY_ID CHAR(36) NOT NULL,
SESSION_ID CHAR(36) NOT NULL,
CREATION_TIME BIGINT NOT NULL,
LAST_ACCESS_TIME BIGINT NOT NULL,
MAX_INACTIVE_INTERVAL INT NOT NULL,
EXPIRY_TIME BIGINT NOT NULL,
PRINCIPAL_NAME VARCHAR(100),
CONSTRAINT SPRING_SESSION_PK PRIMARY KEY (PRIMARY_ID)
);
CREATE UNIQUE INDEX IF NOT EXISTS SPRING_SESSION_IX1 ON MATFRONT.SPRING_SESSION (SESSION_ID);
CREATE INDEX IF NOT EXISTS SPRING_SESSION_IX2 ON MATFRONT.SPRING_SESSION (EXPIRY_TIME);
CREATE INDEX IF NOT EXISTS SPRING_SESSION_IX3 ON MATFRONT.SPRING_SESSION (PRINCIPAL_NAME);
CREATE TABLE IF NOT EXISTS SPRING_SESSION_ATTRIBUTES (
SESSION_PRIMARY_ID CHAR(36) NOT NULL,
ATTRIBUTE_NAME VARCHAR(200) NOT NULL,
ATTRIBUTE_BYTES BLOB NOT NULL,
CONSTRAINT SPRING_SESSION_ATTRIBUTES_PK PRIMARY KEY (SESSION_PRIMARY_ID, ATTRIBUTE_NAME),
CONSTRAINT SPRING_SESSION_ATTRIBUTES_FK FOREIGN KEY (SESSION_PRIMARY_ID) REFERENCES MATFRONT.SPRING_SESSION(PRIMARY_ID) ON DELETE CASCADE
);
Thanks to that, I got rid of an additional entire server used only for storing session data
Answered By - Shessuky