Cloud Computing Conference
March 30 - April 1, New York
Register Today and SAVE !..


2008 East
DIAMOND SPONSOR:
Data Direct
Frontiers in Data Access: The Coming Wave in Data Services
PLATINUM SPONSORS:
Red Hat
The Opening of Virtualization
Intel
Virtualization – Path to Predictive Enterprise
Green Hills
IT Security in a Hostile World
JBoss / freedom oss
Practical SOA Approach
GOLD SPONSORS:
Software AG
The Art & Science of SOA: How Governance Enables Adoption
PlateSpin
Effective Planning for Virtual Infrastructure Growth
Fujitsu
Automated Business Process Discovery & Virtualization Service
Ceedo
Workspace Virtualization
Click For 2007 West
Event Webcasts

2008 East
PLATINUM SPONSORS:
Appcelerator
Think Fast: Accelerate AJAX Development with Appcelerator
GOLD SPONSORS:
DreamFace Interactive
The Ultimate Framework for Creating Personalized Web 2.0 Mashups
ICEsoft
AJAX and Social Computing for the Enterprise
Kaazing
Enterprise Comet: Real–Time, Real–Time, or Real–Time Web 2.0?
Nexaweb
Now Playing: Desktop Apps in the Browser!
Sun
jMaki as an AJAX Mashup Framework
POWER PANELS:
The Business Value
of RIAs
What Lies Beyond AJAX?
KEYNOTES:
Douglas Crockford
Can We Fix the Web?
Anthony Franco
2008: The Year of the RIA
Click For 2007 Event Webcasts
As you can imagine, I spend a lot of time speaking to people about service-oriented architecture (and its variants for infrastructure and enterprise) and about how best to create a true implementation (or at least, an effective one). There is a great deal of detail in creating such an artifact – d...
SYS-CON.TV
TODAY'S TOP SOA & WEBSERVICES LINKS


SOAP on a ROPE - Requested Objects Passed Elegantly
SOAP on a ROPE - Requested Objects Passed Elegantly

Converting a Web site to a Web service requires some new tools in your programming toolbox. For Web services that need to exchange arbitrary Java objects, you can add the tools described here. I'll show you how to exchange Java objects using SOAP RPC and invoke methods on these objects.

The source code for the examples as well as the listings discussed here can be downloaded from www.sys-con.com/webservices/sourcec.cfm. The example code consists of a client and a simple Web service (see Figure 1). The client is a Java application named Client. The Web service code is a Java class called ObjectDepot. ObjectDepot exposes two SOAP callable methods using a deployment descriptor named DeploymentDescriptor.xml. The method getMyObject() will return an instance of AClass. The method getObject (String name) returns an instance of a named class that is passed as a String parameter. BClass is used in the example. AClass and BClass are simple do-nothing classes I've used for demonstration purposes. The only restriction on the objects that you send and receive is that they must implement the Serializable Interface.

The client makes a SOAP method call that returns a Java Object. The dotted lines represent the marshall() and by ObjSerializer. unmarshall() method calls made I used the following tools in addition to the Java 2 Platform, Standard Edition (J2SE) to set up my development environment:

  • Apache SOAP 2.2:
If you are not familiar with Apache SOAP, there are several examples of using SOAP in the sample directory of the SOAP zip file. For this article, assume you have executed one of the SOAP Remote Procedure Call (RPC) sample programs.

A Little Background
Any type of data returned by invoking a SOAP RPC needs to be marshalled at the sender and unmarshalled at the receiver. Apache SOAP uses type mappings to determine how Java data types should be marshalled to XML so that the data can be transmitted on the network. The same is true when the data is received at a client.

Another type mapping is used to determine how the data should be unmarshalled. The type mappings are stored in a type-mapping registry. The default registry is org.apache. soap. encoding. SOAPMappingRegistry. Apache's SOAP implementation contains serializers and deserializers that will marshall and unmarshall many of the basic Java objects. Among the objects supported is the Java String Object, and there is even a Java Bean serializer and deserializer. After browsing the SOAP documentation, I wondered why any Java object couldn't be transmitted. This was in the Apache SOAP documentation:

"If you need to create a new serializer/ deserializer, then looking at the source code for the predefined ones will probably provide you with the best guidance. Remember that they will need to implement org.apache .soap. util.xml. Seri alizer and org.apa che.soap. util.xml. Deserializer respectively. You can implement them both in the same class or use two different classes. It really makes no difference."

There was my answer. I could write my own Java object serializ er/deserializer.

After digging a little further, I discovered that there are several technical hurdles to scale. First I needed to serialize the object. Then I'd need to fit the serialized object into the SOAP envelope. Once the object reached the client, it would need to be deserialized so that it could be used. The biggest hurdle was getting access to the class file on the client so that the object could be deserialized.

My Approach
I'm sure you're aware that developers don't usually write their final version of code on the first attempt. Instead of describing the final version of my code, I'm going to describe how I arrived at that point.

To get started, I needed a serializer and deserializer for my Java objects. My implementation of both is contained in Obj Serializer.java. Objserializer implements the Apache SOAP serializer and deserializer interfaces. I used Java's standard Object Input Stream and ObjectOutputStream to do most of the heavy lifting (see Listing 1).

