views:

14

answers:

0

I have a (JAX-WS/EJB3) web service which has operations that can throw ValidationExceptions, which holds a list of standard POJOs that represent stuff that didn't pass validation. This list causes marshaling to break.

Firstly, the exception class:

public class ValidationException extends Exception {
    private final List<ValidationError> validationErrors;
    public ValidationException(Collection<? extends ValidationError> errors){
        super("Validation errors: " + errors);
        this.validationErrors = Collections.unmodifiableList(
            new ArrayList<ValidationError>(errors));
    }
    public List<ValidationError> getValidationErrors(){ 
        return validationErrors; 
    }
}

ValidationError (not related to java.lang.Error) is a very simple POJO containing nothing but a couple of string properties:

public class ValidationError implements Serializable {
    private String id, code, message;
    // Getters/setters for above fields go here.
}

The remote interface and the web service implementation look like this:

@Remote 
public interface StableServiceRemote {
    PonyInfo searchForPony(PonySearch request) 
        throws ValidationException
}
@Stateless
@WebService
public class StableServiceImpl {
    @Override
    public PonyInfo searchForPony(PonySearch request) 
            throws ValidationException
        // Muck around with stuff that may cause ValidationExceptions
    }
}

If an operation throws ValidationException, the exception is unmarshalled properly if the validationErrors list is empty, but if it isn't, this is what the client sees:

javax.xml.bind.MarshalException
- with linked exception:
[javax.xml.bind.JAXBException: class com.example.stablews.ValidationError nor any of its super class is known to this context.]

If I change ValidationException.getValidationErrors() to return ValidationError[] instead of List<ValidationError>, the unmarshalling works fine and I get a nice little list of errors in the response. But why? The return values of some of the web service methods contain lists of custom objects, and that works fine. It seems to me that it's just list/collection properties in exception classes that cause trouble.

Can someone shed some light on this situation - why can't I have a friggin' list property in my exception class?

Some key points:

  • I'd love to blame erasure, but it's not the culprit here, as fields and methods keep type parameter info (and lists works fine in non-exception return values).
  • I deploy on JBoss 4.2.3.
  • There are no errors during deployment - it's only if I throw a ValidationException with a non-empty validationErrors list that the problem occurs.