Reputation: 56
I'm trying to deserialize a javax.ws.rs.core.MultivaluedHashMap.
The MultivaluedHashMap implements java.io.Serializable and has a public, no arg constructor.
However when deserializing a previously serialized MultivaluedHashMap, an InvalidClassException, no valid constructor, is thrown:
Exception in thread "main" org.apache.commons.lang3.SerializationException: java.io.InvalidClassException: javax.ws.rs.core.MultivaluedHashMap; no valid constructor at org.apache.commons.lang3.SerializationUtils.deserialize(SerializationUtils.java:231) at org.apache.commons.lang3.SerializationUtils.deserialize(SerializationUtils.java:267) at org.arx.serializationtest.Main.main(Main.java:17) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:497) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) Caused by: java.io.InvalidClassException: javax.ws.rs.core.MultivaluedHashMap; no valid constructor at java.io.ObjectStreamClass$ExceptionInfo.newInvalidClassException(ObjectStreamClass.java:150) at java.io.ObjectStreamClass.checkDeserialize(ObjectStreamClass.java:768) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1775) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351) at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1993) at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1918) at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801) at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371) at org.apache.commons.lang3.SerializationUtils.deserialize(SerializationUtils.java:223) ... 7 more
This is easily reproduced by running the simple 3 lines long main method below:
package test;
import org.apache.commons.lang3.SerializationUtils;
import javax.ws.rs.core.MultivaluedHashMap;
public class Test {
public static void main(String[] args) throws Exception {
MultivaluedHashMap<String, String> map = new MultivaluedHashMap<String, String>();
byte[] serializedMap = SerializationUtils.serialize(map);
MultivaluedHashMap<String, String> deserializedMap = SerializationUtils.deserialize(serializedMap);
}
}
From there I'm not sure how to fix this issue. Any suggestion or pointer would be very much appreciated.
Thanks in advance for your help.
Upvotes: 2
Views: 2107
Reputation: 466
This happened because MultivaluedHashMap does not implement Serializable. To solve this do the following:
import java.io.Serializable;
import javax.ws.rs.core.MultivaluedHashMap;
public class MyMultivaluedHashMap<K, V> extends MultivaluedHashMap<K, V> implements Serializable{
private static final long serialVersionUID = 1L;
public MyMultivaluedHashMap(){
super();
//there are other contruc super class
}
}
//your code
import javax.ws.rs.core.MultivaluedHashMap;
import org.apache.commons.lang3.SerializationUtils;
public class Teste{
public Teste(){}
public static void main(String[] args) throws Exception{
MyMultivaluedHashMap<String, String> map = new MyMultivaluedHashMap<String, String>();
map.addFirst("key-1", "chubby");
map.add("key-2", "skinny");
byte[] serializedMap = SerializationUtils.serialize(map);
System.out.println(serializedMap);
MultivaluedHashMap<String, String> deserializedMap = SerializationUtils.deserialize(serializedMap);
System.out.println(deserializedMap);
}
}
So you just create a new class, MyMultivaluedHashMap, that implements Serializable.
Upvotes: 0
Reputation: 22474
It seems that one of the classes that is needed for deserializeing MultivaluedHashMap
doesn't have a parameterless constructor. You can do something like this:
MultivaluedHashMap<String, String> map = new MultivaluedHashMap<String, String>();
HashMap<String, List<String>> serMap = new HashMap<String, List<String>>(map);
byte[] serializedMap = SerializationUtils.serialize(serMap);
HashMap<String, List<String>> tempMap = SerializationUtils.deserialize(serializedMap);
MultivaluedHashMap<String, String> deserializedMap = new MultivaluedHashMap<String, String>();
for (Entry<String, List<String>> entry : tempMap.entrySet()) {
deserializedMap.put(entry.getKey(), entry.getValue());
}
What this does is to create a HashMap
which will hold all the values needed to reconstruct the original MultivaluedHashMap
and serialize/deserialize this HashMap
instead of the MultivaluedHashMap
.
Upvotes: 1