Monday, April 7, 2008

That not found in this context JAX-B exception

I was throwing together a Java code-first example for a CXF web service this morning, and I encountered a scary gotcha. I want to create a simple customer information service, with an interface like this:

public interface CustomerService {
Customer findCustomerByName(String firstName, String lastName);
}


... The Customer type is a straightforward bean, as per below:


public class Customer {
private String firstName;
private String lastName;
private String skypeId;
private String telephoneNumber;
private int age;

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getSkypeId() {
return skypeId;
}

public void setSkypeId(String skypeId) {
this.skypeId = skypeId;
}

public String getTelephoneNumber() {
return telephoneNumber;
}

public void setTelephoneNumber(String telephoneNumber) {
this.telephoneNumber = telephoneNumber;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public Customer(String firstName, String lastName,

String skypeId,
String telephoneNumber, int age) {
super();
this.firstName = firstName;
this.lastName = lastName;
this.skypeId = skypeId;
this.telephoneNumber = telephoneNumber;
this.age = age;
}
}


When my service implementation returns a Customer, I get an exception:

org.apache.cxf.interceptor.Fault: Marshalling Error: com.iona.ps.codefirst.Customer is not known to this context

Looks quite scary. I lost a lot of time trying to figure out what was going on, thinking that maybe I needed to add JAXB annotations to my Customer class. It turns out however that the problem is that my Bean class doesn't have a default constructor. Ouch. Without a default constructor in place, the JAXB runtime cannot create a default instance of the class. Adding the default constructor to the bean makes everything better.

I've seen through Google that lots of people have encountered this problem before - feels like a usability issue to me. While it may be the case that you need a default constructor in JAXB, CXF should give a more helpful message than "not known to this context".

1 comment:

Tromz said...

Tanx, was useful, I was testing CXF and was passing Interfaces without even realizing it...it could not work, was logic, your entry made me realize it.