It is my first time with json and java. I've check a lot of question/ post with the same error like mine. But haven't find anything usefull.
I've uderstood that I have to add no args constructor. I've maded, but it didnt helped me. Still the same error occur. It can work that way. I think that is related with quite complecated iheritance of mine code.
ERROR:
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/derp] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: Failed to invoke public com.derp.procedure.model.SkeletonElement() with no args] with root cause java.lang.InstantiationException
StackTrace:
gru 19, 2014 8:27:50 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [dispatcher] in context with path [/derp] threw exception [Request processing failed; nested exception is java.lang.RuntimeException: Failed to invoke public com.derp.procedure.model.SkeletonElement() with no args] with root cause
java.lang.InstantiationException
at sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at com.google.gson.internal.ConstructorConstructor$3.construct(ConstructorConstructor.java:104)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:186)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60)
at com.google.gson.Gson.fromJson(Gson.java:810)
at com.google.gson.Gson.fromJson(Gson.java:775)
at com.google.gson.Gson.fromJson(Gson.java:724)
at com.derp.procedure.model.SkeletonElement.toObject(SkeletonElement.java:38)
at com.derp.procedure.model.Skeleton.setSkeletonElements(Skeleton.java:53)
at com.derp.procedure.controller.ProcedureController.elementsAssignmentSubmit(ProcedureController.java:81)
at com.derp.procedure.controller.ProcedureController$$FastClassBySpringCGLIB$$35de90ba.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:266)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
at com.derp.procedure.controller.ProcedureController$$EnhancerBySpringCGLIB$$fe2945ed.elementsAssignmentSubmit(<generated>)
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:483)
at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doPut(FrameworkServlet.java:879)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:136)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:526)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:655)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:146)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:279)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
My java classes:
Generic model class that is extended:
package com.derp.generic.model;
import java.io.IOException;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
@MappedSuperclass
public abstract class GenericModel<T extends GenericModel<?>> {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
public long getId() {return id;}
public void setId(long id) {this.id = id;}
public GenericModel() {
}
// a toString method that can be used in any class.
// uses reflection to dynamically print java class field
// values one line at a time.
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}
public String toJson() {
ObjectMapper jsonMapper = new ObjectMapper();
try {
return jsonMapper.writerWithDefaultPrettyPrinter().writeValueAsString(this);
} catch (JsonGenerationException e) {
e.printStackTrace();
return null;
} catch (JsonMappingException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
//public GenericModel<T> toObject(String jsonObject) {
//Suggested by stackOverflowComunity at:
//https://stackoverflow.com/questions/27532206/java-create-list-of-objects-from-json-string-with-jackson
public <T> T toObject(String jsonObject) {
ObjectMapper jsonMapper = new ObjectMapper();
try {
//GenericModel<T> t = jsonMapper.readValue(jsonObject, GenericModel.class);
T t = (T) jsonMapper.readValue(jsonObject, GenericModel.class);
//return t;
return t;
} catch (JsonGenerationException e) {
e.printStackTrace();
return null;
} catch (JsonMappingException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}
Generic hierarchical class that extends generic model:
package com.derp.generic.model;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.FetchType;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToMany;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
@MappedSuperclass
public abstract class GenericHierarchicalModel<T extends GenericHierarchicalModel<T>> extends GenericModel<T> {
private String name;
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private T parent;
@OneToMany(mappedBy = "parent")
private List<T> children;
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public T getParent() {return parent;}
public void setParent(T parent) {this.parent = parent;}
public List<T> getChildren() {return children;}
public void setChildren(List<T> children) {this.children = children;}
public GenericHierarchicalModel() {
super();
}
@Override
public String toJson() {
return "{\"title\":\"" + this.name + "\", \"id\":\"" + this.getId() + "\", \"children\": [" + listToJson(this.getChildren()) + "]}";
}
public String listToJson(List<T> children) {
String json = "";
for(int i=0; i<children.size(); i++) {
json = json + children.get(i).toJson();
if(children.size()!=i+1) {
json = json + ", ";
}
}
return json;
}
// @Override
// public GenericHierarchicalModel<T> toObject(String jsonObject) {
// int start = 0; // '(' position in string
// int end = 0; // ')' position in string
// for(int i = 0; i < jsonObject.length(); i++) {
// if(jsonObject.charAt(i) == '{') // Looking for '{' position in string
// start = i;
// else if(jsonObject.charAt(i) == '}') // Looking for '}' position in string
// end = i;
// }
// String number = jsonObject.substring(start+1, end); // you take value between start and end
// System.out.println(number);
// return null;
// }
}
Model class that I am trying to deserialize from json list of objects:
package com.derp.procedure.model;
import java.io.IOException;
import java.util.List;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import com.derp.generic.model.GenericHierarchicalModel;
import com.derp.generic.model.GenericModel;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
@Entity
@Table(name="procedure__SkeletonElement")
@Inheritance(strategy=InheritanceType.JOINED)
@DiscriminatorColumn(name="type")
public abstract class SkeletonElement extends GenericHierarchicalModel<SkeletonElement> {
@Transient
public String getDecriminatorValue() {
return this.getClass().getSimpleName();
}
@Override
public String toJson() {
return "{\"title\":\"" + this.getName() + "\", \"id\":\"" + this.getId() + "\", \"type\":\"" + this.getDecriminatorValue() + "\", \"children\": [" + listToJson(this.getChildren()) + "]}";
}
public List<SkeletonElement> toObject(String jsonObject) {
Gson gson = new Gson(); // Or use new GsonBuilder().create();
//SkeletonElement[] target2 = gson.fromJson(jsonObject, SkeletonElement[].class);
List<SkeletonElement> target2 = gson.fromJson(jsonObject, new TypeToken<List<SkeletonElement>>(){}.getType());
return target2;
}
public SkeletonElement() {
super();
}
}
And the class that contain collection of object that I am trying to deserialize back to java list of objects:
package com.derp.procedure.model;
import java.util.LinkedList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import com.derp.generic.model.GenericDictionaryModel;
@Entity
@Table(name="procedure__Skeleton")
public class Skeleton extends GenericDictionaryModel<Skeleton> {
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private List<SkeletonElement> skeletonElements;
public void setSkeletonElements(List<SkeletonElement> skeletonElements) {this.skeletonElements = skeletonElements;}
public List<SkeletonElement> getSkeletonElements() {return skeletonElements;}
public List<SkeletonElement> getSkeletonParentsElements() {
List<SkeletonElement> skeletonParentsElements = new LinkedList<SkeletonElement>();
for(int i=0; i<this.skeletonElements.size(); i++) {
if(this.skeletonElements.get(i).getParent()==null) {
skeletonParentsElements.add(this.getSkeletonElements().get(i));
}
}
return skeletonParentsElements;
}
public Skeleton(String name) {
super(name);
}
public Skeleton() {
// TODO Auto-generated constructor stub
}
public String getSkeletonElementsJsonTree() {
String jsonTreeString ="[";
List<SkeletonElement> skeletonParentsElements = getSkeletonParentsElements();
for(int i=0; i<skeletonParentsElements.size(); i++) {
jsonTreeString = jsonTreeString + skeletonParentsElements.get(i).toJson();
if((1+i) != skeletonParentsElements.size()) {
jsonTreeString = jsonTreeString + ",";
}
}
return jsonTreeString + "]";
}
public void setSkeletonElements(String skeletonElementsJson) {
this.skeletonElements.get(0).toObject(skeletonElementsJson);
}
}
And at least my json string that I wont to deserialize:
[
{
"name": "Title1",
"id": "1",
"type": "SkeletonJobElement",
"parent_id": "null",
"children": [
{
"name": "Title11",
"id": "2",
"type": "SkeletonJobElement",
"parent_id": "1",
"children": [
{
"name": "Title111",
"id": "5",
"type": "SkeletonFileElement",
"parent_id": "2",
"children": []
},
{
"name": "Title112",
"id": "6",
"type": "SkeletonFileElement",
"parent_id": "2",
"children": []
}
]
}
]
},
{
"name": "Title2",
"id": "3",
"type": "SkeletonJobElement",
"parent_id": "null",
"children": [
{
"name": "Title21",
"id": "4",
"type": "SkeletonJobElement",
"parent_id": "3",
"children": []
}
]
}
]
I know that is a lot of code to analize, but please help me figure it out. I struggle with it for week so long.
com.derp.procedure.model.SkeletonElement
is an abstract class. Make this class concrete deleting the abstract modifier.
If you want to keep class abstract, you need to write custom deserialization using Gson's JsonDeserializer
and register it as type adapter. So let's say you have abstract class A
and derived class B
(B
extends A
):
JsonDeserializer<A> deserializer = ...;
gsonBuilder.registerTypeAdapter(A.class, deserializer);
Now inside JsonDeserializer
you have to specify that A
should deserialize into B
:
return context.deserialize(json, B.class);
That makes more sense if you have multiple classes that derive from abstract class A
. Let's say that both B
and C
derive from A
. In that scenario you would need to handle deserialization for both of them (inside JsonDeserializer<A>
):
if (json is of class B) {
return context.deserialize(json, B.class);
}
if (json is of class C) {
return context.deserialize(json, C.class);
}
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With