A helpful guide for non-1337 parents from Microsoft

Here: http://www.microsoft.com/athome/security/children/kidtalk.mspx  Hopefully following articles in the same area will cover: How to convince your child that smashing the stack for fun and profit is just WRONG WRONG WRONG.Why SQL Injection attacks are so, like, 1990’s.How to convince your teen that root-kits might not be the right kind of exploit for them.   »

Service contracts and Isomorphism

I’ve been thinking about service contracts a little more in light of recent discussion over what (in the brave new indigo world) will define a service contract. It occurred to me that a contract based on the CLR type system will never be isomorphic with one defined in terms of an XML schema because the two type systems are not equivalent. See: http://weblogs.asp.net/dareobasanjo/archive/2004/02/20/77264.aspx »

SQL Server downunder

It has only been a week or so since SQL Server & ADO.NET supremo Greg Low joined the Readify team, but he’s already making an impact by starting up a SQL Server email list similar to the ausdotnet mailing list run by Dr. Peter Stanski. From the Readify site: Readify have now created SQLDownUnder - a discussion and knowledge-transfer forum for Aussie & Kiwi SQL Server professionals. To subscribe to SQLDownUnder, send an email with “subscribe” in the subject line to sqldownunder@listserver. »

Headfirst communication

I’ve been impressed by the style and expressiveness of the parts that I’ve seen from the “head first” serise of books, also I find the head first weblog quite entertaining. With this in mind I’m going to try a few “headfirst” type designs in some of my upcoming weblog articles. Let me know how it goes. »

Web Service Interoperability Resources

In my recent experimenting with Axis Web Services I found the following useful resources on Web Service interoperability between .NET and Java.http://wiki.apache.org/ws/FrontPage/Axis/DotNetInterophttp://weblogs.asp.net/smguest/articles/TopTenWSITips.aspxhttp://www-128.ibm.com/developerworks/webservices/library/ws-tip-j2eenet2.html Update: Simon Guest has a serise of webcasts from the recent “interoperability month” conducted by MSDN, including two on .NET and Apache Axis 1.2. This one uses a .NET client and Axis service (at a high level this is similar to my recent discussion of Axis JWS, but Simon apparently discusses the more “fully featured” WSDD approach). »

Newsflash: Source Code Control Systems will KEEP TRACK OF YOUR CODE CHANGES

As Eric Kepes points out here http://dotnetjunkies.com/WebLog/ekepes/archive/2005/02/18/55346.aspx This means there is absolutely NO need whatsoever to check in code with large blocks of code commented out. I think “change-log” style comments that appear at the top of code files are also un-necessary for this reason. Tracking who changed what and when is the job of source code control systems, not crufty code-comments. »

Interoperability between .NET and Java via Web Services – Apache Axis JWS

Pre-requisites: <?xml:namespace prefix = o ns = “urn:schemas-microsoft-com:office:office” />/o:p

JDK 1.4+/o:p

Web Server (Apache Tomcat in this case)/o:p

Apache Axis 1.2 http://ws.apache.org/axis/ /o:p

.NET Framework 1.1/o:p

 /o:p

Apache Axis is a Web Services library available in Java and C++, developed as an open-source project under the auspices of the Apache foundation. Although there are some related Apache projects implementing WS-* specifications I’m just looking at Axis basics (if and when .NET developers need to talk to Java Web Service developers) and also inter-op between the two Web Service stacks. /o:p

/o:p 

[Disclaimer: I’m not a java guy. I’m not a Web Services expert. I’m just trying to document what I’ve found. If you think something I’ve written here is incorrect please leave a comment or send me an email and I’ll investigate & update this.]/o:p

 /o:p

Installation/o:p

The Axis installation instructions do a good job of explaining how to set up Axis, and the happiness page http://localhost:8080/axis/happyaxis.jsp gives you pretty good feedback as to what is missing in your Axis install. I’ve used Axis RC2 for the purposes of this investigation, and will try and update when the final version is released./o:p

 /o:p

Two Flavors of Web Services/o:p

 /o:p

Apache Axis supports two different flavors of Web Services – JWS, and “custom” deployment with deployment descriptors (an XML config file, what else) used throughout the J2EE world for configuring deployable units./o:p

 /o:p

