javax.XML.unir.JAXBException: Class * * * ni ninguna de sus superclases es conocida en este contexto


Estoy tratando de pasar un objeto a través del servicio web REST. A continuación están mis clases explica la funcionalidad que necesito usando algunos códigos de ejemplo.

Método de Clase de Servicio Web Rest

@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;
}

Clase de respuesta

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;
    }
}

Clase de departamento

@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;
    }

}

Cuando hago una llamada al método getDepartments en la clase rest web service devuelve las siguientes excepciones. Pero si cambio el tipo Objeto de la carga útil a Department en la clase Response devuelve la respuesta json correctamente. Pero como necesito usar esta clase de Respuesta para diferentes tipos de Clases, no puedo restringir la carga útil a un tipo de clase. ¿Alguien puede ayudarme en este asunto?

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
Author: informatik01, 2012-12-27

5 answers

Las implementaciones de JAX-RS soportan automáticamente marshalling/unmarshalling de clases basadas en anotaciones JAXB detectables, pero debido a que su carga útil se declara como Object, creo que el creado JAXBContext pierde la clase Department y cuando es el momento de marshall no sabe cómo.

Una solución rápida y sucia sería agregar un XmlSeeAlso anotación a su clase de respuesta:

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

O algo un poco más complicado sería "enriquecer" el contexto JAXB para la clase Response usando un 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);
    }
}
 54
Author: Bogdan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-28 18:17:07

Esta excepción se puede resolver especificando la ruta completa de la clase.

Ejemplo:

Si usted es una clase llamada ExceptionDetails.java


Forma Incorrecta de pasar argumentos

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

Forma correcta de pasar argumentos

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

Muchas Gracias, Partha

 5
Author: Parthasarathy B,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-26 11:21:19

Tengo el mismo problema y lo resolví añadiendo package to explore al Jaxb2marshaller. Para la primavera se definirá un frijol como este:

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

De esta manera, si todas sus clases de solicitud y respuesta están en el mismo paquete, no necesita indicar específicamente las clases en el JAXBContext

 3
Author: ftrujillo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-03 10:01:55

Tuve un problema similar usando la implementación de referencia JAXB y JBoss COMO 7.1. Pude escribir una prueba de integración que confirmó que JAXB funcionaba fuera del entorno JBoss (lo que sugiere que el problema podría ser el cargador de clases en JBoss).

Este es el código que estaba dando el error (es decir, no funciona):

private static final JAXBContext JC;

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

Y este es el código que funcionó (ValueSet es una de las clases obtenidas de mi 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);
    }
}

En algunos casos tengo la Clase ni ninguno de sus super clase es conocida en este contexto. En otros casos también obtuve una excepción de org.foo.Bar.ValueSet no se puede enviar a org.foo.Bar.ValueSet (similar al problema descrito aquí: ClassCastException cuando se castea a la misma clase).

 0
Author: John,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:06

Me había enfrentado al error similar al admitir una aplicación. Se trataba de las clases generadas para un servicio web SOAP.

El problema fue causado debido a las clases faltantes. Cuando javax.XML.unir.Marshaller estaba tratando de ordenar el objeto jaxb no estaba encontrando todas las clases dependientes después de lo cual fue generado por wsdl y xsd. después de agregar el jar con todas las clases en la ruta de clase, el problema se resolvió.

 0
Author: Sandesh Dhotre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-11 10:03:36