I also used an Apache SOAP utility called Base64 to convert the binary object data to a base64 encoded String.

byte byteArray[] = ObjectToArray(value);
Base64.encode(byteArray, 0, byteArray.length, sink);

I did this to prevent any encoding that an application server might try to do.

Wire Tapping
Once I had the serializer working, I used another Apache SOAP utility called TcpTunnel Gui to see what was being sent over the wire. The TcpTunnelGui utility works as a relay between the client application and the Web server. The SOAP envelope sent by the client is displayed in one half of the window and the reply is displayed in the other half. Figure 2 shows a typical SOAP exchange. I could see that my serializer was working by looking at the reply envelope. I got several complaints from the Client code, but that was what I expected since I hadn't written any code to handle the returned data yet.

As mentioned earlier, I saw that the deserializer on the client machine had to have access to the object's class file for it to be deserialized for the client to use. When I began, the only way I could accomplish this was to copy the class file from the Web server to a file in the class path of the client just before the class file was needed for unmarshalling the data into the object. I added some code to the catch block in ObjSerializer that caught the ClassNotFoundException that was being thrown by the readObject() method of ObjectIn putStream (see Listing 2).

In the catch block I retrieved the class file from the Web server and then retried the unmarshalling. After the readObj ect() method returned the object, I removed the class file from the disk. I left my original unmarshall() method in ObjSerial izer.java for you. The unmarshalling worked and I could use the returned object, but I thought there must be a more elegant way. I posted a note on the Apache SOAP mailing list explaining what I was trying to do and someone suggested I look at class loaders. After a little reading I realized that URLClass Loader would do the job and I only needed to override the findClass() method in URLClassLoader.

A Class Loader Mini-Course
The entire subject of class loaders is beyond the scope of this article. You need, however, to know about the delegation model to understand how my code works. A class loader has a parent class loader. The set of a class loader and its ancestors is called a delegation. Standard Java applications begin with a delegation of three class loaders. The system class loader loads classes from the class path, delegates to the extension class loader, and is used to load Java extensions. The parent of the extension class loader is the bootstrap class loader. The bootstrap class loader loads the core API.

When MyURLClassLoader is added to the delegation, the system class loader becomes its parent. When a class loader loads a class, it consults its parent first to give the parent a chance to load the class file. Whenever a class refers to another class, the same class loader that loaded the referencing class loads the referent. In other words, since ObjSerializer is loaded by MyURLClassLoader, MyURLClass Loader will be used to load classes needed by ObjSerializer. That is done when the system class loader calls the findClass() method of MyURLClassLoader after failing to find a class file when the readObject() method is called from ObjSerializer's unmarshall() method (see Figure 3). The findClass() method needs to know the host name of the Web server and where the class files are located on the server. These are read from ObjSerial izer.properties when MyUrlClassLoa der is instantiated. The unmarshall() method calls the readObject() method of Object Input Stream. Which then calls the find Class() method of MyURLClass Loader. The findClass() method retrieves the class file from the remote web server. The readObject() method returns the object to the unmarshall() method. The unmarshall() method returns the object in a SOAP Bean.

Here are the contents of my ObjSerializer. properties file:

ClassDefHost=localhost
ClassDefPort=8080
ClassDefDirectory=/objser

Listing 3 from MyURLClass Loader builds the URL for the class file when it's needed (the class file we need is called name). I stored AClass. class and BClass. class in a directory named objser under Tomcat's webapps directory.

As I explained earlier, I would need a Class that would load ObjSerializer using the Class.forName() method. That way I could pass an instance of MyURLClass Loader to be used to load ObjSerializer. This project was getting a little complicated, but I was almost home. I created ObjSerializerLoader.java to do the job (see Listing 4). Okay, now I was ready. I had my SOAP deployment descriptor set up to register ObjSerializerLoader as my serializer and deerializer on the SOAP server. I also registered ObjSerializer Loader in Client for the same purpose. I started up Tomcat, ran Client which invoked ObjDepot's getMyObject() method through SOAP RPC.

I was upset to see a ClassNotFound Exception, just as I had seen before. It looked like MyURLClass Loader wasn't being used at all. After a few System. out.println() statements, I discovered I was right. MyURLClassLoa der wasn't being used. As it turned out, I had made only one mistake. When I used the Class.f or Name() method to create my instance of ObjSerializer, I assigned it to a variable of type ObjSerializer. Since the system class loader could find the class file for ObjSerializer, the system class loader was used to create the object and not my class loader. What I needed to do was put ObjSerializer into a variable of type Object and use Java Reflection to invoke the marshal() and unmarshall() methods (see Listing 5).

That way there would be no reference to ObjSerializer in ObjSerializerLoader, so my code would compile without ObjSe rializer in the class path and the system class loader would delegate to MyURL ClassLoader's find Class() method when ObjectSerializer is unmarshalling the returned data. As I mentioned earlier, the delegation takes place when the read Object() method is called in the unmar shall() method of ObjSerializer (see Listing 6).

