From 228319d656951d18c881c72666339213a8ba2eba Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Wed, 16 Jan 2019 21:10:24 +0300 Subject: [PATCH 1/3] Compilation fixed --- redisson/src/main/java/org/redisson/cache/LocalCacheView.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redisson/src/main/java/org/redisson/cache/LocalCacheView.java b/redisson/src/main/java/org/redisson/cache/LocalCacheView.java index b3352ea54..591623cb6 100644 --- a/redisson/src/main/java/org/redisson/cache/LocalCacheView.java +++ b/redisson/src/main/java/org/redisson/cache/LocalCacheView.java @@ -185,7 +185,7 @@ public class LocalCacheView { if (o instanceof Map.Entry) { Map.Entry e = (Map.Entry) o; CacheKey cacheKey = toCacheKey(e.getKey()); - return cache.remove(cacheKey, new CacheValue(e.getKey(), e.getValue())); + return cache.remove(cacheKey) != null; } return false; } From ae14dba2fcd3150493a00f1cb97af6620745da70 Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Thu, 17 Jan 2019 10:18:00 +0300 Subject: [PATCH 2/3] Fixed - RedissonSessionManager throws java.lang.ClassNotFoundException if readMode=MEMORY #1867 --- .../org/redisson/tomcat/AttributeMessage.java | 28 +++++++++++++--- .../tomcat/AttributeRemoveMessage.java | 5 --- .../tomcat/AttributeUpdateMessage.java | 18 ++++------- .../tomcat/AttributesClearMessage.java | 4 --- .../tomcat/AttributesPutAllMessage.java | 32 +++++++++++++------ .../org/redisson/tomcat/RedissonSession.java | 13 ++++++-- .../tomcat/RedissonSessionManager.java | 17 +++++++--- .../org/redisson/tomcat/AttributeMessage.java | 28 +++++++++++++--- .../tomcat/AttributeRemoveMessage.java | 5 --- .../tomcat/AttributeUpdateMessage.java | 18 ++++------- .../tomcat/AttributesClearMessage.java | 4 --- .../tomcat/AttributesPutAllMessage.java | 32 +++++++++++++------ .../org/redisson/tomcat/RedissonSession.java | 15 +++++++-- .../tomcat/RedissonSessionManager.java | 17 +++++++--- .../org/redisson/tomcat/AttributeMessage.java | 28 +++++++++++++--- .../tomcat/AttributeRemoveMessage.java | 5 --- .../tomcat/AttributeUpdateMessage.java | 18 ++++------- .../tomcat/AttributesClearMessage.java | 4 --- .../tomcat/AttributesPutAllMessage.java | 32 +++++++++++++------ .../org/redisson/tomcat/RedissonSession.java | 13 ++++++-- .../tomcat/RedissonSessionManager.java | 13 ++++++-- .../org/redisson/tomcat/AttributeMessage.java | 28 +++++++++++++--- .../tomcat/AttributeRemoveMessage.java | 5 --- .../tomcat/AttributeUpdateMessage.java | 18 ++++------- .../tomcat/AttributesClearMessage.java | 4 --- .../tomcat/AttributesPutAllMessage.java | 32 +++++++++++++------ .../org/redisson/tomcat/RedissonSession.java | 13 ++++++-- .../tomcat/RedissonSessionManager.java | 17 +++++++--- 28 files changed, 306 insertions(+), 160 deletions(-) diff --git a/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributeMessage.java b/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributeMessage.java index 677f0b54a..68a36ca1b 100644 --- a/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributeMessage.java +++ b/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributeMessage.java @@ -15,8 +15,14 @@ */ package org.redisson.tomcat; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; import java.io.Serializable; +import org.apache.catalina.util.CustomObjectInputStream; + /** * * @author Nikita Koksharov @@ -31,10 +37,6 @@ public class AttributeMessage implements Serializable { public AttributeMessage() { } - public AttributeMessage(String sessionId) { - this.sessionId = sessionId; - } - public AttributeMessage(String nodeId, String sessionId) { this.nodeId = nodeId; this.sessionId = sessionId; @@ -48,4 +50,22 @@ public class AttributeMessage implements Serializable { return nodeId; } + protected byte[] toByteArray(Object value) throws IOException { + if (value == null) { + return null; + } + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(bos); + out.writeObject(value); + out.flush(); + return bos.toByteArray(); + } + + protected Object toObject(ClassLoader classLoader, byte[] value) throws IOException, ClassNotFoundException { + if (value == null) { + return null; + } + CustomObjectInputStream in = new CustomObjectInputStream(new ByteArrayInputStream(value), classLoader); + return in.readObject(); + } } diff --git a/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributeRemoveMessage.java b/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributeRemoveMessage.java index 1ace1f96f..191b317b8 100644 --- a/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributeRemoveMessage.java +++ b/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributeRemoveMessage.java @@ -28,11 +28,6 @@ public class AttributeRemoveMessage extends AttributeMessage { super(); } - public AttributeRemoveMessage(String sessionId, String name) { - super(sessionId); - this.name = name; - } - public AttributeRemoveMessage(String nodeId, String sessionId, String name) { super(nodeId, sessionId); this.name = name; diff --git a/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributeUpdateMessage.java b/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributeUpdateMessage.java index 295e104eb..ed679614b 100644 --- a/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributeUpdateMessage.java +++ b/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributeUpdateMessage.java @@ -15,6 +15,8 @@ */ package org.redisson.tomcat; +import java.io.IOException; + /** * * @author Nikita Koksharov @@ -23,29 +25,23 @@ package org.redisson.tomcat; public class AttributeUpdateMessage extends AttributeMessage { private String name; - private Object value; + private byte[] value; public AttributeUpdateMessage() { } - public AttributeUpdateMessage(String sessionId, String name, Object value) { - super(sessionId); - this.name = name; - this.value = value; - } - - public AttributeUpdateMessage(String nodeId, String sessionId, String name, Object value) { + public AttributeUpdateMessage(String nodeId, String sessionId, String name, Object value) throws IOException { super(nodeId, sessionId); this.name = name; - this.value = value; + this.value = toByteArray(value); } public String getName() { return name; } - public Object getValue() { - return value; + public Object getValue(ClassLoader classLoader) throws IOException, ClassNotFoundException { + return toObject(classLoader, value); } } diff --git a/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributesClearMessage.java b/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributesClearMessage.java index 7c1895fb6..66d348452 100644 --- a/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributesClearMessage.java +++ b/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributesClearMessage.java @@ -25,10 +25,6 @@ public class AttributesClearMessage extends AttributeMessage { public AttributesClearMessage() { } - public AttributesClearMessage(String sessionId) { - super(sessionId); - } - public AttributesClearMessage(String nodeId, String sessionId) { super(nodeId, sessionId); } diff --git a/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributesPutAllMessage.java b/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributesPutAllMessage.java index 085aee8d5..c91390d63 100644 --- a/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributesPutAllMessage.java +++ b/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/AttributesPutAllMessage.java @@ -15,7 +15,10 @@ */ package org.redisson.tomcat; +import java.io.IOException; +import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; /** * @@ -24,23 +27,32 @@ import java.util.Map; */ public class AttributesPutAllMessage extends AttributeMessage { - private Map attrs; + private Map attrs; public AttributesPutAllMessage() { } - public AttributesPutAllMessage(String sessionId, Map attrs) { - super(sessionId); - this.attrs = attrs; - } - - public AttributesPutAllMessage(String nodeId, String sessionId, Map attrs) { + public AttributesPutAllMessage(String nodeId, String sessionId, Map attrs) throws IOException { super(nodeId, sessionId); - this.attrs = attrs; + if (attrs != null) { + this.attrs = new HashMap(); + for (Entry entry: attrs.entrySet()) { + this.attrs.put(entry.getKey(), toByteArray(entry.getValue())); + } + } else { + this.attrs = null; + } } - public Map getAttrs() { - return attrs; + public Map getAttrs(ClassLoader classLoader) throws IOException, ClassNotFoundException { + if (attrs == null) { + return null; + } + Map result = new HashMap(); + for (Entry entry: attrs.entrySet()) { + result.put(entry.getKey(), toObject(classLoader, entry.getValue())); + } + return result; } } diff --git a/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/RedissonSession.java b/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/RedissonSession.java index 8d795105f..a1f0bfa39 100644 --- a/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/RedissonSession.java +++ b/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/RedissonSession.java @@ -15,6 +15,7 @@ */ package org.redisson.tomcat; +import java.io.IOException; import java.lang.reflect.Field; import java.util.Arrays; import java.util.HashMap; @@ -132,7 +133,11 @@ public class RedissonSession extends StandardSession { for (Entry entry : newMap.entrySet()) { map.put(entry.getKey(), entry.getValue()); } - return new AttributesPutAllMessage(redissonManager.getNodeId(), getId(), map); + try { + return new AttributesPutAllMessage(redissonManager.getNodeId(), getId(), map); + } catch (IOException e) { + throw new IllegalStateException(e); + } } @Override @@ -148,7 +153,11 @@ public class RedissonSession extends StandardSession { private void fastPut(String name, Object value) { map.fastPut(name, value); if (readMode == ReadMode.MEMORY) { - topic.publish(new AttributeUpdateMessage(redissonManager.getNodeId(), getId(), name, value)); + try { + topic.publish(new AttributeUpdateMessage(redissonManager.getNodeId(), getId(), name, value)); + } catch (IOException e) { + throw new IllegalStateException(e); + } } } diff --git a/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/RedissonSessionManager.java b/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/RedissonSessionManager.java index ee4e48dbc..c138679fb 100644 --- a/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/RedissonSessionManager.java +++ b/redisson-tomcat/redisson-tomcat-6/src/main/java/org/redisson/tomcat/RedissonSessionManager.java @@ -158,7 +158,9 @@ public class RedissonSessionManager extends ManagerBase implements Lifecycle { } public RTopic getTopic() { - return redisson.getTopic("redisson:tomcat_session_updates:" + container.getName()); + String separator = keyPrefix == null || keyPrefix.isEmpty() ? "" : ":"; + final String name = keyPrefix + separator + "redisson:tomcat_session_updates:" + ((Context) getContainer()).getName(); + return redisson.getTopic(name); } @Override @@ -228,6 +230,13 @@ public class RedissonSessionManager extends ManagerBase implements Lifecycle { public void start() throws LifecycleException { redisson = buildClient(); + final ClassLoader applicationClassLoader; + if (Thread.currentThread().getContextClassLoader() != null) { + applicationClassLoader = Thread.currentThread().getContextClassLoader(); + } else { + applicationClassLoader = getClass().getClassLoader(); + } + if (updateMode == UpdateMode.AFTER_REQUEST) { getEngine().getPipeline().addValve(new UpdateValve(this)); } @@ -252,17 +261,17 @@ public class RedissonSessionManager extends ManagerBase implements Lifecycle { if (msg instanceof AttributesPutAllMessage) { AttributesPutAllMessage m = (AttributesPutAllMessage) msg; - for (Entry entry : m.getAttrs().entrySet()) { + for (Entry entry : m.getAttrs(applicationClassLoader).entrySet()) { session.superSetAttribute(entry.getKey(), entry.getValue(), true); } } if (msg instanceof AttributeUpdateMessage) { AttributeUpdateMessage m = (AttributeUpdateMessage)msg; - session.superSetAttribute(m.getName(), m.getValue(), true); + session.superSetAttribute(m.getName(), m.getValue(applicationClassLoader), true); } } - } catch (IOException e) { + } catch (Exception e) { log.error("Can't handle topic message", e); } } diff --git a/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributeMessage.java b/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributeMessage.java index 677f0b54a..68a36ca1b 100644 --- a/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributeMessage.java +++ b/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributeMessage.java @@ -15,8 +15,14 @@ */ package org.redisson.tomcat; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; import java.io.Serializable; +import org.apache.catalina.util.CustomObjectInputStream; + /** * * @author Nikita Koksharov @@ -31,10 +37,6 @@ public class AttributeMessage implements Serializable { public AttributeMessage() { } - public AttributeMessage(String sessionId) { - this.sessionId = sessionId; - } - public AttributeMessage(String nodeId, String sessionId) { this.nodeId = nodeId; this.sessionId = sessionId; @@ -48,4 +50,22 @@ public class AttributeMessage implements Serializable { return nodeId; } + protected byte[] toByteArray(Object value) throws IOException { + if (value == null) { + return null; + } + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(bos); + out.writeObject(value); + out.flush(); + return bos.toByteArray(); + } + + protected Object toObject(ClassLoader classLoader, byte[] value) throws IOException, ClassNotFoundException { + if (value == null) { + return null; + } + CustomObjectInputStream in = new CustomObjectInputStream(new ByteArrayInputStream(value), classLoader); + return in.readObject(); + } } diff --git a/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributeRemoveMessage.java b/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributeRemoveMessage.java index 1ace1f96f..191b317b8 100644 --- a/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributeRemoveMessage.java +++ b/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributeRemoveMessage.java @@ -28,11 +28,6 @@ public class AttributeRemoveMessage extends AttributeMessage { super(); } - public AttributeRemoveMessage(String sessionId, String name) { - super(sessionId); - this.name = name; - } - public AttributeRemoveMessage(String nodeId, String sessionId, String name) { super(nodeId, sessionId); this.name = name; diff --git a/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributeUpdateMessage.java b/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributeUpdateMessage.java index 295e104eb..ed679614b 100644 --- a/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributeUpdateMessage.java +++ b/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributeUpdateMessage.java @@ -15,6 +15,8 @@ */ package org.redisson.tomcat; +import java.io.IOException; + /** * * @author Nikita Koksharov @@ -23,29 +25,23 @@ package org.redisson.tomcat; public class AttributeUpdateMessage extends AttributeMessage { private String name; - private Object value; + private byte[] value; public AttributeUpdateMessage() { } - public AttributeUpdateMessage(String sessionId, String name, Object value) { - super(sessionId); - this.name = name; - this.value = value; - } - - public AttributeUpdateMessage(String nodeId, String sessionId, String name, Object value) { + public AttributeUpdateMessage(String nodeId, String sessionId, String name, Object value) throws IOException { super(nodeId, sessionId); this.name = name; - this.value = value; + this.value = toByteArray(value); } public String getName() { return name; } - public Object getValue() { - return value; + public Object getValue(ClassLoader classLoader) throws IOException, ClassNotFoundException { + return toObject(classLoader, value); } } diff --git a/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributesClearMessage.java b/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributesClearMessage.java index 7c1895fb6..66d348452 100644 --- a/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributesClearMessage.java +++ b/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributesClearMessage.java @@ -25,10 +25,6 @@ public class AttributesClearMessage extends AttributeMessage { public AttributesClearMessage() { } - public AttributesClearMessage(String sessionId) { - super(sessionId); - } - public AttributesClearMessage(String nodeId, String sessionId) { super(nodeId, sessionId); } diff --git a/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributesPutAllMessage.java b/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributesPutAllMessage.java index 085aee8d5..c91390d63 100644 --- a/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributesPutAllMessage.java +++ b/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/AttributesPutAllMessage.java @@ -15,7 +15,10 @@ */ package org.redisson.tomcat; +import java.io.IOException; +import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; /** * @@ -24,23 +27,32 @@ import java.util.Map; */ public class AttributesPutAllMessage extends AttributeMessage { - private Map attrs; + private Map attrs; public AttributesPutAllMessage() { } - public AttributesPutAllMessage(String sessionId, Map attrs) { - super(sessionId); - this.attrs = attrs; - } - - public AttributesPutAllMessage(String nodeId, String sessionId, Map attrs) { + public AttributesPutAllMessage(String nodeId, String sessionId, Map attrs) throws IOException { super(nodeId, sessionId); - this.attrs = attrs; + if (attrs != null) { + this.attrs = new HashMap(); + for (Entry entry: attrs.entrySet()) { + this.attrs.put(entry.getKey(), toByteArray(entry.getValue())); + } + } else { + this.attrs = null; + } } - public Map getAttrs() { - return attrs; + public Map getAttrs(ClassLoader classLoader) throws IOException, ClassNotFoundException { + if (attrs == null) { + return null; + } + Map result = new HashMap(); + for (Entry entry: attrs.entrySet()) { + result.put(entry.getKey(), toObject(classLoader, entry.getValue())); + } + return result; } } diff --git a/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/RedissonSession.java b/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/RedissonSession.java index e0f561226..0cd0156a3 100644 --- a/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/RedissonSession.java +++ b/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/RedissonSession.java @@ -15,6 +15,7 @@ */ package org.redisson.tomcat; +import java.io.IOException; import java.lang.reflect.Field; import java.util.Arrays; import java.util.HashMap; @@ -55,7 +56,7 @@ public class RedissonSession extends StandardSession { private final RedissonSessionManager.ReadMode readMode; private final UpdateMode updateMode; - public RedissonSession(RedissonSessionManager manager, ReadMode readMode, UpdateMode updateMode) { + public RedissonSession(RedissonSessionManager manager, RedissonSessionManager.ReadMode readMode, UpdateMode updateMode) { super(manager); this.redissonManager = manager; this.readMode = readMode; @@ -132,7 +133,11 @@ public class RedissonSession extends StandardSession { for (Entry entry : newMap.entrySet()) { map.put(entry.getKey(), entry.getValue()); } - return new AttributesPutAllMessage(redissonManager.getNodeId(), getId(), map); + try { + return new AttributesPutAllMessage(redissonManager.getNodeId(), getId(), map); + } catch (IOException e) { + throw new IllegalStateException(e); + } } @Override @@ -148,7 +153,11 @@ public class RedissonSession extends StandardSession { private void fastPut(String name, Object value) { map.fastPut(name, value); if (readMode == ReadMode.MEMORY) { - topic.publish(new AttributeUpdateMessage(redissonManager.getNodeId(), getId(), name, value)); + try { + topic.publish(new AttributeUpdateMessage(redissonManager.getNodeId(), getId(), name, value)); + } catch (IOException e) { + throw new IllegalStateException(e); + } } } diff --git a/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/RedissonSessionManager.java b/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/RedissonSessionManager.java index ff582b73a..7f95e4184 100644 --- a/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/RedissonSessionManager.java +++ b/redisson-tomcat/redisson-tomcat-7/src/main/java/org/redisson/tomcat/RedissonSessionManager.java @@ -137,7 +137,9 @@ public class RedissonSessionManager extends ManagerBase { } public RTopic getTopic() { - return redisson.getTopic("redisson:tomcat_session_updates:" + container.getName()); + String separator = keyPrefix == null || keyPrefix.isEmpty() ? "" : ":"; + final String name = keyPrefix + separator + "redisson:tomcat_session_updates:" + ((Context) getContainer()).getName(); + return redisson.getTopic(name); } @Override @@ -208,6 +210,13 @@ public class RedissonSessionManager extends ManagerBase { super.startInternal(); redisson = buildClient(); + final ClassLoader applicationClassLoader; + if (Thread.currentThread().getContextClassLoader() != null) { + applicationClassLoader = Thread.currentThread().getContextClassLoader(); + } else { + applicationClassLoader = getClass().getClassLoader(); + } + if (updateMode == UpdateMode.AFTER_REQUEST) { getEngine().getPipeline().addValve(new UpdateValve(this)); } @@ -232,17 +241,17 @@ public class RedissonSessionManager extends ManagerBase { if (msg instanceof AttributesPutAllMessage) { AttributesPutAllMessage m = (AttributesPutAllMessage) msg; - for (Entry entry : m.getAttrs().entrySet()) { + for (Entry entry : m.getAttrs(applicationClassLoader).entrySet()) { session.superSetAttribute(entry.getKey(), entry.getValue(), true); } } if (msg instanceof AttributeUpdateMessage) { AttributeUpdateMessage m = (AttributeUpdateMessage)msg; - session.superSetAttribute(m.getName(), m.getValue(), true); + session.superSetAttribute(m.getName(), m.getValue(applicationClassLoader), true); } } - } catch (IOException e) { + } catch (Exception e) { log.error("Can't handle topic message", e); } } diff --git a/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributeMessage.java b/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributeMessage.java index 677f0b54a..68a36ca1b 100644 --- a/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributeMessage.java +++ b/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributeMessage.java @@ -15,8 +15,14 @@ */ package org.redisson.tomcat; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; import java.io.Serializable; +import org.apache.catalina.util.CustomObjectInputStream; + /** * * @author Nikita Koksharov @@ -31,10 +37,6 @@ public class AttributeMessage implements Serializable { public AttributeMessage() { } - public AttributeMessage(String sessionId) { - this.sessionId = sessionId; - } - public AttributeMessage(String nodeId, String sessionId) { this.nodeId = nodeId; this.sessionId = sessionId; @@ -48,4 +50,22 @@ public class AttributeMessage implements Serializable { return nodeId; } + protected byte[] toByteArray(Object value) throws IOException { + if (value == null) { + return null; + } + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(bos); + out.writeObject(value); + out.flush(); + return bos.toByteArray(); + } + + protected Object toObject(ClassLoader classLoader, byte[] value) throws IOException, ClassNotFoundException { + if (value == null) { + return null; + } + CustomObjectInputStream in = new CustomObjectInputStream(new ByteArrayInputStream(value), classLoader); + return in.readObject(); + } } diff --git a/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributeRemoveMessage.java b/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributeRemoveMessage.java index 1ace1f96f..191b317b8 100644 --- a/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributeRemoveMessage.java +++ b/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributeRemoveMessage.java @@ -28,11 +28,6 @@ public class AttributeRemoveMessage extends AttributeMessage { super(); } - public AttributeRemoveMessage(String sessionId, String name) { - super(sessionId); - this.name = name; - } - public AttributeRemoveMessage(String nodeId, String sessionId, String name) { super(nodeId, sessionId); this.name = name; diff --git a/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributeUpdateMessage.java b/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributeUpdateMessage.java index 295e104eb..ed679614b 100644 --- a/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributeUpdateMessage.java +++ b/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributeUpdateMessage.java @@ -15,6 +15,8 @@ */ package org.redisson.tomcat; +import java.io.IOException; + /** * * @author Nikita Koksharov @@ -23,29 +25,23 @@ package org.redisson.tomcat; public class AttributeUpdateMessage extends AttributeMessage { private String name; - private Object value; + private byte[] value; public AttributeUpdateMessage() { } - public AttributeUpdateMessage(String sessionId, String name, Object value) { - super(sessionId); - this.name = name; - this.value = value; - } - - public AttributeUpdateMessage(String nodeId, String sessionId, String name, Object value) { + public AttributeUpdateMessage(String nodeId, String sessionId, String name, Object value) throws IOException { super(nodeId, sessionId); this.name = name; - this.value = value; + this.value = toByteArray(value); } public String getName() { return name; } - public Object getValue() { - return value; + public Object getValue(ClassLoader classLoader) throws IOException, ClassNotFoundException { + return toObject(classLoader, value); } } diff --git a/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributesClearMessage.java b/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributesClearMessage.java index 7c1895fb6..66d348452 100644 --- a/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributesClearMessage.java +++ b/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributesClearMessage.java @@ -25,10 +25,6 @@ public class AttributesClearMessage extends AttributeMessage { public AttributesClearMessage() { } - public AttributesClearMessage(String sessionId) { - super(sessionId); - } - public AttributesClearMessage(String nodeId, String sessionId) { super(nodeId, sessionId); } diff --git a/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributesPutAllMessage.java b/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributesPutAllMessage.java index 085aee8d5..c91390d63 100644 --- a/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributesPutAllMessage.java +++ b/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/AttributesPutAllMessage.java @@ -15,7 +15,10 @@ */ package org.redisson.tomcat; +import java.io.IOException; +import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; /** * @@ -24,23 +27,32 @@ import java.util.Map; */ public class AttributesPutAllMessage extends AttributeMessage { - private Map attrs; + private Map attrs; public AttributesPutAllMessage() { } - public AttributesPutAllMessage(String sessionId, Map attrs) { - super(sessionId); - this.attrs = attrs; - } - - public AttributesPutAllMessage(String nodeId, String sessionId, Map attrs) { + public AttributesPutAllMessage(String nodeId, String sessionId, Map attrs) throws IOException { super(nodeId, sessionId); - this.attrs = attrs; + if (attrs != null) { + this.attrs = new HashMap(); + for (Entry entry: attrs.entrySet()) { + this.attrs.put(entry.getKey(), toByteArray(entry.getValue())); + } + } else { + this.attrs = null; + } } - public Map getAttrs() { - return attrs; + public Map getAttrs(ClassLoader classLoader) throws IOException, ClassNotFoundException { + if (attrs == null) { + return null; + } + Map result = new HashMap(); + for (Entry entry: attrs.entrySet()) { + result.put(entry.getKey(), toObject(classLoader, entry.getValue())); + } + return result; } } diff --git a/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/RedissonSession.java b/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/RedissonSession.java index 5d5638257..e8f411dbd 100644 --- a/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/RedissonSession.java +++ b/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/RedissonSession.java @@ -15,6 +15,7 @@ */ package org.redisson.tomcat; +import java.io.IOException; import java.lang.reflect.Field; import java.util.Arrays; import java.util.HashMap; @@ -132,7 +133,11 @@ public class RedissonSession extends StandardSession { for (Entry entry : newMap.entrySet()) { map.put(entry.getKey(), entry.getValue()); } - return new AttributesPutAllMessage(redissonManager.getNodeId(), getId(), map); + try { + return new AttributesPutAllMessage(redissonManager.getNodeId(), getId(), map); + } catch (IOException e) { + throw new IllegalStateException(e); + } } @Override @@ -148,7 +153,11 @@ public class RedissonSession extends StandardSession { private void fastPut(String name, Object value) { map.fastPut(name, value); if (readMode == ReadMode.MEMORY) { - topic.publish(new AttributeUpdateMessage(redissonManager.getNodeId(), getId(), name, value)); + try { + topic.publish(new AttributeUpdateMessage(redissonManager.getNodeId(), getId(), name, value)); + } catch (IOException e) { + throw new IllegalStateException(e); + } } } diff --git a/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/RedissonSessionManager.java b/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/RedissonSessionManager.java index c6857caf7..761981800 100644 --- a/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/RedissonSessionManager.java +++ b/redisson-tomcat/redisson-tomcat-8/src/main/java/org/redisson/tomcat/RedissonSessionManager.java @@ -209,6 +209,13 @@ public class RedissonSessionManager extends ManagerBase { super.startInternal(); redisson = buildClient(); + final ClassLoader applicationClassLoader; + if (Thread.currentThread().getContextClassLoader() != null) { + applicationClassLoader = Thread.currentThread().getContextClassLoader(); + } else { + applicationClassLoader = getClass().getClassLoader(); + } + if (updateMode == UpdateMode.AFTER_REQUEST) { getEngine().getPipeline().addValve(new UpdateValve(this)); } @@ -233,17 +240,17 @@ public class RedissonSessionManager extends ManagerBase { if (msg instanceof AttributesPutAllMessage) { AttributesPutAllMessage m = (AttributesPutAllMessage) msg; - for (Entry entry : m.getAttrs().entrySet()) { + for (Entry entry : m.getAttrs(applicationClassLoader).entrySet()) { session.superSetAttribute(entry.getKey(), entry.getValue(), true); } } if (msg instanceof AttributeUpdateMessage) { AttributeUpdateMessage m = (AttributeUpdateMessage)msg; - session.superSetAttribute(m.getName(), m.getValue(), true); + session.superSetAttribute(m.getName(), m.getValue(applicationClassLoader), true); } } - } catch (IOException e) { + } catch (Exception e) { log.error("Can't handle topic message", e); } } diff --git a/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributeMessage.java b/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributeMessage.java index 677f0b54a..68a36ca1b 100644 --- a/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributeMessage.java +++ b/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributeMessage.java @@ -15,8 +15,14 @@ */ package org.redisson.tomcat; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; import java.io.Serializable; +import org.apache.catalina.util.CustomObjectInputStream; + /** * * @author Nikita Koksharov @@ -31,10 +37,6 @@ public class AttributeMessage implements Serializable { public AttributeMessage() { } - public AttributeMessage(String sessionId) { - this.sessionId = sessionId; - } - public AttributeMessage(String nodeId, String sessionId) { this.nodeId = nodeId; this.sessionId = sessionId; @@ -48,4 +50,22 @@ public class AttributeMessage implements Serializable { return nodeId; } + protected byte[] toByteArray(Object value) throws IOException { + if (value == null) { + return null; + } + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(bos); + out.writeObject(value); + out.flush(); + return bos.toByteArray(); + } + + protected Object toObject(ClassLoader classLoader, byte[] value) throws IOException, ClassNotFoundException { + if (value == null) { + return null; + } + CustomObjectInputStream in = new CustomObjectInputStream(new ByteArrayInputStream(value), classLoader); + return in.readObject(); + } } diff --git a/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributeRemoveMessage.java b/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributeRemoveMessage.java index 1ace1f96f..191b317b8 100644 --- a/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributeRemoveMessage.java +++ b/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributeRemoveMessage.java @@ -28,11 +28,6 @@ public class AttributeRemoveMessage extends AttributeMessage { super(); } - public AttributeRemoveMessage(String sessionId, String name) { - super(sessionId); - this.name = name; - } - public AttributeRemoveMessage(String nodeId, String sessionId, String name) { super(nodeId, sessionId); this.name = name; diff --git a/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributeUpdateMessage.java b/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributeUpdateMessage.java index 295e104eb..ed679614b 100644 --- a/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributeUpdateMessage.java +++ b/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributeUpdateMessage.java @@ -15,6 +15,8 @@ */ package org.redisson.tomcat; +import java.io.IOException; + /** * * @author Nikita Koksharov @@ -23,29 +25,23 @@ package org.redisson.tomcat; public class AttributeUpdateMessage extends AttributeMessage { private String name; - private Object value; + private byte[] value; public AttributeUpdateMessage() { } - public AttributeUpdateMessage(String sessionId, String name, Object value) { - super(sessionId); - this.name = name; - this.value = value; - } - - public AttributeUpdateMessage(String nodeId, String sessionId, String name, Object value) { + public AttributeUpdateMessage(String nodeId, String sessionId, String name, Object value) throws IOException { super(nodeId, sessionId); this.name = name; - this.value = value; + this.value = toByteArray(value); } public String getName() { return name; } - public Object getValue() { - return value; + public Object getValue(ClassLoader classLoader) throws IOException, ClassNotFoundException { + return toObject(classLoader, value); } } diff --git a/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributesClearMessage.java b/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributesClearMessage.java index 7c1895fb6..66d348452 100644 --- a/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributesClearMessage.java +++ b/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributesClearMessage.java @@ -25,10 +25,6 @@ public class AttributesClearMessage extends AttributeMessage { public AttributesClearMessage() { } - public AttributesClearMessage(String sessionId) { - super(sessionId); - } - public AttributesClearMessage(String nodeId, String sessionId) { super(nodeId, sessionId); } diff --git a/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributesPutAllMessage.java b/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributesPutAllMessage.java index 085aee8d5..c91390d63 100644 --- a/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributesPutAllMessage.java +++ b/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/AttributesPutAllMessage.java @@ -15,7 +15,10 @@ */ package org.redisson.tomcat; +import java.io.IOException; +import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; /** * @@ -24,23 +27,32 @@ import java.util.Map; */ public class AttributesPutAllMessage extends AttributeMessage { - private Map attrs; + private Map attrs; public AttributesPutAllMessage() { } - public AttributesPutAllMessage(String sessionId, Map attrs) { - super(sessionId); - this.attrs = attrs; - } - - public AttributesPutAllMessage(String nodeId, String sessionId, Map attrs) { + public AttributesPutAllMessage(String nodeId, String sessionId, Map attrs) throws IOException { super(nodeId, sessionId); - this.attrs = attrs; + if (attrs != null) { + this.attrs = new HashMap(); + for (Entry entry: attrs.entrySet()) { + this.attrs.put(entry.getKey(), toByteArray(entry.getValue())); + } + } else { + this.attrs = null; + } } - public Map getAttrs() { - return attrs; + public Map getAttrs(ClassLoader classLoader) throws IOException, ClassNotFoundException { + if (attrs == null) { + return null; + } + Map result = new HashMap(); + for (Entry entry: attrs.entrySet()) { + result.put(entry.getKey(), toObject(classLoader, entry.getValue())); + } + return result; } } diff --git a/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/RedissonSession.java b/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/RedissonSession.java index 9fae1068b..4f8240d6c 100644 --- a/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/RedissonSession.java +++ b/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/RedissonSession.java @@ -15,6 +15,7 @@ */ package org.redisson.tomcat; +import java.io.IOException; import java.lang.reflect.Field; import java.util.Arrays; import java.util.HashMap; @@ -132,7 +133,11 @@ public class RedissonSession extends StandardSession { for (Entry entry : newMap.entrySet()) { map.put(entry.getKey(), entry.getValue()); } - return new AttributesPutAllMessage(redissonManager.getNodeId(), getId(), map); + try { + return new AttributesPutAllMessage(redissonManager.getNodeId(), getId(), map); + } catch (IOException e) { + throw new IllegalStateException(e); + } } @Override @@ -148,7 +153,11 @@ public class RedissonSession extends StandardSession { private void fastPut(String name, Object value) { map.fastPut(name, value); if (readMode == ReadMode.MEMORY) { - topic.publish(new AttributeUpdateMessage(redissonManager.getNodeId(), getId(), name, value)); + try { + topic.publish(new AttributeUpdateMessage(redissonManager.getNodeId(), getId(), name, value)); + } catch (IOException e) { + throw new IllegalStateException(e); + } } } diff --git a/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/RedissonSessionManager.java b/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/RedissonSessionManager.java index c0476b915..761981800 100644 --- a/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/RedissonSessionManager.java +++ b/redisson-tomcat/redisson-tomcat-9/src/main/java/org/redisson/tomcat/RedissonSessionManager.java @@ -136,7 +136,9 @@ public class RedissonSessionManager extends ManagerBase { } public RTopic getTopic() { - return redisson.getTopic("redisson:tomcat_session_updates:" + getContext().getName()); + String separator = keyPrefix == null || keyPrefix.isEmpty() ? "" : ":"; + final String name = keyPrefix + separator + "redisson:tomcat_session_updates:" + getContext().getName(); + return redisson.getTopic(name); } @Override @@ -207,6 +209,13 @@ public class RedissonSessionManager extends ManagerBase { super.startInternal(); redisson = buildClient(); + final ClassLoader applicationClassLoader; + if (Thread.currentThread().getContextClassLoader() != null) { + applicationClassLoader = Thread.currentThread().getContextClassLoader(); + } else { + applicationClassLoader = getClass().getClassLoader(); + } + if (updateMode == UpdateMode.AFTER_REQUEST) { getEngine().getPipeline().addValve(new UpdateValve(this)); } @@ -231,17 +240,17 @@ public class RedissonSessionManager extends ManagerBase { if (msg instanceof AttributesPutAllMessage) { AttributesPutAllMessage m = (AttributesPutAllMessage) msg; - for (Entry entry : m.getAttrs().entrySet()) { + for (Entry entry : m.getAttrs(applicationClassLoader).entrySet()) { session.superSetAttribute(entry.getKey(), entry.getValue(), true); } } if (msg instanceof AttributeUpdateMessage) { AttributeUpdateMessage m = (AttributeUpdateMessage)msg; - session.superSetAttribute(m.getName(), m.getValue(), true); + session.superSetAttribute(m.getName(), m.getValue(applicationClassLoader), true); } } - } catch (IOException e) { + } catch (Exception e) { log.error("Can't handle topic message", e); } } From 37b58db7bcc2bdf586e3ce2e55a37803fcd545fd Mon Sep 17 00:00:00 2001 From: Nikita Koksharov Date: Thu, 17 Jan 2019 16:35:01 +0300 Subject: [PATCH 3/3] Fixed - Getting java.lang.ClassNotFoundException if same Redisson instance used in tomcat and application. #1668 --- .../org/redisson/JndiRedissonFactory.java | 11 ---- .../java/org/redisson/RedissonBitSet.java | 4 +- .../org/redisson/client/codec/BaseCodec.java | 19 +++++++ .../client/codec/JsonJacksonMapCodec.java | 4 ++ .../org/redisson/codec/AvroJacksonCodec.java | 4 ++ .../org/redisson/codec/CborJacksonCodec.java | 4 ++ .../org/redisson/codec/CompositeCodec.java | 45 ++++++++++++++++ .../java/org/redisson/codec/FstCodec.java | 20 +++++++ .../org/redisson/codec/IonJacksonCodec.java | 4 ++ .../org/redisson/codec/JsonJacksonCodec.java | 4 ++ .../java/org/redisson/codec/KryoCodec.java | 10 ++++ .../java/org/redisson/codec/LZ4Codec.java | 4 ++ .../redisson/codec/MapCacheEventCodec.java | 37 +++++++++++++ .../redisson/codec/MsgPackJacksonCodec.java | 4 ++ .../redisson/codec/SerializationCodec.java | 26 ++------- .../org/redisson/codec/SmileJacksonCodec.java | 4 ++ .../java/org/redisson/codec/SnappyCodec.java | 4 ++ .../org/redisson/codec/SnappyCodecV2.java | 4 ++ .../redisson/codec/TypedJsonJacksonCodec.java | 22 ++++++++ .../redisson/command/CommandAsyncService.java | 54 ++++++++++++++++++- .../redisson/command/CommandBatchService.java | 3 +- .../redisson/RedissonLocalCachedMapTest.java | 6 +-- 22 files changed, 257 insertions(+), 40 deletions(-) diff --git a/redisson/src/main/java/org/redisson/JndiRedissonFactory.java b/redisson/src/main/java/org/redisson/JndiRedissonFactory.java index 89370dd59..57ffcfbf3 100644 --- a/redisson/src/main/java/org/redisson/JndiRedissonFactory.java +++ b/redisson/src/main/java/org/redisson/JndiRedissonFactory.java @@ -26,9 +26,7 @@ import javax.naming.RefAddr; import javax.naming.Reference; import javax.naming.spi.ObjectFactory; -import org.redisson.Redisson; import org.redisson.api.RedissonClient; -import org.redisson.client.codec.Codec; import org.redisson.config.Config; /** @@ -63,15 +61,6 @@ public class JndiRedissonFactory implements ObjectFactory { } try { - try { - Config c = new Config(config); - Codec codec = c.getCodec().getClass().getConstructor(ClassLoader.class) - .newInstance(Thread.currentThread().getContextClassLoader()); - config.setCodec(codec); - } catch (Exception e) { - throw new IllegalStateException("Unable to initialize codec with ClassLoader parameter", e); - } - return Redisson.create(config); } catch (Exception e) { NamingException ex = new NamingException(); diff --git a/redisson/src/main/java/org/redisson/RedissonBitSet.java b/redisson/src/main/java/org/redisson/RedissonBitSet.java index 87ac51e70..d936bebbe 100644 --- a/redisson/src/main/java/org/redisson/RedissonBitSet.java +++ b/redisson/src/main/java/org/redisson/RedissonBitSet.java @@ -147,7 +147,7 @@ public class RedissonBitSet extends RedissonExpirable implements RBitSet { params.add(getName()); params.add(getName()); params.addAll(Arrays.asList(bitSetNames)); - return commandExecutor.writeAsync(getName(), codec, RedisCommands.BITOP, params.toArray()); + return commandExecutor.writeAsync(getName(), StringCodec.INSTANCE, RedisCommands.BITOP, params.toArray()); } @Override @@ -185,7 +185,7 @@ public class RedissonBitSet extends RedissonExpirable implements RBitSet { @Override public RFuture lengthAsync() { - return commandExecutor.evalReadAsync(getName(), codec, RedisCommands.EVAL_LONG, + return commandExecutor.evalReadAsync(getName(), LongCodec.INSTANCE, RedisCommands.EVAL_LONG, "local fromBit = redis.call('bitpos', KEYS[1], 1, -1);" + "local toBit = 8*(fromBit/8 + 1) - fromBit % 8;" + "for i = toBit, fromBit, -1 do " diff --git a/redisson/src/main/java/org/redisson/client/codec/BaseCodec.java b/redisson/src/main/java/org/redisson/client/codec/BaseCodec.java index 73a0b97e3..602deefff 100644 --- a/redisson/src/main/java/org/redisson/client/codec/BaseCodec.java +++ b/redisson/src/main/java/org/redisson/client/codec/BaseCodec.java @@ -15,8 +15,10 @@ */ package org.redisson.client.codec; +import org.redisson.cache.LocalCachedMessageCodec; import org.redisson.client.protocol.Decoder; import org.redisson.client.protocol.Encoder; +import org.redisson.jcache.JCacheEventCodec; /** * @@ -25,6 +27,23 @@ import org.redisson.client.protocol.Encoder; */ public abstract class BaseCodec implements Codec { + public static Codec copy(ClassLoader classLoader, Codec codec) { + if (codec instanceof StringCodec + || codec instanceof ByteArrayCodec + || codec instanceof LocalCachedMessageCodec + || codec instanceof BitSetCodec + || codec instanceof JCacheEventCodec + || codec == null) { + return codec; + } + + try { + return codec.getClass().getConstructor(ClassLoader.class, codec.getClass()).newInstance(classLoader, codec); + } catch (Exception e) { + throw new IllegalStateException(e); + } + } + @Override public Decoder getMapValueDecoder() { return getValueDecoder(); diff --git a/redisson/src/main/java/org/redisson/client/codec/JsonJacksonMapCodec.java b/redisson/src/main/java/org/redisson/client/codec/JsonJacksonMapCodec.java index bddd7ffd8..85336b34f 100644 --- a/redisson/src/main/java/org/redisson/client/codec/JsonJacksonMapCodec.java +++ b/redisson/src/main/java/org/redisson/client/codec/JsonJacksonMapCodec.java @@ -96,6 +96,10 @@ public class JsonJacksonMapCodec extends JsonJacksonCodec { public JsonJacksonMapCodec(TypeReference keyTypeReference, TypeReference valueTypeReference, ObjectMapper mapper) { this(keyTypeReference, valueTypeReference, null, null, mapper); } + + public JsonJacksonMapCodec(ClassLoader classLoader, JsonJacksonMapCodec codec) { + this(codec.keyTypeReference, codec.valueTypeReference, codec.keyClass, codec.valueClass, createObjectMapper(classLoader, codec.mapObjectMapper.copy())); + } JsonJacksonMapCodec(TypeReference keyTypeReference, TypeReference valueTypeReference, Class keyClass, Class valueClass, ObjectMapper mapper) { super(mapper); diff --git a/redisson/src/main/java/org/redisson/codec/AvroJacksonCodec.java b/redisson/src/main/java/org/redisson/codec/AvroJacksonCodec.java index e55e41690..e9ea4dbb6 100644 --- a/redisson/src/main/java/org/redisson/codec/AvroJacksonCodec.java +++ b/redisson/src/main/java/org/redisson/codec/AvroJacksonCodec.java @@ -81,6 +81,10 @@ public class AvroJacksonCodec extends JsonJacksonCodec { super(createObjectMapper(classLoader, new ObjectMapper(new AvroFactory()))); } + public AvroJacksonCodec(ClassLoader classLoader, AvroJacksonCodec codec) { + super(createObjectMapper(classLoader, codec.mapObjectMapper.copy())); + } + @Override protected void initTypeInclusion(ObjectMapper mapObjectMapper) { } diff --git a/redisson/src/main/java/org/redisson/codec/CborJacksonCodec.java b/redisson/src/main/java/org/redisson/codec/CborJacksonCodec.java index 4f341e666..c2be7a860 100644 --- a/redisson/src/main/java/org/redisson/codec/CborJacksonCodec.java +++ b/redisson/src/main/java/org/redisson/codec/CborJacksonCodec.java @@ -33,4 +33,8 @@ public class CborJacksonCodec extends JsonJacksonCodec { super(createObjectMapper(classLoader, new ObjectMapper(new CBORFactory()))); } + public CborJacksonCodec(ClassLoader classLoader, CborJacksonCodec codec) { + super(createObjectMapper(classLoader, codec.mapObjectMapper.copy())); + } + } diff --git a/redisson/src/main/java/org/redisson/codec/CompositeCodec.java b/redisson/src/main/java/org/redisson/codec/CompositeCodec.java index 0f5cba4c1..c9329d5a2 100644 --- a/redisson/src/main/java/org/redisson/codec/CompositeCodec.java +++ b/redisson/src/main/java/org/redisson/codec/CompositeCodec.java @@ -15,6 +15,7 @@ */ package org.redisson.codec; +import org.redisson.client.codec.BaseCodec; import org.redisson.client.codec.Codec; import org.redisson.client.protocol.Decoder; import org.redisson.client.protocol.Encoder; @@ -41,6 +42,13 @@ public class CompositeCodec implements Codec { this.valueCodec = valueCodec; } + public CompositeCodec(ClassLoader classLoader, CompositeCodec codec) { + super(); + this.mapKeyCodec = BaseCodec.copy(classLoader, codec.mapKeyCodec); + this.mapValueCodec = BaseCodec.copy(classLoader, codec.mapValueCodec); + this.valueCodec = BaseCodec.copy(classLoader, codec.valueCodec); + } + @Override public Decoder getMapValueDecoder() { return mapValueCodec.getMapKeyDecoder(); @@ -76,4 +84,41 @@ public class CompositeCodec implements Codec { return getClass().getClassLoader(); } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((mapKeyCodec == null) ? 0 : mapKeyCodec.hashCode()); + result = prime * result + ((mapValueCodec == null) ? 0 : mapValueCodec.hashCode()); + result = prime * result + ((valueCodec == null) ? 0 : valueCodec.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CompositeCodec other = (CompositeCodec) obj; + if (mapKeyCodec == null) { + if (other.mapKeyCodec != null) + return false; + } else if (!mapKeyCodec.equals(other.mapKeyCodec)) + return false; + if (mapValueCodec == null) { + if (other.mapValueCodec != null) + return false; + } else if (!mapValueCodec.equals(other.mapValueCodec)) + return false; + if (valueCodec == null) { + if (other.valueCodec != null) + return false; + } else if (!valueCodec.equals(other.valueCodec)) + return false; + return true; + } + } diff --git a/redisson/src/main/java/org/redisson/codec/FstCodec.java b/redisson/src/main/java/org/redisson/codec/FstCodec.java index 1404c6ba3..2b66b3615 100644 --- a/redisson/src/main/java/org/redisson/codec/FstCodec.java +++ b/redisson/src/main/java/org/redisson/codec/FstCodec.java @@ -50,7 +50,27 @@ public class FstCodec extends BaseCodec { public FstCodec(ClassLoader classLoader) { this(createConfig(classLoader)); } + + public FstCodec(ClassLoader classLoader, FstCodec codec) { + this(copy(classLoader, codec)); + } + private static FSTConfiguration copy(ClassLoader classLoader, FstCodec codec) { + FSTConfiguration def = FSTConfiguration.createDefaultConfiguration(); + def.setClassLoader(classLoader); + def.setCoderSpecific(codec.config.getCoderSpecific()); + def.setCrossPlatform(codec.config.isCrossPlatform()); + def.setForceClzInit(codec.config.isForceClzInit()); + def.setForceSerializable(codec.config.isForceSerializable()); + def.setInstantiator(codec.config.getInstantiator(null)); + def.setName(codec.config.getName()); + def.setPreferSpeed(codec.config.isPreferSpeed()); + def.setShareReferences(codec.config.isShareReferences()); + def.setStreamCoderFactory(codec.config.getStreamCoderFactory()); + def.setVerifier(codec.config.getVerifier()); + return def; + } + private static FSTConfiguration createConfig(ClassLoader classLoader) { FSTConfiguration def = FSTConfiguration.createDefaultConfiguration(); def.setClassLoader(classLoader); diff --git a/redisson/src/main/java/org/redisson/codec/IonJacksonCodec.java b/redisson/src/main/java/org/redisson/codec/IonJacksonCodec.java index e44166656..8a46d7035 100644 --- a/redisson/src/main/java/org/redisson/codec/IonJacksonCodec.java +++ b/redisson/src/main/java/org/redisson/codec/IonJacksonCodec.java @@ -33,4 +33,8 @@ public class IonJacksonCodec extends JsonJacksonCodec { super(createObjectMapper(classLoader, new IonObjectMapper())); } + public IonJacksonCodec(ClassLoader classLoader, IonJacksonCodec codec) { + super(createObjectMapper(classLoader, codec.mapObjectMapper.copy())); + } + } diff --git a/redisson/src/main/java/org/redisson/codec/JsonJacksonCodec.java b/redisson/src/main/java/org/redisson/codec/JsonJacksonCodec.java index 708787126..903f1164b 100755 --- a/redisson/src/main/java/org/redisson/codec/JsonJacksonCodec.java +++ b/redisson/src/main/java/org/redisson/codec/JsonJacksonCodec.java @@ -103,6 +103,10 @@ public class JsonJacksonCodec extends BaseCodec { public JsonJacksonCodec(ClassLoader classLoader) { this(createObjectMapper(classLoader, new ObjectMapper())); } + + public JsonJacksonCodec(ClassLoader classLoader, JsonJacksonCodec codec) { + this(createObjectMapper(classLoader, codec.mapObjectMapper.copy())); + } protected static ObjectMapper createObjectMapper(ClassLoader classLoader, ObjectMapper om) { TypeFactory tf = TypeFactory.defaultInstance().withClassLoader(classLoader); diff --git a/redisson/src/main/java/org/redisson/codec/KryoCodec.java b/redisson/src/main/java/org/redisson/codec/KryoCodec.java index 8ee88fc50..a1af846b9 100755 --- a/redisson/src/main/java/org/redisson/codec/KryoCodec.java +++ b/redisson/src/main/java/org/redisson/codec/KryoCodec.java @@ -49,6 +49,8 @@ public class KryoCodec extends BaseCodec { void yield(Kryo kryo); ClassLoader getClassLoader(); + + List> getClasses(); } @@ -92,6 +94,10 @@ public class KryoCodec extends BaseCodec { return kryo; } + public List> getClasses() { + return classes; + } + @Override public ClassLoader getClassLoader() { return classLoader; @@ -166,6 +172,10 @@ public class KryoCodec extends BaseCodec { this(Collections.>emptyList(), classLoader); } + public KryoCodec(ClassLoader classLoader, KryoCodec codec) { + this(codec.kryoPool.getClasses(), classLoader); + } + public KryoCodec(List> classes) { this(classes, null); } diff --git a/redisson/src/main/java/org/redisson/codec/LZ4Codec.java b/redisson/src/main/java/org/redisson/codec/LZ4Codec.java index 0a0a174f4..aa0381e2d 100644 --- a/redisson/src/main/java/org/redisson/codec/LZ4Codec.java +++ b/redisson/src/main/java/org/redisson/codec/LZ4Codec.java @@ -61,6 +61,10 @@ public class LZ4Codec extends BaseCodec { this(new FstCodec(classLoader)); } + public LZ4Codec(ClassLoader classLoader, LZ4Codec codec) { + this(copy(classLoader, codec.innerCodec)); + } + private final Decoder decoder = new Decoder() { @Override public Object decode(ByteBuf buf, State state) throws IOException { diff --git a/redisson/src/main/java/org/redisson/codec/MapCacheEventCodec.java b/redisson/src/main/java/org/redisson/codec/MapCacheEventCodec.java index bc0019208..166c1fae9 100644 --- a/redisson/src/main/java/org/redisson/codec/MapCacheEventCodec.java +++ b/redisson/src/main/java/org/redisson/codec/MapCacheEventCodec.java @@ -61,6 +61,15 @@ public class MapCacheEventCodec implements Codec { this.codec = codec; this.isWindows = isWindows; } + + public MapCacheEventCodec(ClassLoader classLoader, MapCacheEventCodec codec) { + try { + this.codec = codec.codec.getClass().getConstructor(ClassLoader.class, codec.codec.getClass()).newInstance(classLoader, codec.codec); + } catch (Exception e) { + throw new IllegalStateException(e); + } + this.isWindows = codec.isWindows; + } @Override public Decoder getMapValueDecoder() { @@ -109,4 +118,32 @@ public class MapCacheEventCodec implements Codec { return getClass().getClassLoader(); } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((codec == null) ? 0 : codec.hashCode()); + result = prime * result + (isWindows ? 1231 : 1237); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + MapCacheEventCodec other = (MapCacheEventCodec) obj; + if (codec == null) { + if (other.codec != null) + return false; + } else if (!codec.equals(other.codec)) + return false; + if (isWindows != other.isWindows) + return false; + return true; + } + } diff --git a/redisson/src/main/java/org/redisson/codec/MsgPackJacksonCodec.java b/redisson/src/main/java/org/redisson/codec/MsgPackJacksonCodec.java index aa8f62440..b663a75bc 100644 --- a/redisson/src/main/java/org/redisson/codec/MsgPackJacksonCodec.java +++ b/redisson/src/main/java/org/redisson/codec/MsgPackJacksonCodec.java @@ -35,4 +35,8 @@ public class MsgPackJacksonCodec extends JsonJacksonCodec { super(createObjectMapper(classLoader, new ObjectMapper(new MessagePackFactory()))); } + public MsgPackJacksonCodec(ClassLoader classLoader, MsgPackJacksonCodec codec) { + super(createObjectMapper(classLoader, codec.mapObjectMapper.copy())); + } + } diff --git a/redisson/src/main/java/org/redisson/codec/SerializationCodec.java b/redisson/src/main/java/org/redisson/codec/SerializationCodec.java index 724881e19..7df6f7dec 100644 --- a/redisson/src/main/java/org/redisson/codec/SerializationCodec.java +++ b/redisson/src/main/java/org/redisson/codec/SerializationCodec.java @@ -19,7 +19,7 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; -import org.redisson.client.codec.Codec; +import org.redisson.client.codec.BaseCodec; import org.redisson.client.handler.State; import org.redisson.client.protocol.Decoder; import org.redisson.client.protocol.Encoder; @@ -34,7 +34,7 @@ import io.netty.buffer.ByteBufOutputStream; * @author Nikita Koksharov * */ -public class SerializationCodec implements Codec { +public class SerializationCodec extends BaseCodec { private final Decoder decoder = new Decoder() { @Override @@ -83,27 +83,11 @@ public class SerializationCodec implements Codec { public SerializationCodec(ClassLoader classLoader) { this.classLoader = classLoader; } - - @Override - public Decoder getMapValueDecoder() { - return getValueDecoder(); - } - @Override - public Encoder getMapValueEncoder() { - return getValueEncoder(); - } - - @Override - public Decoder getMapKeyDecoder() { - return getValueDecoder(); - } - - @Override - public Encoder getMapKeyEncoder() { - return getValueEncoder(); + public SerializationCodec(ClassLoader classLoader, SerializationCodec codec) { + this.classLoader = classLoader; } - + @Override public Decoder getValueDecoder() { return decoder; diff --git a/redisson/src/main/java/org/redisson/codec/SmileJacksonCodec.java b/redisson/src/main/java/org/redisson/codec/SmileJacksonCodec.java index e37ad8be7..ead4910f7 100644 --- a/redisson/src/main/java/org/redisson/codec/SmileJacksonCodec.java +++ b/redisson/src/main/java/org/redisson/codec/SmileJacksonCodec.java @@ -34,4 +34,8 @@ public class SmileJacksonCodec extends JsonJacksonCodec { super(createObjectMapper(classLoader, new ObjectMapper(new SmileFactory()))); } + public SmileJacksonCodec(ClassLoader classLoader, SmileJacksonCodec codec) { + super(createObjectMapper(classLoader, codec.mapObjectMapper.copy())); + } + } diff --git a/redisson/src/main/java/org/redisson/codec/SnappyCodec.java b/redisson/src/main/java/org/redisson/codec/SnappyCodec.java index 01364266e..06ca20e55 100644 --- a/redisson/src/main/java/org/redisson/codec/SnappyCodec.java +++ b/redisson/src/main/java/org/redisson/codec/SnappyCodec.java @@ -65,6 +65,10 @@ public class SnappyCodec extends BaseCodec { this(new FstCodec(classLoader)); } + public SnappyCodec(ClassLoader classLoader, SnappyCodec codec) { + this(copy(classLoader, codec.innerCodec)); + } + private final Decoder decoder = new Decoder() { @Override diff --git a/redisson/src/main/java/org/redisson/codec/SnappyCodecV2.java b/redisson/src/main/java/org/redisson/codec/SnappyCodecV2.java index 30f843715..308b3161b 100644 --- a/redisson/src/main/java/org/redisson/codec/SnappyCodecV2.java +++ b/redisson/src/main/java/org/redisson/codec/SnappyCodecV2.java @@ -55,6 +55,10 @@ public class SnappyCodecV2 extends BaseCodec { this(new FstCodec(classLoader)); } + public SnappyCodecV2(ClassLoader classLoader, SnappyCodecV2 codec) { + this(copy(classLoader, codec.innerCodec)); + } + private final Decoder decoder = new Decoder() { @Override diff --git a/redisson/src/main/java/org/redisson/codec/TypedJsonJacksonCodec.java b/redisson/src/main/java/org/redisson/codec/TypedJsonJacksonCodec.java index 5ee255fa5..01aef0f7b 100644 --- a/redisson/src/main/java/org/redisson/codec/TypedJsonJacksonCodec.java +++ b/redisson/src/main/java/org/redisson/codec/TypedJsonJacksonCodec.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import org.redisson.client.codec.JsonJacksonMapCodec; import org.redisson.client.handler.State; import org.redisson.client.protocol.Decoder; import org.redisson.client.protocol.Encoder; @@ -74,6 +75,14 @@ public class TypedJsonJacksonCodec extends JsonJacksonCodec { private final Decoder valueDecoder; private final Decoder mapValueDecoder; private final Decoder mapKeyDecoder; + + private final TypeReference valueTypeReference; + private final TypeReference mapKeyTypeReference; + private final TypeReference mapValueTypeReference; + + private final Class valueClass; + private final Class mapKeyClass; + private final Class mapValueClass; public TypedJsonJacksonCodec(Class valueClass) { this(valueClass, new ObjectMapper()); @@ -122,6 +131,12 @@ public class TypedJsonJacksonCodec extends JsonJacksonCodec { public TypedJsonJacksonCodec(TypeReference valueTypeReference, TypeReference mapKeyTypeReference, TypeReference mapValueTypeReference, ObjectMapper mapper) { this(valueTypeReference, mapKeyTypeReference, mapValueTypeReference, null, null, null, mapper); } + + public TypedJsonJacksonCodec(ClassLoader classLoader, TypedJsonJacksonCodec codec) { + this(codec.valueTypeReference, codec.mapKeyTypeReference, codec.mapValueTypeReference, + codec.valueClass, codec.mapKeyClass, codec.mapValueClass, + createObjectMapper(classLoader, codec.mapObjectMapper.copy())); + } TypedJsonJacksonCodec( TypeReference valueTypeReference, TypeReference mapKeyTypeReference, TypeReference mapValueTypeReference, @@ -130,6 +145,13 @@ public class TypedJsonJacksonCodec extends JsonJacksonCodec { this.mapValueDecoder = createDecoder(mapValueClass, mapValueTypeReference); this.mapKeyDecoder = createDecoder(mapKeyClass, mapKeyTypeReference); this.valueDecoder = createDecoder(valueClass, valueTypeReference); + + this.mapValueClass = mapValueClass; + this.mapValueTypeReference = mapValueTypeReference; + this.mapKeyClass = mapKeyClass; + this.mapKeyTypeReference = mapKeyTypeReference; + this.valueClass = valueClass; + this.valueTypeReference = valueTypeReference; } @Override diff --git a/redisson/src/main/java/org/redisson/command/CommandAsyncService.java b/redisson/src/main/java/org/redisson/command/CommandAsyncService.java index 4a18b10af..3cc03d3e5 100644 --- a/redisson/src/main/java/org/redisson/command/CommandAsyncService.java +++ b/redisson/src/main/java/org/redisson/command/CommandAsyncService.java @@ -21,11 +21,13 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -41,6 +43,8 @@ import org.redisson.api.RedissonClient; import org.redisson.api.RedissonReactiveClient; import org.redisson.api.RedissonRxClient; import org.redisson.cache.LRUCacheMap; +import org.redisson.cache.LocalCachedMessageCodec; +import org.redisson.cache.ReferenceCacheMap; import org.redisson.client.RedisAskException; import org.redisson.client.RedisClient; import org.redisson.client.RedisConnection; @@ -52,6 +56,8 @@ import org.redisson.client.RedisResponseTimeoutException; import org.redisson.client.RedisTimeoutException; import org.redisson.client.RedisTryAgainException; import org.redisson.client.WriteRedisConnectionException; +import org.redisson.client.codec.BitSetCodec; +import org.redisson.client.codec.ByteArrayCodec; import org.redisson.client.codec.Codec; import org.redisson.client.codec.StringCodec; import org.redisson.client.protocol.CommandData; @@ -68,6 +74,7 @@ import org.redisson.connection.ConnectionManager; import org.redisson.connection.MasterSlaveEntry; import org.redisson.connection.NodeSource; import org.redisson.connection.NodeSource.Redirect; +import org.redisson.jcache.JCacheEventCodec; import org.redisson.liveobject.core.RedissonObjectBuilder; import org.redisson.misc.LogHelper; import org.redisson.misc.RPromise; @@ -677,12 +684,14 @@ public class CommandAsyncService implements CommandAsyncExecutor { return; } + Codec codecToUse = getCodec(codec); + final AsyncDetails details = AsyncDetails.acquire(); final RFuture connectionFuture = getConnection(readOnlyMode, source, command); final RPromise attemptPromise = new RedissonPromise(); details.init(connectionFuture, attemptPromise, - readOnlyMode, source, codec, command, params, mainPromise, attempt); + readOnlyMode, source, codecToUse, command, params, mainPromise, attempt); FutureListener mainPromiseListener = new FutureListener() { @Override @@ -816,7 +825,48 @@ public class CommandAsyncService implements CommandAsyncExecutor { } }); } - + + private static final Map> codecs = ReferenceCacheMap.weak(0, 0); + + protected Codec getCodec(Codec codec) { + if (codec instanceof StringCodec + || codec instanceof ByteArrayCodec + || codec instanceof LocalCachedMessageCodec + || codec instanceof BitSetCodec + || codec instanceof JCacheEventCodec + || codec == null) { + return codec; + } + + Codec codecToUse = codec; + ClassLoader threadClassLoader = Thread.currentThread().getContextClassLoader(); + if (threadClassLoader != null) { + Map map = codecs.get(threadClassLoader); + if (map == null) { + synchronized (codecs) { + map = codecs.get(threadClassLoader); + if (map == null) { + map = new ConcurrentHashMap(); + codecs.put(threadClassLoader, map); + } + } + } + codecToUse = map.get(codec); + if (codecToUse == null) { + try { + codecToUse = codec.getClass().getConstructor(ClassLoader.class, codec.getClass()).newInstance(threadClassLoader, codec); + } catch (NoSuchMethodException e) { + codecToUse = codec; + // skip + } catch (Exception e) { + throw new IllegalStateException(e); + } + map.put(codec, codecToUse); + } + } + return codecToUse; + } + protected RFuture getConnection(final boolean readOnlyMode, final NodeSource source, final RedisCommand command) { final RFuture connectionFuture; diff --git a/redisson/src/main/java/org/redisson/command/CommandBatchService.java b/redisson/src/main/java/org/redisson/command/CommandBatchService.java index 4536e6f62..95ba44030 100644 --- a/redisson/src/main/java/org/redisson/command/CommandBatchService.java +++ b/redisson/src/main/java/org/redisson/command/CommandBatchService.java @@ -172,7 +172,8 @@ public class CommandBatchService extends CommandAsyncService { if (!isRedisBasedQueue()) { batchParams = params; } - BatchCommandData commandData = new BatchCommandData(mainPromise, codec, command, batchParams, index.incrementAndGet()); + Codec codecToUse = getCodec(codec); + BatchCommandData commandData = new BatchCommandData(mainPromise, codecToUse, command, batchParams, index.incrementAndGet()); entry.getCommands().add(commandData); } diff --git a/redisson/src/test/java/org/redisson/RedissonLocalCachedMapTest.java b/redisson/src/test/java/org/redisson/RedissonLocalCachedMapTest.java index f9572b087..7b916f525 100644 --- a/redisson/src/test/java/org/redisson/RedissonLocalCachedMapTest.java +++ b/redisson/src/test/java/org/redisson/RedissonLocalCachedMapTest.java @@ -281,10 +281,10 @@ public class RedissonLocalCachedMapTest extends BaseMapTest { RLocalCachedMap map = redisson.getLocalCachedMap("test", options); map.put("1", "11"); map.put("2", "22"); - assertThat(map.cachedKeySet()).containsExactly("1", "2"); + assertThat(map.cachedKeySet()).containsExactlyInAnyOrder("1", "2"); assertThat(map.cachedValues()).containsExactlyInAnyOrder("11", "22"); - assertThat(map.getCachedMap().keySet()).containsExactly("1", "2"); - assertThat(map.getCachedMap().values()).containsExactly("11", "22"); + assertThat(map.getCachedMap().keySet()).containsExactlyInAnyOrder("1", "2"); + assertThat(map.getCachedMap().values()).containsExactlyInAnyOrder("11", "22"); }