JAXB Exception: Class not known to this context
Asked Answered
B

6

46

When I call a particular restful service method, which is built using CXF, I get the following error, anyone know why and how to resolve it?

JAXBException occurred : class com.octory.ws.dto.ProfileDto nor any of its super class is known to this context...

Following are the service method and relevant DTOs:

public class Service {
   public Response results() {
   Collection<ProfileDto> profilesDto = new ArrayList<ProfileDto>();
   ...
   SearchResultDto srd = new SearchResultDto();
   srd.setResultEntities(profilesDto); // Setting profilesDto collection as resultEntities
   srd.setResultSize(resultSize);
   return Response.ok(srd).build();
   }
}

SearchResultDto:

@XmlRootElement(name="searchResult")
public class SearchResultDto {
    private Collection resultEntities;
    private int resultSize;

    public SearchResultDto() { }

    @XmlElementWrapper(name="resultEntities")
    public Collection getResultEntities() {
        return resultEntities;
    }

    public void setResultEntities(Collection resultEntities) {
        this.resultEntities = resultEntities;
    }

    public int getResultSize() {
        return resultSize;
    }

    public void setResultSize(int resultSize) {
        this.resultSize = resultSize;
    }
}

ProfileDto:

@XmlRootElement(name="profile")
public class ProfileDto {
    ...
    ...
    public ProfileDto() { }
    ...
}
Belkisbelknap answered 13/7, 2010 at 13:11 Comment(0)
G
41

Your ProfileDto class is not referenced in SearchResultDto. Try adding @XmlSeeAlso(ProfileDto.class) to SearchResultDto.

Gadmann answered 13/7, 2010 at 14:42 Comment(8)
Adding @XmlSeeAlso resolved the issue; I was under the impression the annotations was only needed when the referenced class was a sub-class. Thanks.Belkisbelknap
What if the class is SearchResultDto<T> where T is generic ?Hammock
@Hendy Irawan - The annotation can also be added to the web service itself (i.e. after the @WebService annotation). If you are dealing with generics it makes more sense to declare additional types there as by that stage you should know the full set of types.Arrant
@CurtainDog: Thanks for the tip about adding @XmlSeeAlso to the webservice itself. I'd been having problems with generated types and adding @XmlSeeAlso to the generated classes didn't seem to help, but adding that annotation to the webservice cleared up the problem.Uninhibited
@Arrant very useful comment. Btw, is there any alternative use of @XMlSeeAlso in JAX-RS annotated resources?Sectarianism
In my case, the ObjectFactory class did not have a 'create' method for my class. I had to add the method and it fixed the error. While working with Jaxb, as a rule of thumb I always check package-info.java and ObjectFactory.java when such errors are encountered.Sybaris
Worked for me too , in case of multiple classes use like : @XmlSeeAlso({ClassOne.class,ClassTwo.class,....})Pavier
Thank you imnd_neel. This piece of info saved us. In our case, an abstract class had a "child" implementation class. We only had a create method that returned the abstract class from our ObjectFactory. By adding a create method that returns a new implementation class, it solved the problem. Unfortunately, by searching our code base, it would seem that the new create method we added is never used, and is at risk of being deleted by future automated code reviewers, so we added a big comment: do not delete this method!Cerecloth
A
41

I had this error because I registered the wrong class in this line of code:

JAXBContext context = JAXBContext.newInstance(MyRootXmlClass.class);
Aeromechanic answered 29/3, 2012 at 20:25 Comment(0)
D
10

I had the same problem with spring boot. It resolved when i set package to marshaller.

@Bean
public Jaxb2Marshaller marshaller() throws Exception
{
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
    marshaller.setPackagesToScan("com.octory.ws.dto");
    return marshaller;
}

@Bean
public WebServiceTemplate webServiceTemplate(final Jaxb2Marshaller marshaller)   
{
    WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
    webServiceTemplate.setMarshaller(marshaller);
    webServiceTemplate.setUnmarshaller(marshaller);
    return webServiceTemplate;
}
Deejay answered 13/7, 2015 at 8:28 Comment(0)
M
5

This error message happens either because your ProfileDto class is not registered in the JAXB Content, or the class using it does not use @XmlSeeAlso(ProfileDto.class) to make processable by JAXB.

About your comment:

I was under the impression the annotations was only needed when the referenced class was a sub-class.

No, they are also needed when not declared in the JAXB context or, for example, when the only class having a static reference to it has this reference annotated with @XmlTransient. I maintain a tutorial here.

Midis answered 7/8, 2012 at 18:10 Comment(1)
thanks for your tutorial. Should "content" be "context" in this answer?Bowes
T
2

Fixed it by setting the class name to the property "classesToBeBound" of the JAXB marshaller:

<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="classesToBeBound">
          <list>
                <value>myclass</value>
          </list>
        </property>
</bean>
Townshend answered 9/7, 2015 at 9:32 Comment(0)
F
1

I had the same exception on Tomcat.. I found another problem - when i use wsimport over maven plugin to generate stubs for more then 1 WSDLs - class ObjectFactory (stubs references to this class) contains methods ONLY for one wsdl. So you should merge all methods in one ObjectFactory class (for each WSDL) or generate each wsdl stubs in different directories (there will be separates ObjectFactory classes). It solves problem for me with this exception..J

Fronde answered 2/9, 2011 at 11:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.