Last active
December 11, 2015 09:59
-
-
Save bjpeterdelacruz/4583918 to your computer and use it in GitHub Desktop.
How to dynamically load a class, de-serialize an object that was serialized using the loaded class, and ignore serialVersionUID in a unit test.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private URLClassLoader childClassLoader; | |
private Class<?> clazz; | |
@Before | |
public void init() throws Exception { | |
// put class file in same package together with this source file | |
URL url = getClass().getResource("MyClass.class").toURI().toURL(); | |
childClassLoader = new URLClassLoader(new URL[] { url }, | |
getClass().getClassLoader()); | |
clazz = childClassLoader.loadClass("com.bpd.old.MyClass"); | |
} | |
@After | |
public void cleanup() throws Exception { | |
childClassLoader.close(); | |
} | |
@Test | |
public void test() throws Exception { | |
InputStream is = getClass().getResourceAsStream("MyClass.old"); | |
CustomObjectInputStream ois = new CustomObjectInputStream(is); | |
System.out.println(ois.readObject()); | |
} | |
private class CustomObjectInputStream extends ObjectInputStream { | |
public CustomObjectInputStream(InputStream in) throws IOException { | |
super(in); | |
} | |
@Override | |
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, | |
ClassNotFoundException { | |
if (!desc.getName().contains("com.bpd.old.MyClass")) { | |
return super.resolveClass(desc); | |
} | |
return clazz; | |
} | |
@Override | |
protected ObjectStreamClass readClassDescriptor() throws IOException, | |
ClassNotFoundException { | |
ObjectStreamClass resultClassDescriptor = super.readClassDescriptor(); | |
if (resultClassDescriptor.getSerialVersionUID() == 0) { | |
// if serialVersionUID is zero, object is an enum | |
return resultClassDescriptor; | |
} | |
ObjectStreamClass localClassDescriptor = ObjectStreamClass.lookup(clazz); | |
if (localClassDescriptor != null) { | |
final long localSUID = localClassDescriptor.getSerialVersionUID(); | |
final long streamSUID = resultClassDescriptor.getSerialVersionUID(); | |
if (streamSUID != localSUID) { | |
resultClassDescriptor = localClassDescriptor; | |
} | |
} | |
return resultClassDescriptor; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment