Differences between revisions 21 and 22
Revision 21 as of 2006-02-19 23:39:10
Size: 13978
Editor: JasonCone
Comment:
Revision 22 as of 2009-09-20 22:49:10
Size: 14032
Editor: localhost
Comment: converted to 1.6 markup
Deletions are marked like this. Additions are marked like this.
Line 2: Line 2:
'''Interoperability Notes on Apache Axis 1.1 and [http://msdn.microsoft.com/library/default.asp?url=/downloads/list/netdevframework.asp Microsoft .NET Framework] 1.0/1.1 FAQ''' '''Interoperability Notes on Apache Axis 1.1 and [[http://msdn.microsoft.com/library/default.asp?url=/downloads/list/netdevframework.asp|Microsoft .NET Framework]] 1.0/1.1 FAQ'''
Line 10: Line 10:
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 [http://java.sun.com/products/javabeans/ JavaBeans] and arrays of {{{JavaBeans}}} are supported as well. 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 [[http://java.sun.com/products/javabeans/|JavaBeans]] and arrays of {{{JavaBeans}}} are supported as well.
Line 19: Line 19:
A: This works, although there are some things you have to look out for. Under Java, the [http://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html Calendar] class includes timezone information. Under .NET, the [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemDateTimeClassTopic.asp 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. A: This works, although there are some things you have to look out for. Under Java, the [[http://java.sun.com/j2se/1.4.2/docs/api/java/util/Calendar.html|Calendar]] class includes timezone information. Under .NET, the [[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemDateTimeClassTopic.asp|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.
Line 21: Line 21:
Previously, this page has advised that one possible workaround is to assume any time or date to be UTC (i.e. use [http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemDateTimeClassToUniversalTimeTopic.asp 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 [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/datetimecode.asp this article] for more details. Previously, this page has advised that one possible workaround is to assume any time or date to be UTC (i.e. use [[http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemDateTimeClassToUniversalTimeTopic.asp|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 [[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/datetimecode.asp|this article]] for more details.
Line 33: Line 33:
 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 [http://nullabletypes.sourceforge.net/ the NullableTypes project] on SF.NET.  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 [[http://nullabletypes.sourceforge.net/|the NullableTypes project]] on SF.NET.
Line 35: Line 35:
 c. Do special handling of nil Date''''''Time values on the .NET side, as per [http://cheeso.members.winisp.net/srcview.aspx?dir=xml-serialization&file=XsiNilDate.cs here].  c. Do special handling of nil Date''''''Time values on the .NET side, as per [[http://cheeso.members.winisp.net/srcview.aspx?dir=xml-serialization&file=XsiNilDate.cs|here]].
Line 46: Line 46:
 || String || string || String || [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemStringClassTopic.asp System.String] ||
 || boolean|| bool || Boolean|| [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemBooleanClassTopic.asp System.Boolean] ||
 || byte || sbyte || -N/A- || [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemSByteClassTopic.asp System.SByte] ||
 || short || short || Decimal|| [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemInt16ClassTopic.asp System.Int16] ||
 || int || int || Integer|| [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemInt32ClassTopic.asp System.Int32] ||
 || long || long || Long || [http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemInt64ClassTopic.asp System.Int64] ||
 || float || float || Single || [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemSingleClassTopic.asp System.Single] ||
 || double || double || Double || [http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemDoubleClassTopic.asp System.Double] ||
 || Calendar || Date''''''Time || Date''''''Time || [http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemDateTimeClassTopic.asp System.DateTime] * see note above||
 || String || string || String || [[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemStringClassTopic.asp|System.String]] ||
 || boolean|| bool || Boolean|| [[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemBooleanClassTopic.asp|System.Boolean]] ||
 || byte || sbyte || -N/A- || [[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemSByteClassTopic.asp|System.SByte]] ||
 || short || short || Decimal|| [[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemInt16ClassTopic.asp|System.Int16]] ||
 || int || int || Integer|| [[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemInt32ClassTopic.asp|System.Int32]] ||
 || long || long || Long || [[http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemInt64ClassTopic.asp|System.Int64]] ||
 || float || float || Single || [[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemSingleClassTopic.asp|System.Single]] ||
 || double || double || Double || [[http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemDoubleClassTopic.asp|System.Double]] ||
 || Calendar || Date''''''Time || Date''''''Time || [[http://msdn.microsoft.com/library/en-us/cpref/html/frlrfSystemDateTimeClassTopic.asp|System.DateTime]] * see note above||
Line 114: Line 114:
Otherwise you get a {{{MustUnderstand}}} fault when Axis fails to understand the WS-Routing headers. For more info, see [http://www.anecon.com/aktuelles/Java_and_dotNet_Interoperability_HowTo.pdf Java & .NET Interop - How To]. Otherwise you get a {{{MustUnderstand}}} fault when Axis fails to understand the WS-Routing headers. For more info, see [[http://www.anecon.com/aktuelles/Java_and_dotNet_Interoperability_HowTo.pdf|Java & .NET Interop - How To]].
Line 121: Line 121:
  Click on the following link for a discussion and potential work around to the issue: [http://marc.theaimsgroup.com/?l=axis-dev&m=106086909809576&w=2 archive]   Click on the following link for a discussion and potential work around to the issue: [[http://marc.theaimsgroup.com/?l=axis-dev&m=106086909809576&w=2|archive]]
Line 125: Line 125:
  [http://msdn.microsoft.com/netframework/archive/default.aspx?pull=/library/en-us/dnvs05/html/wsnetfx2.asp New Features for Web Service Developers in Beta 1 of the .NET Framework 2.0]   [[http://msdn.microsoft.com/netframework/archive/default.aspx?pull=/library/en-us/dnvs05/html/wsnetfx2.asp|New Features for Web Service Developers in Beta 1 of the .NET Framework 2.0]]
Line 153: Line 153:
  [http://support.microsoft.com/default.aspx?scid=kb;en-us;330065 archive]   [[http://support.microsoft.com/default.aspx?scid=kb;en-us;330065|archive]]
Line 169: Line 169:
A: Yes, be aware of [http://issues.apache.org/jira/browse/AXIS-1366 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). A: Yes, be aware of [[http://issues.apache.org/jira/browse/AXIS-1366|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).
Line 174: Line 174:
A: See [http://wiki.apache.org/ws/FrontPage/Axis/DotNetInteropMapInfo DotNetInteropMapInfo]. A: See [[http://wiki.apache.org/ws/FrontPage/Axis/DotNetInteropMapInfo|DotNetInteropMapInfo]].
Line 181: Line 181:
[http://www.perfectxml.com/DotNet11Changes.asp XML & Web Services Changes in .NET Framework 1.1] [[http://www.perfectxml.com/DotNet11Changes.asp|XML & Web Services Changes in .NET Framework 1.1]]
Line 183: Line 183:
[http://msdn.microsoft.com/webservices/default.aspx?pull=/library/en-us/dnwebsrv/html/syswebserchange.asp Changes in System.web.services from .NET Framework 1.0 to 1.1] [[http://msdn.microsoft.com/webservices/default.aspx?pull=/library/en-us/dnwebsrv/html/syswebserchange.asp|Changes in System.web.services from .NET Framework 1.0 to 1.1]]
Line 188: Line 188:
[http://msdn.microsoft.com/webservices/ MSDN Web Services Developer Center] [[http://msdn.microsoft.com/webservices/|MSDN Web Services Developer Center]]
Line 190: Line 190:
[http://www.west-wind.com/articles.asp West Wind Technologies White Papers] [[http://www.west-wind.com/articles.asp|West Wind Technologies White Papers]]

Interoperability Notes on Apache Axis 1.1 and Microsoft .NET Framework 1.0/1.1 FAQ


Data Types

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?

A: Yes.

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:

  1. 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?

A: Sure.

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.


Aproach

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


Other Features

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.


Examples

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.


Misc

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

    archive

    • 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:

XML & Web Services Changes in .NET Framework 1.1

Changes in System.web.services from .NET Framework 1.0 to 1.1


Resources

MSDN Web Services Developer Center

West Wind Technologies White Papers

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.

FrontPage/Axis/DotNetInterop (last edited 2009-09-20 22:49:10 by localhost)