javax.xml.bind.JAXBException: Class *** nor any of its super class is known to this context

JavaRestJaxbJax Rs

Java Problem Overview


I'm trying to pass a object via REST web service. Following are my classes explains the functionality that I need using some example codes.

Rest Web Service Class method

@POST
@Path("/find")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces({MediaType.APPLICATION_JSON})
public Response getDepartments(){
	Response response = new Response();
			
	try {
		
		response.setCode(MessageCode.SUCCESS);
		response.setMessage("Department Names");
		Department dept = new Department("12", "Financial");
		response.setPayload(dept);

	} catch (Exception e) {
		response.setCode(MessageCode.ERROR);
		response.setMessage(e.getMessage());
		e.printStackTrace();
	}		
	return response;
}

Response Class

import java.io.Serializable;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement

public class Response implements Serializable{
	
	private static final long serialVersionUID = 1L;

	public enum MessageCode {
		SUCCESS, ERROR, UNKNOWN
	}

	private MessageCode code;
	private String message;
	private Object payload;
	
	public MessageCode getCode() {
		return code;
	}
	
	public void setCode(MessageCode code) {
		this.code = code;
	}
	
	public String getMessage() {
		return message;
	}
	
	public void setMessage(String message) {
		this.message = message;
	}
	
	public Object getPayload() {
		return payload;
	}
	
	public void setPayload(Object payload) {
		this.payload = payload;
	}
}

Department Class

@XmlRootElement
public class Department implements java.io.Serializable {

	
	private String deptNo;
	private String deptName;


	public Department() {
	}

	public Department(String deptNo, String deptName) {
		this.deptNo = deptNo;
		this.deptName = deptName;
	}

	public String getDeptNo() {
		return this.deptNo;
	}

	public void setDeptNo(String deptNo) {
		this.deptNo = deptNo;
	}

	public String getDeptName() {
		return this.deptName;
	}

	public void setDeptName(String deptName) {
		this.deptName = deptName;
	}

}

When I make a call to getDepartments method in the rest web service class it returns following exceptions. But If I change the type Object of the payload to Department in the Response class it returns the json response correctly. But since I need to use this Response class for different types of Classes I can't restring the payload to one class type. Can anyone please help me in this matter?

Stack Trace

Dec 27, 2012 9:34:18 PM com.sun.jersey.spi.container.ContainerResponse logException
SEVERE: Mapped exception to response: 500 (Internal Server Error)
javax.ws.rs.WebApplicationException: javax.xml.bind.MarshalException
 - with linked exception:
[javax.xml.bind.JAXBException: class Department nor any of its super class is known to this context.]
	at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.writeTo(AbstractRootElementProvider.java:159)
	at com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:306)
	at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1437)
	at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1349)
	at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1339)
	at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:416)
	at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
	at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:699)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
	at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
	at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:401)
	at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
	at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
	at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766)
	at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:450)
	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
	at org.mortbay.jetty.Server.handle(Server.java:326)
	at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
	at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:945)
	at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
	at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
	at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
	at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
	at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Caused by: javax.xml.bind.MarshalException
 - with linked exception:
[javax.xml.bind.JAXBException: class Department nor any of its super class is known to this context.]
	at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:323)
	at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:177)
	at com.sun.jersey.json.impl.BaseJSONMarshaller.marshallToJSON(BaseJSONMarshaller.java:103)
	at com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider.writeTo(JSONRootElementProvider.java:136)
	at com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.writeTo(AbstractRootElementProvider.java:157)
	... 23 more
Caused by: javax.xml.bind.JAXBException: class Department nor any of its super class is known to this context.
	at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:250)
	at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:265)
	at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:657)
	at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:156)
	at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:344)
	at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:597)
	at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:328)
	at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:498)
	at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:320)
	... 27 more
Caused by: javax.xml.bind.JAXBException: class Department nor any of its super class is known to this context.
	at com.sun.xml.bind.v2.runtime.JAXBContextImpl.getBeanInfo(JAXBContextImpl.java:611)
	at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:652)
	... 33 more

Java Solutions


Solution 1 - Java