If you're like me, you've spent some time figuring out class path problems when some class file couldn't be found. In this case, I didn't want ObjSerializer to be found by the system class loader.

Try, Try Again
After a few modifications, I was ready to go again. When I tried the client this time, it worked. I had sent a Java object across the network using SOAP RPC and executed that object on the client machine by using Java Reflection to invoke the main() method of the returned object. This was done without having any reference to the class file on the client machine. Life was good.

A word about security: as powerful as this tool can be, it can also be dangerous. This tool should only be used among trusted Web sites. You should also consider encryption, based on the sensitivity of the data transmitted.

Running the Example Code
Here is what you will need to do to run the example code.

  • On the client workstation, create a directory called Client.
  • Extract Client.java, ObjSerializer.java, Obj SerializerLoader.java, MyURLClass Load er.java, Deployment Desciptor xml, Obj ectSerializer.properties, and wssetup.bat into the client directory.
  • On the Web service workstation, which can be the same as the client workstation, create a directory called "objde pot". Extract IObjDepot.java, ObjDepot. java, Aclass.java, Bclass.java, MyURLCl assLoader.java, and wssetup.bat into the obj depot directory.
  • Edit wssetup.bat and change the line that modifies the classpath to point to the location of your various toolkit .jar files. You'll notice a remark at the top. You can cut and paste this line to your command line. When executed, this will add ObjDepot to the Apache SOAP deployed services. You can access the Apache SOAP Admin Web page at: http://localhost:8080/soap/admin/index.html. That way you can see that the Web service is properly deployed.
Removing from the Depository There is also a remarked-out line at the bottom of the batch file that can be used to remove ObjDepot from the Apache SOAP depository.
  • From a command window, change to the client directory and execute wssetup.bat. Compile the Java files in the client directory. Now go to the objdepot directory and compile the Java files there.
  • Create a directory called "objser" under Tomcat's webapps directory.
  • Move (not copy) ObjSerializer.class, ACla ss.class, and BClass.class to the objser directory.
  • Modify your tomcat.bat file to include the objdepot directory in the classpath.
  • Start Tomcat.
  • From the client directory, run Client.
You should see indications that AClass was received and BClass executed.

Create Your Own
If you download the code, read the comments, and refer back to this article, you should be able to figure out how to use SOAP to transfer Java objects from your Web service and use them on a client.

YOUR FEEDBACK
Scott wrote: All of the articles about Web Services seem to be introductory level stuff or they seem to be only about Java to Java web services. Doing Java to Java SOAP and passing objects is easy. Why doesn't anyone want to talk about the real benefit of web services--talking amongst heterogeneous application architectures like VB clients and Java back ends? This is the stuff you're most likely going to find in many corporate environments. So, enough with the "What is Web Services?" stuff and "Hey, here's YET ANOTHER Java-to-Java example!"--let's see some meaningful treatment of this topic!!! Do something really useful with a VB client talking SOAP to a Java web service and passing some meaningful object payloads around!!!
SOA WORLD LATEST STORIES
If you've been following me on Twitter, or through my other blogs, you already know that I made it to the SOA World Conference & Expo in San Jose, CA, which was collocated with Cloud Computing Conference & Expo. I did the keynote on Wednesday and then stayed around for some of the sess...
A few years ago, a British newspaper speculated on what might be the Web equivalent of the Seven Wonders of the World, and received suggestions that were hardly surprising: Google search, the Amazon.com e-tail portal, the eBay auction mechanism, etc. But that was back in 1991, before F...
Active Endpoints has announced the general availability of ActiveVOS 6.0.2, in response to ever increasing demands for improved process performance and efficiencies. ActiveVOS is an all-in-one, 100% standards-based orchestration and business process management system (BPM) that permits...
"This is the premier social graph fully integrating with the premier enterprise cloud computing company - this is the true power of Internet," gushed Marc Benioff, Chairman and CEO of Salesforce.com, as he today launched a new offering called Force.com for Facebook – designed to fost...
How does SOA work, how can it be used? And what is WOA? With the use of a real-world example,this article describes why a properly planned and implemented Service Oriented Architecture can create a flexible way of aligning business and IT.
In his virtualization session on Nov. 21 at the 4th International Virtualization Conference & Expo in San Jose, CA, Roland Wartenberg, SAP's director of virtualization strategy, discussed the supported virtualization solutions provided by partners of SAP's virtualization ecosystem. Sim...
SUBSCRIBE TO THE WORLD'S MOST POWERFUL NEWSLETTERS
SUBSCRIBE TO OUR RSS FEEDS & GET YOUR SYS-CON NEWS LIVE!
Click to Add our RSS Feeds to the Service of Your Choice:
Google Reader or Homepage Add to My Yahoo! Subscribe with Bloglines Subscribe in NewsGator Online
myFeedster Add to My AOL Subscribe in Rojo Add 'Hugg' to Newsburst from CNET News.com Kinja Digest View Additional SYS-CON Feeds
Publish Your Article! Please send it to editorial(at)sys-con.com!

Advertise on this site! Contact advertising(at)sys-con.com! 201 802-3021


SYS-CON FEATURED WHITEPAPERS


ADS BY GOOGLE