JWS – The simplest thing that could possibly work/o:p

 /o:p

Once your Axis environment is set up, JWS is about as simple as Web Services could get. You re-name a Java class file to .jws, copy it into your Axis directory and when a request is made an end-point is compiled on the fly, exposing all the public methods of the class as port types (as if you’d decorated every public method of a class with the [WebMethod] attribute in ASP.NET Web Services). I’m sure the “schema first” people in the Java world like this kind of Web Service development about as much as they like having pointy things thrust into there eye./o:p

 /o:p

The StockQuote JWS example file that ships with Axis has the following Java code:/o:p

 /o:p

public class StockQuoteService {/o:p

  public float getQuote (String symbol) throws Exception {/o:p

     // code omitted for brevity/o:p

  }/o:p

}/o:p

 /o:p

Which gets exposed something like this:/o:p

 /o:p

<?<xml version=1.0 encoding=UTF-8?>/o:p

<wsdl:definitions targetNamespace=http://localhost:8181/axis/StockQuoteService.jws xmlns:apachesoap=http://xml.apache.org/xml-soap xmlns:impl=http://localhost:8181/axis/StockQuoteService.jws xmlns:intf=http://localhost:8181/axis/StockQuoteService.jws xmlns:soapenc=http://schemas.xmlsoap.org/soap/encoding/ xmlns:wsdl=http://schemas.xmlsoap.org/wsdl/ xmlns:wsdlsoap=http://schemas.xmlsoap.org/wsdl/soap/ xmlns:xsd=http://www.w3.org/2001/XMLSchema>/o:p

    /o:p

    <wsdl:message name=getQuoteRequest>/o:p

        <wsdl:part name=symbol type=xsd:string/>/o:p

    </</< SPAN></< SPAN>wsdl:message>/o:p

    <wsdl:message name=getQuoteResponse>/o:p

        <wsdl:part name=getQuoteReturn type=xsd:float/>/o:p

    </</< SPAN></< SPAN>wsdl:message>/o:p

    <wsdl:portType name=StockQuoteService>/o:p

        <wsdl:operation name=getQuote parameterOrder=symbol>/o:p

            <wsdl:input message=impl:getQuoteRequest name=getQuoteRequest/>/o:p

            <wsdl:output message=impl:getQuoteResponse name=getQuoteResponse/>/o:p

        </</< SPAN></< SPAN>wsdl:operation>/o:p

    </</< SPAN></< SPAN>wsdl:portType>/o:p

    <wsdl:binding name=StockQuoteServiceSoapBinding type=impl:StockQuoteService>/o:p

        <wsdlsoap:binding style=rpc transport=http://schemas.xmlsoap.org/soap/http/>/o:p

        <wsdl:operation name=getQuote>/o:p

            <wsdlsoap:operation soapAction=””/>/o:p

            <wsdl:input name=getQuoteRequest>/o:p

                <wsdlsoap:body encodingStyle=http://schemas.xmlsoap.org/soap/encoding/ namespace=http://DefaultNamespace use=encoded/>/o:p

            <</< SPAN>wsdl:input>/o:p

            <wsdl:output name=getQuoteResponse>/o:p

                <wsdlsoap:body encodingStyle=http://schemas.xmlsoap.org/soap/encoding/ namespace=http://localhost:8181/axis/StockQuoteService.jws use=encoded/>/o:p

            </</< SPAN></< SPAN>wsdl:output>/o:p

        </</< SPAN></< SPAN>wsdl:operation>/o:p

    </</< SPAN></< SPAN>wsdl:binding>/o:p

    <wsdl:service name=StockQuoteServiceService>/o:p

        <wsdl:port binding=impl:StockQuoteServiceSoapBinding name=StockQuoteService>/o:p

            <wsdlsoap:address location=http://localhost:8181/axis/StockQuoteService.jws/>/o:p

        </</< SPAN></< SPAN>wsdl:port>/o:p

    </</< SPAN></< SPAN>wsdl:service>/o:p

</< SPAN></< FONT></wsdl:definitions>/o:p

 /o:p

/o:p

/o:p