JAX-RS implementations automatically support marshalling/unmarshalling of classes based on discoverable JAXB annotations, but because your payload is declared as Object, I think the created JAXBContext misses the Department class and when it's time to marshall it it doesn't know how.

A quick and dirty fix would be to add a XmlSeeAlso annotation to your response class:

@XmlRootElement
@XmlSeeAlso({Department.class})
public class Response implements Serializable {
  ....

or something a little more complicated would be "to enrich" the JAXB context for the Response class by using a ContextResolver:

import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;

@Provider
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public class ResponseResolver implements ContextResolver<JAXBContext> {
	private JAXBContext ctx;

	public ResponseResolver() {
		try {
			this.ctx = JAXBContext.newInstance(
                                      
                        Response.class, 
                        Department.class

                    );
		} catch (JAXBException ex) {
			throw new RuntimeException(ex);
		}
	}

	public JAXBContext getContext(Class<?> type) {
		return (type.equals(Response.class) ? ctx : null);
	}
}

Solution 2 - Java

I have the same problem and I solved it by adding package to explore to the Jaxb2marshaller. For spring will be define a bean like this:

@Bean
	public Jaxb2Marshaller marshaller() {
		Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
		String[] packagesToScan= {"<packcge which contain the department class>"};
		marshaller.setPackagesToScan(packagesToScan);
		return marshaller;
	}

By this way if all your request and response classes are in the same package you do not need to specifically indicate the classes on the JAXBcontext

Solution 3 - Java

This exception can be solved by specifying a full class path.

Example:

If you are using a class named ExceptionDetails


Wrong Way of passing arguments

JAXBContext jaxbContext = JAXBContext.newInstance(ExceptionDetails.class);

Right Way of passing arguments

JAXBContext jaxbContext = JAXBContext.newInstance(com.tibco.schemas.exception.ExceptionDetails.class);

Solution 4 - Java

I had a similar issue using the JAXB reference implementation and JBoss AS 7.1. I was able to write an integration test that confirmed JAXB worked outside of the JBoss environment (suggesting the problem might be the class loader in JBoss).

This is the code that was giving the error (i.e. not working):

private static final JAXBContext JC;

static {
	try {
		JC = JAXBContext.newInstance("org.foo.bar");
	} catch (Exception exp) {
		throw new RuntimeException(exp);
	}
}

and this is the code that worked (ValueSet is one of the classes marshaled from my XML).

private static final JAXBContext JC;

static {
	try {
		ClassLoader classLoader = ValueSet.class.getClassLoader();
		JC = JAXBContext.newInstance("org.foo.bar", classLoader);
	} catch (Exception exp) {
		throw new RuntimeException(exp);
	}
}

In some cases I got the Class nor any of its super class is known to this context. In other cases I also got an exception of org.foo.bar.ValueSet cannot be cast to org.foo.bar.ValueSet (similar to the issue described here: https://stackoverflow.com/questions/826319/classcastexception-when-casting-to-the-same-class).

Solution 5 - Java

I had faced the similar error when supporting one application. It was about the generated classes for a SOAP Webservice.

The issue was caused due to the missing classes. When javax.xml.bind.Marshaller was trying to marshal the jaxb object it was not finding all dependent classes which were generated by using wsdl and xsd. after adding the jar with all the classes at the class path the issue was resolved.

Solution 6 - Java

Ftrujillo's answer works well but if you only have one package to scan this is the shortest form::

    @Bean
    public Jaxb2Marshaller marshaller() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        marshaller.setContextPath("your.package.to.scan");
        return marshaller;
    }

Solution 7 - Java

This errors occurs when we use same method name for Jaxb2Marshaller for exemple:

    @Bean
    public Jaxb2Marshaller marshallerClient() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        // this package must match the package in the <generatePackage> specified in
        // pom.xml
        marshaller.setContextPath("library.io.github.walterwhites.loans");

        return marshaller;
    }

And on other file

    @Bean
    public Jaxb2Marshaller marshallerClient() {
        Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
        // this package must match the package in the <generatePackage> specified in
        // pom.xml
        marshaller.setContextPath("library.io.github.walterwhites.client");

        return marshaller;
    }

Even It's different class, you should named them differently

Solution 8 - Java

