Interoperability Notes on Apache Axis 1.1 and Microsoft .NET Framework 1.0/1.1 FAQ
Q: What datatypes can be safely used between Java and the Microsoft .NET 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 and arrays of JavaBeans are supported as well.
Q: What about nested complex types, like a JavaBean that contains other beans, which contain arrays of beans, and so on. Does this work?
Q: What about transferring java.util.Calendar values?
A: This works, although there are some things you have to look out for. Under Java, the Calendar class includes timezone information. Under .NET, the System.DateTime structure 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.
Previously, this page has advised that one possible workaround is to assume any time or date to be UTC (i.e. use ToUniversalTime() method on the .NET side when sending times or dates, and correctly parse the time/date strings originating from the Java side). However, such an approach will not work due to the way .NET serializes the DateTime object. The .NET XML serializer always assumes that the DateTime values being serialized represent local machine time, so it applies the machine local time zone offset as the offset portion of the encoded XML. See this article for more details.
Because the .NET XML serializer encodes the DateTime correctly *only* if the DateTime represents the local machine time, the easiest approach is to send the local time in the DateTime, and send the time zone/offset along with it in a separate variable.
Another possible workaround is to specify the value in WSDL as type xsd:date, which does not carry a timezone. This works only if you use WSDL First (more about that below).
Q: But java.util.Calendar can take the value null, while .NET's System.DateTime cannot. Isn't this a problem?
A: Yes. AXIS will serialize a null java.util.Calendar as something like <DateValue xsi:nil='true'/>. De-serializing this XML into a System.DateTime on the .NET side will result in an exception, since System.DateTime can never be nil (not true with .NET 1.1.4322: .NET translates nil dateTime to .NET default DateTime, 0001-01-01T00:00:00). There are some possible workarounds:
- select a particular date value to represent "no date at all", for example 1970/01/01 (or, even better, 0001-01-01). This requires strict enforcement on the Java side so that no nil value is every serialized to the wire (not needed if your .NET version is handling nil dateTime correctly). Also every Java app that uses a Calendar value obtained from a webservice must check the value of the Calendar against this well known "no value" value (this can be solved by adding a custom Axis deserializer that translates 0001-01-01T00:00:00 dateTime to null Calendar using a typeMapping configuration. TODO: add code and configuration sample).
b. Wrap every date value in a wrapper type, that could take the null value. Again, this requires that any Java app that sends dates or times only sends them wrapped within such a structure. .NET Can de-serialize null wrapper types. One project that helps in this area is the NullableTypes project on SF.NET.
c. Do special handling of nil DateTime values on the .NET side, as per here.
d. Wait for .NET 2.0, which has support for Nullable'Types built in.
Q: Can you provide mappings for Java datatypes to their equivalents under .NET?
.NET Framework Type
System.DateTime * see note above
Q: Can the standard Java primitive wrappers like java.lang.Integer or java.lang.Double be used?
A: Sure, why not? Here again, though, you need to concern yourself with null values. Either use one of the workarounds mentioned above in the answer for null java.util.Calendar values, or, don't use the wrapper types, use the value types like int, float, and so on.
Q: What datatypes 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. * Sparse arrays (allowed in SOAP 1.1, not in SOAP 1.2). * 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.
You can avoid these pitfalls automatically by starting with WSDL First.
Q: What design patterns should I use when seeking maximum interoperability?
A: For interop, the best advice is to start with WSDL First. This means you begin designing the Web service by writing WSDL and W3C XML Schema, rather than a Java class or interface. This may feel foreign, but it does pay off in better interop. Rather than specifying a webservice interface in terms of the Java types that are serialized to XML, or de-serialized from XML, WSDL First means you specify the interface in terms of the W3C XML Schema datatypes: xsd:int, xsd:float, xsd:string, xsd:date, and so on, and complexTypes composed of those primitives.
This has the effect of eliminating many interop problems before they start. It also encourages the designer of the web service interface to think in terms of message exchanges, rather than object exchanges.
Q: What if I have a large set of Java classes that I want to use in a webservices interface? I don't want to generate them all from WSDL. Can I still use the WSDL First approach?
A: Well, no. But you can still be interoperable. To do: finish this
Q: How does one go about transmitting attachments between Java and the Microsoft .NET Framework?
A: The base versions of the .NET Framework 1.0 and 1.1 do NOT provide support for attachments.
The Microsoft Web Services Enhancements (WSE) adds support for [/Dime DIME (Direct Internet Message Encapsulation)]. As a result, DIME support requires the installation on WSE on client machines.
Axis supports both MIME and DIME attachments: the server handles either, the client needs to be told to use DIME when sending messages.
Q: Are there any requirements for using Axis with Microsoft Web Services Enhancements (WSE)?
A: To use the WSE toolkit with Axis, you need to turn off WS-Routing.
This can be done by adding the following call:
_server.RequestSoapContext.Path.MustUnderstand = false;
Otherwise you get a MustUnderstand fault when Axis fails to understand the WS-Routing headers. For more info, see Java & .NET Interop - How To.
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.
Click on the following link for a discussion and potential work around to the issue: archive It does appear GZIP compression support will be added in the .NET Framework 2.0. See the following article for more information:
Q: Are there examples of JavaBean serialization and access from a C# or other .Net client?
A: Yes. For a working example see: http://dinoch.dyndns.org:7070/axis1.2/AboutCtService.jsp . It is an AXIS server (v1.2RC3), that exchanges complex types JavaBeans with a C# client. The source is available. This example follows the WSDL First approach - start with WSDL, then generate the server-side and client-side artifacts from that WSDL.
Q: What about examples of Arrays? or an AXIS Server with a VB.NET client?
A: Yes. For a working example see: http://dinoch.dyndns.org:7070/axis1.2/AboutArrays2.jsp . It is an AXIS server 1.2RC3, and there are VB.NET and C# clients. The source is available. For more on Array Interop, see DotNetInteropArrays.
Q: What about very basic examples? Just the primitives. And VB.NET clients?
A: Ok, see: http://dinoch.dyndns.org:7070/axis1.2/AboutEchoService.jsp . It is an AXIS server 1.2RC3, and there are VB.NET and C# clients. The source is available, with a makefile. It echos strings, ints, floats.
Q: Are there any documented web service bugs in Microsoft .NET Framework?
A: Yes, within .NET 1.0 there is an issue with empty array deserialization described in the following article:
- BUG: Incorrect Results Occur When a Web Service Returns an Array of Size 0
- This bug has been corrected in the .NET 1.1 release. Starting with Axis 1.1RC2, you can place the following entry within your WSDD file to work around the issue:
<globalConfiguration> <parameter name="axis.sendMinimizedElements" value="false"/> </globalConfiguration>
It is recommended that you only enable this option if you must support .NET 1.0 clients. }}}
Q: What about issues present in AXIS that affect interop?
A: Yes, be aware of Jira AXIS-1366 , where AXIS publishes a WSDL that does not conform to the actual interface. This is still present in V1.2rC3. The workaround is to build the client from the static WSDL (not the generated WSDL).
Q: Can you provide a recommendation of how to transport a java.util.Map to C#?
A: See DotNetInteropMapInfo.
Q: Is there a list of web service related changes made between the Microsoft .NET Framework 1.0 and 1.1?
A: Yes, See the following articles:
Q: Why sendNull parameter of the method "org.apache.axis.encoding.SerializationContextImpl.serialize" is hard code set to true ?
Remark: When you want to access a Microsoft Web Services, the parameters with a Null value shouldn't be sent. I think it will be interesting to add a Tag in the client-config.wsdd to choose if we want to send <Parameter xsi:nil="true"/> in the SOAP envelope of the request.