views:

1592

answers:

4

I am creating a WCF Service that will be consumed by both .NET and Java client applications.

We do not have any Java experience in the team, so are looking for guidelines or rules to follow to ensure that we do not accidentally include any types in our WCF Service interface or do anything else that would preclude it from being consumed by a Java client application.

Are our worries well-founded? If so, what should we be wary of?

Edit

One example of a concern is whether a .NET DateTime value is represented in the service interface in a manner that can be correctly understood by a Java client.

Edit2

A second example of a concern is the use of any nullable value types (bool?, int? etc).

Edit3

At present some of our development teams are hand-writing .xsd files to define the various objects that the WCF interface methods will take as arguments and return as return values. They are then using xsd.exe to auto-generate C# classes from these.

The rationale behind this is that it guarantees that the generated classes won't contain anything that is .NET-specific.

The downside is that this adds a development burden and also precludes us from documenting these classes using <summary> tags (.NET equivalent of javadoc comments).

A: 

Does WCF provide standard SOAP interfaces? If it does, getting Java to talk to it should be a doddle.

Re: Edit1: The WSDL / XSD will use a standard date time format (Calendar at the Java end, a formatted datetime string in the SOAP, DateTime in .NET), or you could force it into a string format of your own choosing.

Read up on the Apache Axis (1.4 and 2.0) documentation for Java web services. It's very easy to use to get a Java web service client set up from the wsdl/xsd that your web service will provide.

Edit3: In Java you would define a Java model (with all your favoured documentation), then run Java2WSDL (preferably as an ANT/Maven task) to create your WSDL (however I have found you need to hand-reorder the fields in it). Axis 2 supports Collections and Enums just fine, Axis 1.4 likes Arrays and hand-rolled Java 1.4 style enumerations. From this WSDL you would create a server-side skeleton using WSDL2Java in which the only thing you need to do is implement your business logic.

JeeBee
+2  A: 

Using basicHttpBinding endpoint will guarantee that any SOAP 1.1 compatible client will be able to consume your service.

Darin Dimitrov
Isn't it up to the client to decide what binding to use?
Richard Ev
No, it is the server that decides what protocol, binding to use. The client must comply.
Darin Dimitrov
Checkout this article: http://romenlaw.blogspot.com/2008/07/consuming-wcf-web-service-using-java.html
Darin Dimitrov
+1  A: 

Use DateTime?, i.e. a nullable struct. Java does not have the notional of complex value types (i.e. structs). I believe there are ways to specify in the WSDL not to allow nulls, but I think WCF doesn't do it out of the box.

Use arrays instead of collections. If I recall correctly, the collection types do not translate very well over SOAP, but array types do quite well.

You should get a copy of Eclispe or Netbeans. After you create a prototype WCF service, run the web service wizard to create your proxies. Examine the object model for any major defects with particular emphasis on complex objects or non-primitive types (treat string as a primitive).

The learning curve to do that with Netbeans or Eclipse is pretty flat, so it's not a huge burden.

Edit: The other potential problems are with the bindings. If you stick with HTTP(S), you should be good... start going to the alternatives like TCP or MSMQ, you'll have to do a lot of work in Java. Also, some of the security features don't interop in all cases, such as using NTLM tokens... Take an iterative approach. Start with a simple HTTP w/SOAP binding with no security and go from there.

James Schek
Thanks for the pointer James - I am still hoping for a non trial-and-error approach for this though
Richard Ev
You are a lot braver than I am.
James Schek
Don't know about brave...I just want to _know_ what's allowed and what's not. :-)
Richard Ev
+6  A: 

The recommendation to start with XSD is a good one. That will not guarantee compatibility on each side, as XML Schema is really big and no web services stack supports all of it. (Example: lists).

So, start with XSD, but confine yourself to mainstream types. Primitives, complextypes composed of primitives, arrays of same. You can safely nest complextypes and arrays. (arrays of complextypes, complextypes that contain arrays or complextypes, etc).

Stay away from restrictions, substitution groups, lists, derivations, and any other XSD esoterica. Even XSD enumerations should be avoided.

About dateTime: It's not enough to use a nullable datetime. There are formatting concerns as well. The .NET DateTime is a higher resolution quantity than a Java Calendar and as a result, shipping a .NET time to Java can result in de-serialization exceptions on the Java side. (EDIT: using the DataType="dateTime" decorator in the XmlElement attribute on the .NET side can make sure you serialize properly)

Some old advice on that.

Finally, it is not true that you cannot use in-code XML doc on the classes that get generated. With C#'s partial classes, you can write separate code from the generated classes with the in-code doc you want. Even if you re-gen the code, your partial class code will remain unchanged. EDIT: When you compile, the doc will appear on the classes.

EDIT: Someone asked, if using XSD-first is not enough to guarantee interop, why use it? My answer: it is not a guarantee but it is a good step, it helps. It keeps you away from designing interfaces in code (either Java or C# or VB, etc) that expose platform-specific things like .NET DataSets, generic Dictionaries, Java ResultSets, etc, all of which present interop problems. There are still pitfalls in the more marginal parts of XSD, but you can usually avoid those with thoughtful design.

I should have mentioned in my original answer that you can apply an iterative process to the development of the interface. Design in XSD, then generate (client) stub and (server) skeleton code from the XSD+WSDL, then adjust and do it again.

Cheeso