Distributed Object Programming with XML and Java CC432 / Short Course 509 Applied XML Lecturer:...
-
date post
21-Dec-2015 -
Category
Documents
-
view
222 -
download
3
Transcript of Distributed Object Programming with XML and Java CC432 / Short Course 509 Applied XML Lecturer:...
Distributed Object Programmingwith XML and Java
CC432 / Short Course 509
Applied XML
Lecturer: Simon Lucas
University of Essex
Spring 2002
Outline
• Web Services
• Distributed Object Programming
• Java RMI
• XML-RPC
• SOAP-RPC
Web Services
Client Application Service Implementation
Web Service
Language Neutral Messages
Language Specific Messages
Web Service Components
Service Implementation
Web Application Server (e.g. Tomcat)
Client Service Listener
Service Proxy
Web Service Stack
Discovery (UDDI)
Network (TCP/IP)
Transport (HTTP)
Packaging (SOAP)
Description (WSDL)
Web Services and DOP
• If both clients and services are implemented in OO languages
• Then we can view a web service system as a form of distributed object programming (DOP)
• Therefore: instructive to consider other (less general) ways of doing this
Why is DOP Difficult?
• Aim: invoke a method call on a remote object
• Easy if: parameters and return values are all primitive types
• What if they are Objects?– Of standard classes– Of user-defined classes
Java RMI
• We’ll begin by looking at Java RMI• This allows easy distributed object
programming• BUT: restricted to the Java language• Almost transparent:
– declare things to be remote or serializable– then just call methods on remote objects
just as you would on local objects
Remote Objects
• Suppose we have a Rectangle class:– class Rectangle { double w; double h; }
• Suppose we have the following method in class Geometry to be exposed service:– public double area(Rectangle r) { return r.w * r.h; }
Rectangle Reference
• There are two distinct ways in which the remote service can access the w and h values
• Either the client sends it a serialized version of the Rectangle
• OR – the client sends it a remote reference to the Rectangle
• In other words, pass by value, or pass by reference
Parameter Marshalling / Unmarshalling
• Marshalling is the process of the caller packaging up the parameters prior to the remote method call
• Unmarshalling is when the server unpacks them at the other end
• Before then passing them on to the remote object (i.e. the object at the server)
Hello World in RMI
• For comparison with SOAP later, let’s look at a hello world service, and how to implement and deploy it using RMI
• We need to:– Define the service interface– Provide a Remote-enabled implementation– Register an implementation object– Access it with a client
• The client gets a remote reference to the object implementation
• Then makes calls on it, just like a local object
Hello Interface
package examples.rmi;
import java.rmi.*;
public interface HelloInterface extends Remote { public String getResponse(String request)
throws RemoteException;
}
Hello Implementation
package examples.rmi;import java.rmi.*;import java.rmi.server.UnicastRemoteObject;
public class HelloServer extends UnicastRemoteObject implements HelloInterface { public String getResponse(String request) throws RemoteException { return "Hello from " + name; }}
Registering the Service
package examples.rmi;import java.rmi.Naming;public class RegisterHelloServer { public static void main(String[] args) throws Exception { HelloServer hob = new HelloServer(); Naming.rebind("HelloServer2", hob); System.out.println( "HelloServer bound in registry"); }}
Hello Client
package examples.rmi;
import java.rmi.Naming;
public class HelloClient {
public static void main (String[] args)
throws Exception
{
HelloInterface obj = (HelloInterface)
Naming.lookup(
"//ace.essex.ac.uk/HelloServer2");
System.out.println(obj.getResponse( "From Me" ));
}
}
Serialized v. Remote Ref
• Discussion Question:– Suppose you must decide whether to send
a serialized copy of an object, or a remote reference to the object
– What do you think are the criteria for deciding which option is best?
XML-RPC
A simple protocol for making language neutral remote
procedure calls
XML-RPC• Easy way to make RPCs over the web
• Typically done over HTTP
• XML-based so language neutral
• Offers a fixed set of datatypes– Primitives (int, boolean etc, all the usual)– Strings– Arrays of primitives or Strings (uniform)– Structs of primitives or Strings (mixed)
XML-RPC Parameters
• Method parameters are passed by value• So: what happens if the parameters are
objects?• XML-RPC only supports a fixed set of data
types• So: you must make your code fit in with these• Could be very HARD WORK for comp[lex
objects• But very easy to use for simple examples
Apache XML-RPC Client
XmlRpcClient xmlrpc =
new XmlRpcClient
("http://localhost:8080/RPC2");
Vector params = new Vector ();
params.addElement ("some parameter");
// this method returns a string
String result = (String)
xmlrpc.execute ("method.name", params);
Client Request Header
POST / HTTP/1.0
User-Agent: Apache XML-RPC 1.0
Host: localhost:5050
Content-Type: text/xml
Content-Length: 192
Client Request Body<?xml version="1.0" encoding="ISO-8859-1"?><methodCall> <methodName>echo</methodName> <params> <param> <value>test</value> </param> <param> <value> <int>123</int> </value> </param> </params></methodCall>
Server Response HeaderHTTP/1.0 200 OK
Server: Helma XML-RPC 1.0
Connection: close
Content-Type: text/xml
Content-Length: 199
Server Response Body<?xml version="1.0" encoding="ISO-8859-1"?><methodResponse> <params> <param> <value> <array> <data> <value>test</value> <value><int>123</int></value> </data> </array> </value> </param> </params></methodResponse>
SOAP
Simple Object Access Protocol
SOAP Basics
• Parameters passed by value• Can be of any type• Selectable Object Encoding
– Can use a SOAP standard encoding– Or ANY user defined one
• In which case client and service MUST agree!
• Often layered over HTTP POST requests• BUT is actually protocol neutral – can work
over email as well, or any other transport
SOAP-RPC Request
• Parameters passed by value
• SOAP-RPC Request envelope– Defines the Object URN– The method name– The method parameters
SOAP-RPC Response
• Returns a response value or a fault
• Again – object encoding is user-defined
• See example below
Deploying SOAP Services
• Apache-SOAP offers two methods– Fill in a form using a web-browser– POST an XML DeploymentDescriptor to
the SOAP RPC Router
• The latter method is generally preferred– can be executed from a program– hence less effort
SOAP-RPCs from Java
• The following example uses Apache SOAP 2.0
• Make a remote method call – hello world example
• This example was adapted from the SOAP articles by Tarak Modi:
• http://www.javaworld.com/javaworld/jw-03-2001/jw-0330-soap.html
Making a SOAP-RPC
A standard SOAP-RPC involves:• Create a call Object• Set up the URI encoding style• Set the URN of the object (TargetObject URN)• Set the method name• Set up a Vector of parameters (each one of
type Parameter)• Set the call parameters to be this vector of
parameters
Making a SOAP-RPC contd
• Set up a URL for the call• Make the method invocation:
– Response r = call.invoke()
• From the response, we detect whether the call was successful, or if some error has occurred
• If successful, we extract the Parameter from the call, and retrieve the object from the parameter
Hello SOAP World
• Define this interface for Hello Service• Not necessary – but useful to decouple
the service description from the implementation
• Essential for Dynamic Proxy – see later
package hello;
public interface Hello {
public String sayHelloTo(String name)
}
Implementing the Service• In this case, the service is very simple:
package hello; public class HelloImpl { // just to notify when tomcat loads the class static { System.out.println("Loaded HelloImpl.class"); } public String sayHelloTo(String name) { System.out.println("sayHelloTo(String name)"); return "Hello " + name + ", How are you doing?"; } }
DeploymentDescriptor.xml
<isd:service
xmlns:isd="http://xml.apache.org/xml-soap/deployment"
id="urn:Hello">
<isd:provider
type="java"
scope="Application"
methods="sayHelloTo">
<isd:java
class="hello.HelloImpl"
static="false"/>
</isd:provider>
</isd:service>
Notes on Deployment
• id=“urn:Hello” – this will be the urn identified in the SOAP-Request by the client– and mapped to a service object
• scope=“Application” – an instance is created once for the entire application
Notes on Deployment II
• class=“hello.HelloImpl” – the (Java) class to be loaded for this URN– Must be available on the Servlet-Engine’s
classpath
• static=“false” – an instance method rather than a class method
Deploying the Descriptor
• Done by POSTing a SOAP message to the SOAP Service Manager:
\soap>java
org.apache.soap.server.ServiceManagerClient
http://localhost:8080/soap/servlet/rpcrouter
deploy hello\DeploymentDescriptor.xml
(line breaks for presentation only)
The Hello Client
• Note that the most basic version is quite long-winded
• Compare this to the Dynamic Proxy version that comes later!
Hello I - imports
package hello;
import java.net.URL;
import java.util.Vector;
import org.apache.soap.SOAPException;
import org.apache.soap.Constants;
import org.apache.soap.Fault;
import org.apache.soap.rpc.Call;
import org.apache.soap.rpc.Parameter;
import org.apache.soap.rpc.Response;
Hello II - init
public class Client {
public static void main(String[] args)
throws Exception
{
String name = args[0];
try {
URL url = new
URL("http://localhost:8080/
soap/servlet/rpcrouter");
// Build the call - but time it also
long start = System.currentTimeMillis();
Hello III – Call setup
Call call = new Call();
call.setTargetObjectURI("urn:Hello");
call.setMethodName("sayHelloTo");
call.setEncodingStyleURI(
Constants.NS_URI_SOAP_ENC);
Vector params = new Vector();
params.addElement(
new Parameter(
"name", String.class, name, null));
call.setParams(params);
Hello IV – Method Invocation
Response resp = null; try { resp = call.invoke(url, ""); resp = call.invoke(url, ""); } catch( SOAPException e ) { System.err.println( "Caught SOAPException (" + e.getFaultCode() + "): " + e.getMessage()); System.exit(-1); }
Hello V – Response Handling
if( !resp.generatedFault() ) { Parameter ret = resp.getReturnValue(); Object value = ret.getValue(); System.out.println(value); } else { Fault fault = resp.getFault(); System.err.println( fault ); } long end = System.currentTimeMillis(); System.out.println( "Elapsed ms: " + (end - start) );
Running Hello
• When run successfully, get the following:
\soap>java hello.Client SimonHello Simon, How are you doing?Elapsed ms: 701
• The elapsed time looks very slow• BUT: most of the delay is in loading the client-
side classes• Subsequent calls are much quicker!!!
Dynamic Proxies
• A Dynamic Proxy can hide the nasty details!• We set up a dynamic proxy by:
– specifying an array of interfaces that it will implement
– a service end-point to use to invoke methods of those interfaces (i.e. an Invocation Handler)
• We can now invoke the methods on the object just as if it were a local object
• The following code (Again from Tarak Modi) illustrates this
hello.ProxyClient.javapackage hello;
import proxy.*;
public class ProxyClient {
public static void main(String[] args)
throws Exception
{
Class[] interfaces = new Class[] {hello.Hello.class};
Hello hello =
(Hello) Proxy.newInstance("urn:Hello",interfaces);
System.out.println(hello.sayHelloTo("Simon"));
}
}
Dynamic Proxies Contd.• Dynamic proxies greatly simplify invoking
SOAP services• Of course – even without a Dynamic Proxy,
we could still write a SOAP-RPC implementation of the Hello interface
• And then make RPC call just like with the Dynamic Proxy version
• But – with the Dynamic Proxy, we don’t have to write the code!
• Clever!!!
TcpTunnelGui
• Apache SOAP comes with a simple but great tool – TcpTunnelGui
• Can be invoked from the command line like this:
java org.apache.soap.util.net.TcpTunnelGui 5050 localhost 8080
• 5050 – the port to listen for client connections• localhost – the server host to connect to• 8080 – the server port to connect to
TcpTunnelGui
Hello Request HTTP Header
POST /soap/servlet/rpcrouter HTTP/1.0
Host: localhost:5050
Content-Type: text/xml
Content-Length: 402
SOAPAction: ""
Hello Request Envelope<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body>
<ns1:sayHelloTo
xmlns:ns1="urn:Hello"
SOAP-ENV:encodingStyle=
"http://schemas.xmlsoap.org/soap/encoding/">
<name xsi:type="xsd:string">Simon</name>
</ns1:sayHelloTo>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
Hello Response HTTP Header
HTTP/1.0 200 OK
Content-Type: text/xml; charset=UTF-8
Content-Length: 448
Set-Cookie2: JSESSIONID=x8u8uwwaf1;Version=1;Discard;Path="/soap"
Set-Cookie: JSESSIONID=x8u8uwwaf1;Path=/soap
Servlet-Engine: Tomcat Web Server/3.2.1 (JSP 1.1; Servlet 2.2; Java 1.3.1_01; Windows 2000 5.1 x86; java.vendor=Sun Microsystems Inc.)
Hello Response Envelope<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema">
<SOAP-ENV:Body> <ns1:sayHelloToResponse xmlns:ns1="urn:Hello" SOAP-ENV:encodingStyle= "http://schemas.xmlsoap.org/soap/encoding/"> <return xsi:type="xsd:string"> Hello Simon, How are you doing? </return> </ns1:sayHelloToResponse> </SOAP-ENV:Body></SOAP-ENV:Envelope>
RPC Protocol Comparisons
RMI v. XML RPC Protocols
• RMI is based on the Java language– each process involved in the computation must
include a Java Virtual Machine– although the JVM may invoke native methods –
and hence integrate calls to components written in other languages
• RMI can use call-backs i.e. client and server can reverse roles
• RMI allows remote references to objects
XML v. RMI (part II)
• RMI uses binary-based object serialisation• XML encodes objects in plain text• Java serialized objects are more compact
than XML-serialized objects• Typically makes RMI more efficient
– Note that in some cases the XML can be sent over a GZIP stream to reduce network bandwidth
– But still have the XML writing/parsing overhead
XML v. RMI (part III)
• XML-based methods work better over HTTP – and better through firewalls.
• Java RMI by default uses Socket numbers that often get filtered out by firewalls.
• Java RMI can be made to work over HTTP– But callbacks may no longer work– problems may also arise with remote references –
have to mess around with special socket factories
XML v. RMI (part iv)
• XML-based methods are not just platform independent, but also language independent, and can be processed by very simple and compact XML readers and writers.
• XML-based methods also typically (though not necessarily) involve– separate HTTP Request/Response pairs for each
call– separate socket connections to be used for each
call – another source of inefficiency.
XML-RPC v. SOAP-RPC• XML-RPC is much simpler than SOAP• XML-RPC is an easy way to make a remote
procedure call• The procedure call is associated with a
service rather than an object• SOAP nominally accesses an Object
(specified via its URN)• But in many cases, this is used just like the
XML-RPC case• Either way – possible to specify an Object-Id
as a parameters
Object Encoding• XML-RPC has a fixed mapping for primitive
types and simple collections (e.g. Arrays and Vectors in Java)– but is unable to directly encode user-defined
objects.
• SOAP leaves the object-encoding scheme open to the user
• Note that there are some standard methods - in particular, the SOAP-standard encoding scheme
• This means that SOAP is very powerful and flexible, but can also be more complex to set up than RPC.
Version robustness with XML
• Suppose we change out Rectangle class to include a Color attribute.
• Any RMI clients must now be updated to use the new classes (which may or may not happen automatically, depending on the class-loader in use)
• The XML versions continue to work happily – merely ignoring the new Color attribute
The Story Continues
• Using XML RPC methods allow language neutral RPC services to be offered
• BUT: client and server must agree on the structure of the XML documents that get exchanged
• Both the broad structure (e.g. SOAP-RPC)• And the details of each method signature
AND object encoding• The use of XML offers some robustness
against version changing
Further Reading
• Programming Web Services with SOAP– Snell, Tidwell and Kulchenko– O’Reilly, 2002
• Various articles at xml.com on web services such as:
• http://www.xml.com/pub/a/2002/02/20/rest.html
Discussion Exercise
• Suppose you are required to implement your own XML-based RPC system
• Unlike the standard XML-RPC, it will allow any type of object to be passed
• For Java binding, will use JSX for serialization• Discuss how you would design such a
protocol, and what the main implementation challenges would be