This is a little different to the sort of schema you would see if the [WebMethod] attribute was added to an equivalent .NET method. In particular the <?xml:namespace prefix = wsdl />wsdl:typeselement (shown below from an equivalent .NET service) is not present in the Axis JWS WSDL. /o:p

<wsdl:types>/o:p

    <s:schema elementFormDefault=qualified targetNamespace=http://tempuri.org/>/o:p

      <s:element name=GetQuote>/o:p

        <s:complexType>/o:p

          <s:sequence>/o:p

            <s:element minOccurs=0 maxOccurs=1 name=symbol type=s:string />/o:p

          </</< SPAN></< SPAN>s:sequence>/o:p

        </</< SPAN></< SPAN>s:complexType>/o:p

      </</< SPAN></< SPAN>s:element>/o:p

      <s:element name=GetQuoteResponse>/o:p

        <s:complexType>/o:p

          <s:sequence>/o:p

            <s:element minOccurs=1 maxOccurs=1 name=GetQuoteResult type=s:float />/o:p

          </</< SPAN></< SPAN>s:sequence>/o:p

        </</< SPAN></< SPAN>s:complexType>/o:p

      </</< SPAN></< SPAN>s:element>/o:p

    </</< SPAN></< SPAN>s:schema>/o:p

  </</< SPAN></< SPAN>wsdl:types>/o:p

 /o:p

