diff --git a/pom.xml b/pom.xml
index e2e0f007c6..4653a864ed 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.data
spring-data-redis
- 1.7.0.BUILD-SNAPSHOT
+ 1.7.0.DATAREDIS-427-SNAPSHOT
Spring Data Redis
diff --git a/src/main/java/org/springframework/data/redis/serializer/JdkSerializationRedisSerializer.java b/src/main/java/org/springframework/data/redis/serializer/JdkSerializationRedisSerializer.java
index e45612aa49..d72f21e679 100644
--- a/src/main/java/org/springframework/data/redis/serializer/JdkSerializationRedisSerializer.java
+++ b/src/main/java/org/springframework/data/redis/serializer/JdkSerializationRedisSerializer.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2013 the original author or authors.
+ * Copyright 2011-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,17 +18,53 @@
import org.springframework.core.convert.converter.Converter;
import org.springframework.core.serializer.support.DeserializingConverter;
import org.springframework.core.serializer.support.SerializingConverter;
+import org.springframework.util.Assert;
/**
- * Java Serialization Redis serializer. Delegates to the default (Java based) serializer in Spring 3.
+ * Java Serialization Redis serializer. Delegates to the default (Java based) {@link DefaultSerializer serializer} and
+ * {@link DefaultDeserializer}. This {@link RedisSerializer serializer} can be constructed with either custom
+ * {@link ClassLoader} or own {@link Converter converters}.
*
* @author Mark Pollack
* @author Costin Leau
+ * @author Mark Paluch
*/
public class JdkSerializationRedisSerializer implements RedisSerializer {
- private Converter serializer = new SerializingConverter();
- private Converter deserializer = new DeserializingConverter();
+ private final Converter serializer;
+ private final Converter deserializer;
+
+ /**
+ * Creates a new {@link JdkSerializationRedisSerializer} using the default class loader.
+ */
+ public JdkSerializationRedisSerializer() {
+ this(new SerializingConverter(), new DeserializingConverter());
+ }
+
+ /**
+ * Creates a new {@link JdkSerializationRedisSerializer} using a {@link ClassLoader}.
+ *
+ * @param classLoader
+ */
+ public JdkSerializationRedisSerializer(ClassLoader classLoader) {
+ this(new SerializingConverter(), new DeserializingConverter(classLoader));
+ }
+
+ /**
+ * Creates a new {@link JdkSerializationRedisSerializer} using a {@link Converter converters} to serialize and
+ * deserialize objects.
+ *
+ * @param serializer must not be {@literal null}
+ * @param deserializer must not be {@literal null}
+ */
+ public JdkSerializationRedisSerializer(Converter serializer, Converter deserializer) {
+
+ Assert.notNull("Serializer must not be null!");
+ Assert.notNull("Deserializer must not be null!");
+
+ this.serializer = serializer;
+ this.deserializer = deserializer;
+ }
public Object deserialize(byte[] bytes) {
if (SerializationUtils.isEmpty(bytes)) {
diff --git a/src/test/java/org/springframework/data/redis/serializer/SerializableDomainClass.java b/src/test/java/org/springframework/data/redis/serializer/SerializableDomainClass.java
new file mode 100644
index 0000000000..739d235b8b
--- /dev/null
+++ b/src/test/java/org/springframework/data/redis/serializer/SerializableDomainClass.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2016 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.springframework.data.redis.serializer;
+
+import java.io.Serializable;
+
+/**
+ * @author Mark Paluch
+ */
+public class SerializableDomainClass implements Serializable {
+
+}
diff --git a/src/test/java/org/springframework/data/redis/serializer/SimpleRedisSerializerTests.java b/src/test/java/org/springframework/data/redis/serializer/SimpleRedisSerializerTests.java
index 8b80cc7cfe..37710d6a2f 100644
--- a/src/test/java/org/springframework/data/redis/serializer/SimpleRedisSerializerTests.java
+++ b/src/test/java/org/springframework/data/redis/serializer/SimpleRedisSerializerTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2011-2013 the original author or authors.
+ * Copyright 2011-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,9 +15,13 @@
*/
package org.springframework.data.redis.serializer;
+import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
+import java.io.IOException;
+import java.io.InputStream;
import java.io.Serializable;
+import java.net.URL;
import java.util.UUID;
import org.junit.After;
@@ -26,9 +30,11 @@
import org.springframework.data.redis.Address;
import org.springframework.data.redis.Person;
import org.springframework.oxm.xstream.XStreamMarshaller;
+import org.springframework.util.StreamUtils;
/**
* @author Jennifer Hickey
+ * @author Mark Paluch
*/
public class SimpleRedisSerializerTests {
@@ -119,6 +125,22 @@ private void verifySerializedObjects(Object... objects) {
}
}
+ @Test
+ public void jdkSerializerShouldUseCustomClassLoader() throws ClassNotFoundException {
+
+ ClassLoader customClassLoader = new CustomClassLoader();
+
+ JdkSerializationRedisSerializer serializer = new JdkSerializationRedisSerializer(customClassLoader);
+ SerializableDomainClass domainClass = new SerializableDomainClass();
+
+ byte[] serialized = serializer.serialize(domainClass);
+ Object deserialized = serializer.deserialize(serialized);
+
+ assertThat(deserialized.getClass().getName(), is(equalTo(SerializableDomainClass.class.getName())));
+ assertThat(deserialized, is(not(instanceOf(SerializableDomainClass.class))));
+ assertThat(deserialized.getClass().getClassLoader(), is(equalTo(customClassLoader)));
+ }
+
@Test
public void testStringEncodedSerialization() {
String value = UUID.randomUUID().toString();
@@ -157,4 +179,43 @@ public void testJsonSerializer() throws Exception {
assertEquals(p1, serializer.deserialize(serializer.serialize(p1)));
}
+ /**
+ * Custom class loader that loads class files from the test's class path. This {@link ClassLoader} does not delegate
+ * to a parent class loader to truly load classes that are defined by this class loader and not interfere with any
+ * parent class loader. The class loader uses simple class definition which is fine for the test but do not use this
+ * as sample for production class loaders.
+ */
+ private static class CustomClassLoader extends ClassLoader {
+
+ public CustomClassLoader() {
+ super(null);
+ }
+
+ @Override
+ protected Class> findClass(String name) throws ClassNotFoundException {
+
+ URL resource = SimpleRedisSerializerTests.class.getResource("/" + name.replace('.', '/') + ".class");
+
+ InputStream is = null;
+ try {
+
+ is = resource.openStream();
+ byte[] bytes = StreamUtils.copyToByteArray(is);
+ return defineClass(name, bytes, 0, bytes.length);
+ } catch (IOException o_O) {
+ throw new ClassNotFoundException("Cannot read class file", o_O);
+ } finally {
+
+ if (is != null) {
+ try {
+ is.close();
+ } catch (IOException e) {
+ // ignore
+ }
+ }
+ }
+
+ }
+
+ }
}