Hi gang! This version includes revisions based on comments over the last few days. I would not mind if someone checked it into CVS. At this point, I will turn it over to the Axis community for ongoing growth.
Many thanks to everyone for their suggestions, Rick Kellogg <<DotNetInterop.txt>> Interoperability Notes on Apache Axis 1.1 Beta and Microsoft .NET Framework 1.0 FAQ Last Updated: Feb-07-2003 Q: What datatypes can be safely used between Java and the Microsoft .NET 1.0 Framework? A: The following simple Java datatypes can be used: String, boolean, byte, short, int, long, float, and double. You can also create typed arrays of any of the above. Standard Sun JavaBeans (http://java.sun.com/products/javabeans) and arrays of JavaBeans are supported as well. Q: What about transferring java.util.Calendar values? A: There are known problems with serializing/deserializing Calendar objects. Under Java, the Calendar object includes timezone information. Under .NET, the System.DateTime value object does not contain timezone information. The .NET Framework assumes its timezone is the current timezone when serializing and ignores it when deserializing. As a result, values can be off by +/- 24 hours. Two possible work arounds are the use of a string or wrapper value object. When transmitting time values, a long is recommended. Q: Can you provide mappings for Java datatypes to their equivalents under .NET? A: Java C#.NET VB.NET .NET Framework Type String string String System.String boolean bool Boolean System.Boolean byte sbyte -N/A- System.SByte short short Decimal System.Int16 int int Integer System.Int32 long long Long System.Int64 float float Single System.Single double double Double System.Double Q: Can the standard Java primitive wrappers like java.lang.Integer or java.lang.Double be used? A: Not directly. The problem is C# and VB.NET do not support the concept of primitive wrappers. It only has int or long. No Integer or Long datatypes. They do have a System.Object type which can be used to contain a null or the boxed equivalent of a primitive. This looses too much datatype information for my tastes. Q: What datatypes or design patterns should I avoid when seeking maximum interoperability? A: You should avoid the following constructs: * Standard Java Collection classes. * Typesafe enumerations. Use static final variables within Java instead. * Multi-dimensional and jagged arrays. * The Java char datatype is not supported because of an omission in XML Schema. * Avoid using the same method name multiple times with varying parameters on a web service. Q: How does one go about transmitting attachments between Java and the Microsoft .NET 1.0 Framework? A: The basic .NET Framework 1.0 does not provide any support for attachments. The recent Microsoft Web Services Enhancements (WSE) 1.0 does add support for DIME (Direct Internet Message Encapsulation). Please note the upcoming .NET Framework 1.1 does not include WSE. As a result, DIME support would require the installation on WSE on client machines. Axis does support both MIME and DIME attachments. Q: Is there built in support for compressing messages using something like GZIP? A: Unfortunately at this time no. In fact, the .NET Framework does not include a built in compression library. It does appear that using a technique similar to the following article something could be worked out: Retrieving Data from Web Services using Standard HTTP 1.1 Compression http://www.dotnetjunkies.com/tutorials.aspx?tutorialid=304 Q: Can you provide a recommendation of how to transport a java.util.Map to C#? A: The easiest solution is to implement a typed array with a JavaBean. public class MapEntryVO { private Object key; private Object value; public MapEntryVO() { } public MapEntryVO(String key, Object value) { this.key = key; this.value = value; } public Object getKey() { return key; } public void setKey(Object value) { key = value; } public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } } ------------------------------------------------ import java.util.*; public class WebServicesUtils { public static MapEntryVO[] convertMapToMapEntryVO(Map conv) { MapEntryVO[] result = new MapEntryVO[conv.size()]; int i = 0; Iterator iter = conv.entrySet().iterator(); while (iter.hasNext()) { Map.Entry item = (Map.Entry) iter.next(); result[i++] = new MapEntryVO(item.getKey(),item.getValue()); } return result; } } ------------------------------------------------ // Example WebService public class TestService { public MapEntryVO[] testMethod() { java.util.Map value = new java.util.HashMap(); value.put("Key 1","Value 1"); value.put("Key 2","Value 2"); return WebServicesUtils.convertMapToMapEntryVO(value); } }
Interoperability Notes on Apache Axis 1.1 Beta and Microsoft .NET Framework 1.0 FAQ Last Updated: Feb-07-2003 Q: What datatypes can be safely used between Java and the Microsoft .NET 1.0 Framework? A: The following simple Java datatypes can be used: String, boolean, byte, short, int, long, float, and double. You can also create typed arrays of any of the above. Standard Sun JavaBeans (http://java.sun.com/products/javabeans) and arrays of JavaBeans are supported as well. Q: What about transferring java.util.Calendar values? A: There are known problems with serializing/deserializing Calendar objects. Under Java, the Calendar object includes timezone information. Under .NET, the System.DateTime value object does not contain timezone information. The .NET Framework assumes its timezone is the current timezone when serializing and ignores it when deserializing. As a result, values can be off by +/- 24 hours. Two possible work arounds are the use of a string or wrapper value object. When transmitting time values, a long is recommended. Q: Can you provide mappings for Java datatypes to their equivalents under .NET? A: Java C#.NET VB.NET .NET Framework Type String string String System.String boolean bool Boolean System.Boolean byte sbyte -N/A- System.SByte short short Decimal System.Int16 int int Integer System.Int32 long long Long System.Int64 float float Single System.Single double double Double System.Double Q: Can the standard Java primitive wrappers like java.lang.Integer or java.lang.Double be used? A: Not directly. The problem is C# and VB.NET do not support the concept of primitive wrappers. It only has int or long. No Integer or Long datatypes. They do have a System.Object type which can be used to contain a null or the boxed equivalent of a primitive. This looses too much datatype information for my tastes. Q: What datatypes or design patterns should I avoid when seeking maximum interoperability? A: You should avoid the following constructs: * Standard Java Collection classes. * Typesafe enumerations. Use static final variables within Java instead. * Multi-dimensional and jagged arrays. * The Java char datatype is not supported because of an omission in XML Schema. * Avoid using the same method name multiple times with varying parameters on a web service. Q: How does one go about transmitting attachments between Java and the Microsoft .NET 1.0 Framework? A: The basic .NET Framework 1.0 does not provide any support for attachments. The recent Microsoft Web Services Enhancements (WSE) 1.0 does add support for DIME (Direct Internet Message Encapsulation). Please note the upcoming .NET Framework 1.1 does not include WSE. As a result, DIME support would require the installation on WSE on client machines. Axis does support both MIME and DIME attachments. Q: Is there built in support for compressing messages using something like GZIP? A: Unfortunately at this time no. In fact, the .NET Framework does not include a built in compression library. It does appear that using a technique similar to the following article something could be worked out: Retrieving Data from Web Services using Standard HTTP 1.1 Compression http://www.dotnetjunkies.com/tutorials.aspx?tutorialid=304 Q: Can you provide a recommendation of how to transport a java.util.Map to C#? A: The easiest solution is to implement a typed array with a JavaBean. public class MapEntryVO { private Object key; private Object value; public MapEntryVO() { } public MapEntryVO(String key, Object value) { this.key = key; this.value = value; } public Object getKey() { return key; } public void setKey(Object value) { key = value; } public Object getValue() { return value; } public void setValue(Object value) { this.value = value; } } ------------------------------------------------ import java.util.*; public class WebServicesUtils { public static MapEntryVO[] convertMapToMapEntryVO(Map conv) { MapEntryVO[] result = new MapEntryVO[conv.size()]; int i = 0; Iterator iter = conv.entrySet().iterator(); while (iter.hasNext()) { Map.Entry item = (Map.Entry) iter.next(); result[i++] = new MapEntryVO(item.getKey(),item.getValue()); } return result; } } ------------------------------------------------ // Example WebService public class TestService { public MapEntryVO[] testMethod() { java.util.Map value = new java.util.HashMap(); value.put("Key 1","Value 1"); value.put("Key 2","Value 2"); return WebServicesUtils.convertMapToMapEntryVO(value); } }
