1

I'm using the jaxb/jaxws libraries to handle Soap messages. When a soap fault occurs, I have to cast it to one of the message types. That is, I do something like this:

if(exceptionObject instanceof Message1Data){
     Integer errorCode = ((Message1ExceptionData) exceptionObject).
                           getExceptionData().getErrorCode();
}
if(exceptionObject instanceof Message2Data){
     Integer errorCode = ((Message2ExceptionData) exceptionObject).
                           getExceptionData().getErrorCode();
}
//...

For a bunch of different types of messages. All of which have the function getErrorCode() but are auto generated so there isn't any kind of class inheritance.

So this turns into a long series of if statements to just get the errorCode out, which always exists. Is there a way to tell the compiler that its OK to call this function on the object, similar how I would cast an object in order to access certain functions. So instead of doing a bunch of if statements I can remove it and do something like

Integer errorCode = exceptionObject.getExceptionData().getErrorCode();

once, instead of the same code for each type of message? Or is there an option in jaxb/jaxws to tell it that each of these classes implement an interface? (Short of writing a custom library that allows this)

Carlos Bribiescas
  • 4,197
  • 9
  • 35
  • 66
  • Partial duplicate of http://stackoverflow.com/questions/1271980/generating-a-jaxb-class-that-implements-an-interface – Jon Skeet Oct 29 '14 at 17:57

3 Answers3

1

JAXB2 Inheritance Plugin allows you to make your classes implement a given interface or extends a certain class.

Customization directly in the schema:

<xs:complexType name="WillBeMadeCloneableType">
    <xs:annotation>
        <xs:appinfo>
            <inheritance:implements>java.lang.Cloneable</inheritance:implements>
        </xs:appinfo>
    </xs:annotation>
    <!-- ... -->
</xs:complexType>

Or in an external binding file:

<jaxb:bindings node="xsd:simpleType[@name='MyType']">
     <inheritance:implements>java.lang.Cloneable</inheritance:implements>
 </jaxb:bindings>

You can also use generics.

Customizing WSDLs is a bit trickier, but is also possible.

Disclosure: I am the author of the JAXB2 Inheritance plugin which is the part of the JAXB2 Basics package.

Documentation is currently being moved to GitHub. Please check the following links:

lexicore
  • 42,748
  • 17
  • 132
  • 221
0

Not sure how your objects are setup, hopefully it has a base exception that contains your errorCode, because using instanceOf is very bad way to tell what exception you have. You probably should base what Exception you have base on your errerCode:

interface ExceptionBase extends Exception { public int getErrorCode; }
class Message1ExceptionData implements ExceptionBase {
     public int getErrorCode() { return 1; }
}
class Message2ExceptionData implements ExceptionBase { ... return 2; }

switch(exceptionObject.getErrorCode()) {
case 1: Message1ExceptionData exception = (Message1ExceptionData) exceptionObject;
case 2: ...
}
Churk
  • 4,556
  • 5
  • 22
  • 37
0

Reflection might work. It depends on the exact structure of the exception classes. Something like that might do the trick:

Method method = exceptionObject.getClass().getMethod("getExceptionData");
ExceptionData exceptionData = (ExceptionData) method.invoke(exceptionObject);
Integer errorCode = exceptionData.getErrorCode();
Khalid
  • 2,212
  • 11
  • 12