I know that it's an old question, but you can change the Response using a parameter (P):

public class Response<P> implements Serializable{

private static final long serialVersionUID = 1L;

public enum MessageCode {
    SUCCESS, ERROR, UNKNOWN
}

private MessageCode code;
private String message;
private P payload;

...
public P getPayload() {
    return payload;
}

public void setPayload(P payload) {
    this.payload = payload;
}

}

The method would be

public Response<Departments> getDepartments(){...}

I can't try it now but it should works.

Otherwise it's possible to extends Response

@XmlRootElement    
public class DepResponse extends Response<Department> {<no content>}

Solution 9 - Java

Like already proposed by @ftrujillo if you use the Spring Jaxb2Marshaller, you can set the packages to scan. In some cases, if there is a more sophisticated XSD model with inheritance or have just more wide spread model, there could be a problem to get the information in the class hierarchy which packages to scan, then you can use the scan of the object hierarchy. In such case I took the advantage of the following function, handling the plain POJO hierarchy (I believe it could be possibly enhanced for non-simple POJO):

....
			Jaxb2Marshaller locMarshaller = new Jaxb2Marshaller();
			locMarshaller.setPackagesToScan(
					resolveJaxb2MarshallerPackagesToScan(
							someFaultContentContainerClass,
							someFaultContentClass
					)
			);
...

	/**
	 * Resolves the packages which have to be passed into the Spring Jaxb2Marshaller
	 * to be able to perform the serialization/deserialization action
	 * @param aClassesToBeMarshalled classes which has to be marshalled. Null array items
	 *   are ignored without any error.
	 * @return packages which have to be scanned by Spring Jaxb2Marshaller for it.
	 */
	public static String[] resolveJaxb2MarshallerPackagesToScan(Class<?>... aClassesToBeMarshalled) {
		List<String> locResultList = new ArrayList<>();
		for (Class<?> locProcessedTopLevelClass : aClassesToBeMarshalled) {
			Class<?> locProcessedClass = locProcessedTopLevelClass;
			while (locProcessedClass != null) {
				if (!locResultList.contains(locProcessedClass.getPackageName()))
					locResultList.add(locProcessedClass.getPackageName());
				locProcessedClass = locProcessedClass.getSuperclass();
			}
		}
		return locResultList.toArray(new String[0]);
	}


Solution 10 - Java

I had a similar error, same error message but different cause.

In my case the problem was an incomplete ObjectFactory implementation which was automatically created empty. After coding the ObjectFactory for my main class the problem was solved.

@XmlRegistry
public class ObjectFactory {

    /**
     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: x
     * 
     */
    public ObjectFactory() {
    }

    public CartaPorte createCartaPorte() {
        return new CartaPorte();
    }
}

Solution 11 - Java

In addition to defining the packags to scan, we must also ensure that we have @XmlRootElement annotation on top of the class we are trying to unmarshal/marshal.

Example:

@Bean
public Jaxb2Marshaller jaxb2Marshaller() {
    var jaxb2Marshaller = new Jaxb2Marshaller();
    jaxb2Marshaller.setPackagesToScan("com.yourpackages");

    return jaxb2Marshaller;
}

@Data
@XmlRootElement
public class ValueIndividual{
    private String id;
    private Member member;
    private UserDate updated;
    private String language_v;
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionShanakaView Question on Stackoverflow
Solution 1 - JavaBogdanView Answer on Stackoverflow
Solution 2 - JavaftrujilloView Answer on Stackoverflow
Solution 3 - JavaParthasarathy BView Answer on Stackoverflow
Solution 4 - JavaJohnView Answer on Stackoverflow
Solution 5 - JavaSandesh DhotreView Answer on Stackoverflow
Solution 6 - JavaMike D3ViD TysonView Answer on Stackoverflow
Solution 7 - JavaWalterwhitesView Answer on Stackoverflow
Solution 8 - JavaDaniele LicitraView Answer on Stackoverflow
Solution 9 - JavaArtur LinhartView Answer on Stackoverflow
Solution 10 - JavaZooMMXView Answer on Stackoverflow
Solution 11 - JavaJCompetenceView Answer on Stackoverflow