distributed object programming with xml and java cc432 / short course 509 applied xml lecturer:...

Post on 21-Dec-2015

228 Views

Category:

Documents

3 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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

top related