RPC over XML Web services with Java Distributed Systems SS03 Layered architecture based on TCP Bottommost layer is HTTP SOAP (XML) sits above it LOT of W3C standards and W3C drafts describe it. Reference implementation Sun JWSDK (Java Web Services Development kit) Enables to test the newest technology for free Contains Tomcat (Apache-based webserver), Ant (make utility) and several example applications and JAX-RPC (we will use this component), JAXM (the message-based middleware). Installation and maintenance is quite hard! (About 6000 files in the tree, 60 MB disk-space required) Works under Windows and Linux (everything is written in Java) How to install it? Install J2SE 1.3.1 or better 1.4.x! Start the JWSDP installer! Follow the instructions to replace some older files in the J2SE library tree Set the PATH variables Experiment with it! Setting the environment variables Set JAVA_HOME to the J2SE s root Set TOMCAT_HOME and CATALINA_HOME to the JWSDP s root Put the bin directories into the search PATH (don t forget to include ant s bin directory) PATH to JWSDP s Ant s bin directory should be at the beginning! Otherwise things won t work Most problems with J2EE/JWSDP are caused by wrong PATH and variable settings Preparing the system Create a file, called build.properties in your homedirectory ~ on Unices C:\Dokumente und Einstellungen\yourName on Windows systems It should contain the following 2 lines: username=your TOMCAT user name password=your TOMCAT password Look at the tomcat-users.xml file if you have forgotten your user name and password
Starting/Stopping Tomcat $JWSDP_HOME/bin/startup.sh Install your web applications (Write them if necessary) You can access the Tomcat server on the port 8080 http://localhost:8080/yourapplication $JWSDP_HOME/bin/shutdown.sh How to develop a web service with JAX-RPC? Write only 2 classes. One class exposes the service method signature, the other class should provide implementation of the service Define an XML configuration file that contain instructions to generate client-side and server-side stubs required by JAX-RPC (necessary for the Java-to-WSDL mapping tool) Define a web.xml file that specifies the deployment descriptor for deployment in an application server That s all! and install ( deploy ) them! Our sample web service the interface The interface defining the service should extend java.rmi.remote Every method should throw a java.rmi.remoteexception No constant declaration is allowed Only SOAP-able data types are supported We will see the SOAP-able Primitive data types in JAX-RPC JAX-RPC uses the following type-mapping Boolean -> xsd:boolean Byte -> xsd:byte Double -> xsd:double Float -> xsd:float Integer (int) -> xsd:int Long -> xsd:long Short -> xsd:short Supported Java standard-classes BigDecimal -> xsd:decimal BigInteger -> xsd:integer Calendat -> xsd:datetime Date -> xsd:datetime [broken] GregorianCalendar -> xsd:datetime String -> xsd:string JWSDP supports more data types that can be used only if all involved parties are using Java (Vector, Stack, HashTable, etc.) Arrays of supported JAX-RPC types are also supported Supported application classes Other, programmer defined classes are also supported. They must adhere to some conventions They must have a public default constructor It must not implement the java.rmi.remote interface Ist fields must be supported JAX-RPC types A public field cannot be final or transient A non-public field may have corresponding getter and setter methods (JavaBeans coding convention)
Hello web service description The world s simplest distributed greeting service Its input is a name (String) The result is a greeting in String form Implemented as a JAX-RPC web service endpoint The hello web service interface package hello; import java.rmi.remote; import java.rmi.remoteexception; public interface HelloIF extends Remote { public String sayhello(string s) throws RemoteException; A sample XML configuration file for the hello service <?xml version="1.0" encoding="utf-8"?> <configuration xmlns="http://java.sun.com/xml/ns/jaxrpc/ri/config"> <wsdl location="http://localhost:8080/hellojaxrpc/hello?wsdl packagename="hello"/> </configuration> This file (config.xml) will be used to generate cliens/server stubs/skeletons with the wscompile utility. hello implementation class package hello; public class HelloImpl implements HelloIF { public String message = "Hello "; public String sayhello(string s) { return message + s; Using wscompile(.sh/.bat) to generate client stubs The hard way... ~/jwsdp-1.1/jaxrpc-1.0.3/bin/wscompile.sh -gen:client -d build/client/hello classpath build/shared config.xml And then execute deployment, etc. etc. with the manager login of your Tomcat server! The easy way: Download ds2003webservices.tar from the course page Modify the war-path (use your directory instead of /home/itec/csb) Start the command kompajl to compile everything Start the command ant run to execute the client If the paths are set correctly, the program will be deployed and run! A client application of the service import javax.xml.rpc.stub; import java.util.date; public class HelloClient { public static void main(string[] args) { try { Stub stub = createproxy(); HelloIF hello = (HelloIF)stub; System.out.println(hello.sayHello("Duke!")); catch (Exception ex) {ex.printstacktrace(); private static Stub createproxy() { return (Stub)(new MyHello_Impl(). // for JWSDP gethelloifport()); //see jaxrpc-ri.xml!
Client stub name The name of the client stub is not standardized JWSDP uses the file jaxrpc-ri.xml when contructing the client stub Look at it! Here is an excerpt: <endpointmapping endpointname="myhello" That s why wscopile and we used MyHello for the stub s classname. wscompile creates client stubs based on their WSDL description ( downloaded from the Tomcat server) Implementation-specific parts The file config.xml is used by JWSDP only jaxrpc-ri.xml too Stub and tie (server skeleton) class names The tools (wscompile,wsdeploy,deploytool) Support for collections as parameters and return values (Using JAX-RPC with J2EE is not the same as with JWSDP) We use the latest version (1.1) of JWSDP Common errors SOAP on the wire request hdr The paths are not set An older version of ant is in the PATH before a newer one Tomcat is not running during compilation time (remember: WSDL descriptions stored in WAR files are accessed during compilation) HTTP-specific response codes: 404: resource unavailable 401: password required (does the file named build.properties contain the right password?) localhost.37408 > localhost.http-alt: POST /hello-jaxrpc/hello HTTP/1.1 Content-Type: text/xml; charset="utf-8" Content-Length:477 SOAPAction: "" User-Agent:Java/1.4.1_02 Host: localhost:8080 Accept: text/html, image/gif, image/jpeg, *; q=2, */*; q=2 Connection: keep-alive SOAP on the wire request body SOAP on the wire reply hdr <?xml.version="1.0" encoding="utf-8"?> <env:envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelop e/" xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:xsi="http://www.w3.org/2001/xmlschemainstance" xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/ " xmlns:ns0="http://com.test/wsdl/myhello" env:encodingstyle="http://schemas.xmlsoap.org/soap/e ncoding/"> <env:body><ns0:sayhello><string_1 xsi:type="xsd:string">duke!</string_1> </ns0:sayhello></env:body></env:envelope> localhost.http-alt > localhost.37408 HTTP/1.1 200 OK Content-Type: text/xml; charset="utf-8" SOAPAction: "" Transfer-Encoding: chunked Date: Sun, 01 Jun 2003 16:39:54 GMT Server: Apache Coyote HTTP/1.1 Connector [1.0]
SOAP on the wire - reply body And where are WSDL&UDDI? <?xml.version="1.0".encoding="utf-8"?> <env:envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns0="http://com.test/wsdl/myhello" env:encodingstyle="http://schemas.xmlsoap.org/soap/enco ding/"> <env:body><ns0:sayhelloresponse> <result xsi:type="xsd:string">hello Duke!</result> </ns0:sayhelloresponse></env:body></env:envelope> WSDL descriptions are automagically generated by the wscompile tool in JWSDP They are stored in.war files (WEB application archives) Take a look at the file hello-jaxrpc.war Unzip it Look for WEB-INF/MyHello.wsdl See the next 3 slides about the generated WSDL file <?xml version="1.0" encoding="utf-8"?> <definitions name="myhello" targetnamespace="http://com.test/wsdl/myhello" xmlns:tns="http://com.test/wsdl/myhello" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/xmlschema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soa p/"> <types/> <message name="helloif_sayhello"> <part name="string_1 type="xsd:string"/> </message> <message name="helloif_sayhelloresponse"> <part name="result" type="xsd:string"/> </message> <porttype name="helloif"> <operation name="sayhello" parameterorder="string_1"> <input message="tns:helloif_sayhello"/> <outputmessage="tns:helloif_sayhelloresponse"/> </operation></porttype> <binding name="helloifbinding" type="tns:helloif"> <operation name="sayhello"> <input> <soap:body encodingstyle="http://schemas.xmlsoap.org/soap/ encoding/" use="encoded" namespace="http://com.test/wsdl/myhello"/></inp ut> <output> <soap:body encodingstyle="http://schemas.xmlsoap.org/soap/ encoding/" use="encoded" namespace="http://com.test/wsdl/myhello"/></out put> <soap:operation soapaction=""/></operation> <soap:binding transport="http://schemas.xmlsoap.org/soap/http " style="rpc"/></binding> <service name="myhello"> <port name="helloifport" binding="tns:helloifbinding"> <soap:address location="replace_with_actual_url"/></p ort></service></definitions> The UDDI Role of UDDI: stores links to WSDL descriptions of web services UDDI registry is not part of JWSDP A registry browser and registry access library are part of JWSDP See JAXR! Register your service if it works well at well-known UDDI-Servers
Well-known UDDI servers http://www-3.ibm.com/services/uddi https://uddi.ibm.com/ https://uddi.ibm.com/ubr/registry.html http://uddi.microsoft.com A test server: http://test.uddi.microsoft.com Use only if a service will be added soon into a the public registry Other test server this from IBM: https://uddi.ibm.com/testregistry/publish Registering your service@uddi Open the start page of one of the UDDI servers, log in and choose Publish Press Add a new Business and insert your (company s) name and other details Add Business Locators to it (categorize!) Press Continue and then Save Press Add a new Service and insert Name, Description, Access Point, Locator Press Add a new Technical Model (also known as tmodel). Add the same information as above. The Overview URL will be the URL of yur WSDL description UDDI Service Inquiry There are two ways to do this : Using inquiry API-s https://www- 3.ibm.com/services/uddi/testregistry/inquiryapi Using a webbrowser Note that some service providers listed in the UBR charge consumers that access their Web services UDDI Inquiry by... Open the registry startpage and select Find Choose Business if you know company names and want to search by company name Service if you know the name of the service you want or want to search by service name Technical Model if you are searching with WSDL descriptions Use the % sign as a joker (wildchar) character Homework See http://www.itec.uniklu.ac.at/~csb/ds2003webservices.tar Implement TimeServer with webservices! (Deadline: 25.06.2003)