By default .NET services are document-style services which “wrap” simple schema types in complex types for each message. The Axis service is an RPC-style service. In .NET we could create an equivalent RPC-style service by applying the [SoapRpcMethod] attribute to a single method, or the [SoapRpcService] to our entire service. At this time there doesn’t seem to be any way of configuring Axis JWS services to be anything other than RPC-literal (there is an open enhancement here http://issues.apache.org/jira/browse/AXIS-1393 to make this configurable). While the WS-I does permit both document and RPC style services as part of the basic profile, document is considered a more explicit super-set of RPC./o:p

/o:p

/o:p/o:p

 /o:p

In order to test this very simple service I created a C# windows forms project and added a webreference. 2 lines of code later I was pulling stock quotes back from my .jws Axis Web Service without any problems (and people say this whole “integration” thing is hard)./o:p

 /o:p

When the endpoint is first requested Axis generates a .java file in the %AXISROOT%WEB-INF/jwsClasses directory on the fly which it then complies./o:p

 /o:p

Returning Complex Types/o:p

 /o:p

Impressed with my progress I tried to write my own JWS to return a complex type Customer. I attempted to do this using the following Java code:/o:p

 /o:p

public class CustomerInfoService {/o:p

  public Customer getCustomer (int id) throws Exception {/o:p

    Customer cust = new Customer();/o:p

    cust.name = “Test Customer”;/o:p

    cust.id = id;/o:p

    return cust;/o:p

  } /o:p

}/o:p

 /o:p

class Customer/o:p

{/o:p

      public String name;/o:p

      public int id;/o:p

}/o:p

 /o:p

I was able to call the getCustomer method using the following console application in the same package/o:p

 /o:p

public class Caller{/o:p

  public static void main(String[] args){/o:p

      CustomerInfoService svc = new CustomerInfoService();/o:p

      try{/o:p

            System.out.println(svc.getCustomer(1).name);/o:p

      }/o:p

      catch (Exception ex){/o:p

            System.out.println(“caught” + ex.getMessage());/o:p

      }/o:p

  }/o:p

}/o:p

 /o:p

However when I attempted to create this as an Axis JWS Web Service I got the following error: /o:p

 /o:p

Exception - java.lang.NoClassDefFoundError: Customer

 /o:p

Creating the Customer type as an inner class to CustomerInfoService, and qualifying the return type didn’t work either (it did work from the console application). /o:p

 /o:p

Exception - java.lang.NoClassDefFoundError: CustomerInfoService$Customer

 /o:p

Strangely enough, Java .class files WERE being created for these types in the jwsClass directory (where Axis does its code generation and compilation for JWS to work). Hmm….There’s something funny going on here./o:p

 /o:p

A Serialization Problem? Web Services? Well, knock me over with a feather!/o:p

A possible explanation for the problems serializing complex types using Axis-JWS is that JWS can’t serialize/de-serialize the complex type Customer that I’m trying to return. Although the Axis docs don’t go into specifics about complex type serialization in JWS, the descriptor-based method of deployment does discuss serialization. In descriptor-based Axis Web Services you gain a great deal more control about how your endpoint is exposed, as well as how types are serialized. The BeanSerializer will handler bean-style classes with getProperty and setProperty methods, but you do have to hook this up in your descriptor, so I think it’s fair to say that in JWS Axis Web Services this is (probably) not enabled by default. Although not explicitly stated in the documentation some discussions from the Axis mailing list back this up./o:p

 /o:p

http://marc.theaimsgroup.com/?l=axis-user&m=101907793104693&w=2 /o:p

http://marc.theaimsgroup.com/?l=axis-user&m=107037683118922&w=2 /o:p

 /o:p

My good friend Java Pete thought there were some possible ways to work around these issues by registering a global serialization handler (and that just MIGHT work), however this (if it did work) was more of a dirty hack than a viable solution./o:p

/o:p 

An exceptional JWS Service/o:p

Since returning complex types appeared to be something of a dead-end, I started looking at some other interoperability considerations. I created the following service to test the exception propagation facilities between the Axis Web Service and .NET/o:p

 /o:p

public class ExceptionalService{/o:p

      public void RaiseException() throws Exception{/o:p

            throw new Exception();/o:p

      }     /o:p

} /o:p

 /o:p

Here we can see a java exception being propagated as the message of the SystemException inside the SoapException that we get on the .NET client end./o:p

/o:p 

<?xml:namespace prefix = v ns = “urn:schemas-microsoft-com:vml” />/v:stroke/v:f/v:f/v:f/v:f/v:f/v:f/v:f/v:f/v:f/v:f/v:f/v:f/v:formulas/v:path/o:lock/v:shapetype/o:p

 /o:p

We can specify a message when we create the java.lang.Exception and this is translated across to our .NET client code./o:p

 /o:p

throw new Exception(“something went wrong”);/o:p

 /o:p

  /o:p

 /o:p

This is a good example of how implementation details from the service can “leak out”, so best not to take too much notice of the java.lang.Exception stuff./o:p

 /o:p

Where are we?/o:p

We’ve seen that creating Apache Axis JWS Web Services fairly easily, but that returning anything complex or shaping the WSDL in any way seems hard to impossible. Consuming said services from .NET is extremely straightforward (by creating a proxy class via “add web reference” in VS.NET or WSDL.exe in the framework SDK), and since only simple types can be returned there is a high chance that .NET will be able to interoperate with an Axis JWS Web Service./o:p

 /o:p

Thanks to Java Pete for his help preparing this article.

 

Note: After several edits parts of this post some parts of the XML formatting are getting screwed up. Appologies if some of the fragments are not valid. Also note that BEA has a Web Service technology also called JWS which is quite different to Apache Axis JWS.

/wsdl:types

Comments

john apps
Great article!
Would you post the .NET source, please? Or send it to me at john DOT apps AT hp DOT com

Thank you!
22/03/2006 3:54:00 AM

»

What defines a Service Contract

The public re-unveiling of Indigo at VSLive last week has ignited some “lively discussion” in .NET circles about what defines a service contract. As Don Box says here in Indigo you can expose a service contract as either WSDL or annotated CLR interfaces, but neither is the “real” service contract. Clemens (ever ready to inflame discussion and drive hits to his weblog) said that in this brave new ultra-violet world staring at angle-brackets was now deprecated, which was like calling their kids ugly to Tim Ewald and Aaron Skonnard. »

Patterns of Enterprise Application Architecture

I finished reading Martin Fowler’s Patterns of Enterprise Application Architecture some time ago, and have been meaning to do a short review. I found the book quite enjoyable to read. In many cases the patterns presented just gave a name to a familliar face (which is almost what you would expect from a patterns book) but typically the analysis also added something “extra“ to my previous understanding of a particular pattern. Probably the highest compliment I can give the book is that it made me want to re-read several others I have read recently - Eric Evans’ Domain Driven Design (which I quite liked) and Jim Newkirk’s Test Driven Development in Microsoft . »