May 07 2009
Using different data types between Java and WCF
Many C# or Java data types can be described by using XML Schema so that we can use XML Schema to communicate between Java and WCF.
- Primitive Data Types
- String
- Enumeration
- Complex Types: Structure or Class
- Array, List
- DateTime
Primitive data types such as byte, short, int, long, float, double, boolean, char are almost the same in C# and Java. You can use these data types in WCF Contract normally. But there are some points you must pay attention to:
using short in Java when the type is byte in C#;
using int in Java when the type is char in C#.
Here, I listed the details of primitive data types:
|
Java Client Data Type |
C# WCF Data Type |
|
short |
byte |
|
short |
short |
|
int |
int |
|
long |
long |
|
float |
float |
|
double |
double |
|
Boolean |
Boolean |
|
int |
char |
C# has a System.String class which is analogous to the java.lang.String class. In C#, the string class can be written as string or String.
WCF sends and receives an enumeration value with its name in the String format. For example, for an enumeration variable (C#) as follows:
public enum EnumColor
{
enumBlack = 0,
enumWhite = 1,
enumRed = 2
}
The generated code is as follows:
@XmlType(name = "EnumColor")
@XmlEnum
public enum EnumColor {
@XmlEnumValue("enumBlack")
ENUM_BLACK("enumBlack"),
@XmlEnumValue("enumWhite")
ENUM_WHITE("enumWhite"),
@XmlEnumValue("enumRed")
ENUM_RED("enumRed");
private final String value;
EnumColor(String v) {
value = v;
}
public String value() {
return value;
}
public static EnumColor fromValue(String v) {
for (EnumColor c: EnumColor.values()) {
if (c.value.equals(v)) {
return c;
}
}
throw new IllegalArgumentException(v);
}
}
[DataContract]
public class CompositeType {
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue {
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue {
get { return stringValue; }
set { stringValue = value; }
}
}
“[DataContract]” and “[DataMember]” make a class or a structure serializable. If a member variable is declared as a [DataMember], it will be serialized. Then you can write the following code in Java class:
ObjectFactory of = new ObjectFactory();
CompositeType composite = of.createCompositeType();
composite.setBoolValue(true); composite.setStringValue(of.createCompositeTypeStringValue("world"));
CompositeType returnComposite = port.getDataUsingDataContract(composite);
The Array or List data types can be used as parameters in WCF Operation Contract and the generated Java code of these two data types is the same. Metro generates a new data type by adding a prefix “ArrayOf”. For example: List and String[] are both translated to ArrayOfstring. This class can be used in Java as follows:
ArrayOfstring arrayValue = new ArrayOfstring();
arrayValue.getString().add("This");
There is a data type named “DateTime” in C#. It describes date, time and time zone information. For the DateTime type, Metro generates Java code with the corresponding type “XMLGregorianCalendar”. You can use the XMLGregorianCalendar type directly. However, Java generally uses “GregorianCalendar” to declare date time variable. Therefore, it is necessary to make a conversion between GregorianCalendar and XMLGregorianCalendar.
/*Convert GregorianCalendar to XMLGregorianCalendar*/
public XMLGregorianCalendar convertCalendarToXMLCalendar(GregorianCalendar objGregorianCalendar)
{
XMLGregorianCalendar objXMLGregorianCalendar = DatatypeFactory.newInstance().newXMLGregorianCalendar(objGregorianCalendar);
return objXMLGregorianCalendar;
}
/*Convert XMLGregorianCalendar to GregorianCalendar*/
public GregorianCalendar convertXMLCalendarToCalendar(XMLGregorianCalendar objXMLGregorianCalendar)
{
objXMLGregorianCalendar.objXMLGregorianCalendar.toGregorianCalendar();
}
Links:
Previous article >>>>: Data types between Java and WCF
Next article >>>>:
WCF & Java Interop series home page: WCF & Java Interop

Great series of articles on WCF and Java interoperability. This subject is not well addressed anywhere. We are also using a WCF server and were testing out a Java client. We ran into some issues with a string DataMember that is defined in our WCF with “IsRequired = false”. This produced an xsd element with minOccurs=”0″ and nillable=”true”. This caused our Java client to want a JAXBElement instead of just a string.
I was wondering if you ran across this with your system. It would be nice if there was a way to omit the nillable=true in the generated xsd. I have not found any DataMemberAttributes that would result in this.
I am looking forward to more of your articles in this series.
Thanks,
Charlie
Charlie,
We did run across the same issue in our SCM Anywhere.
You can use the methods of JAXBElement to get and set string values. If you are not comfortable with JAXBElement, you can try avoiding “IsRequired = false” in your DataMember definition by providing default values in your function calls.
Thanks,
Kevin
Have you tried setting EmitDefaultValue=false for the DataMember attribute?
One thing you also have to remember is that XMLGregorianCalendar and java.util.Calendar differ in the numeric value they use for January (1 and 0 respectively). The conversion example between the calendars above needs to be changed to reflect this difference.