View Source

{panel:title=Last tested with}
* Petals Guide Package 1.0 - [Download binaries here|http://doc.petalslink.com/x/t4KK]
* Tomcat 6.0.29
* JDK 6 update 20
* SoapUI 3.6

This Tutorial uses:
* Petals Studio
* Petals ESB
* Petals SE RMI
* Petals BC SOAP
* Petals Web console
* Tomcat
* soapUI
* Petals SE Jsr-181 _(new)_
{panel}

Any question, any problem? Find the solution on the [JSR181 tutorial discussion.|http://forum.petalslink.com/Petals-Starting-Guide-day-4-Jsr-181-tp2686713p2686713.html]



h2. A Few reminders

*In case you forgot Java:*


# Run this Java Hello World Tutorial with Petals Studio: [http://www.cis.upenn.edu/~matuszek/cit591-2004/Pages/starting-eclipse.html]
# Read this Object-Oriented Programming Tutorial (Inheritance doesn't matter here): [http://download.oracle.com/javase/tutorial/java/concepts/index.html]
# Answer those questions: What is a Java Object ? Class ? Method ? Attribute ?


*JSR181 and POJO*:
Java classes can be included in Petals ESB in two ways:
* POJO (Plain Old Java Object) is the basic way to include Java code into Petals ESB.
* JSR181 (POJO+Annotations) adds Web Services Metadata (Annotations) for the Java Platform. This fits well with SOA.
{info}Why Jsr-181 instead of POJO ?
JSR 181 or Web Services Metadata for the Java Platform is a Java Specification Request that defines an annotated Java format that uses Java Language Metadata (JSR 175) to enable easy definition of Java Web Services in a J2EE container. To put simply, JSR 181 enables developers to create portable Java Web Services from a simple Plain Old Java Object (POJO) class by adding annotations.
{info}

*Service Engines (SE) and Binding Components (BC)*:
In previous tutorials, you configured only Binding Components (BC-SOAP and BC-FTP). Today you will configure a Service Engine (SE-Jsr181). Difference between BC and SE:

* Binding components connect the bus to the outside with various protocols.
* Service Engines are engines to run processes.


h2. Jsr181 : Hello World

*Configure JSR181 HelloWorld:*
# Create a new *Service-Unit Project* in *Petals Studio*.
# Select *Use a Petals Technical Service > Jsr-181 > Your_current_version*.
# Click *Next*.
## *Project name*: su-jsr181-HelloWorld-provide
# Click Next. It displays the window "Jsr-181 Service-Unit - Select creation mode of the JAX Web Service."
## Check *Start with a JAX-WS implementation*.
## *Class name*: com.petalslink.test.HelloWorld
{info:title:About class name and namespaces}{_}com.petalslink.test_ is the Package Name (Corresponding namespace URI is: [http://test.petalslink.com] )
_HelloWorld_ is the Class Name.
_com.petalslink.test.HelloWorld_ is the Qualified Class Name.{info}
# Click *Next > Finish*.

This generates a _HelloWorld.java_ file, looking like this:
{code:lang=java|title=HelloWorld.java|collapse=false}
package com.petalslink.test;

import javax.jws.Oneway;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

/**
 * Here is a sample JAX-WS implementation.
 * <p>
 * For more information about JAX-WS, please visit
 * <b>https://jax-ws.dev.java.net/jax-ws-ea3/docs/annotations.html</b>.
 * </p>
 *
 * @author mathieulebreton
 */
@WebService( serviceName="HelloWorld", targetNamespace="http://test.petalslink.com", portName="HelloWorldPort" )
public class HelloWorld {

    /* (non-Javadoc)
     * @see JaxWSInterface#HelloWorld()
     */
    @WebMethod( operationName="helloWorld" )
    @WebResult( name="returnMessage" )
    public String helloWorld() {
        return "Hello World!";
    }
    
    /*
     * (non-Javadoc)
     * @see toto.JaxWSInterface
     * #listenToTheWorld(java.lang.String)
     */    
    @WebMethod( operationName="listenToTheWorld" )
    @Oneway
    public void listenToTheWorld( @WebParam( name="message" ) String message ) {
        // We here illustrate a method that do not return anything.
    }
}
{code}

*Generate corresponding WSDL:*

# Right-click on *su-jsr181-HelloWorld-provide* in Petals project tree.
# Select *Petals > Generate WSDL(s)*. It displays a pop-up "Also generate a jbi.xml ?"
# Click *Yes*.
# Just give a look at the generated source of _jbi.xml_ and _HelloWorld.wsdl_.

{note}listenToTheWorld method uses "@OneWay" annotation, which is not well supported yet, in SE-Jsr181 1.1.3, so please do not use operation listenToTheWorld. @OneWay might be supported in next SE-Jsr181 release.{note}
{note}{*}Known problem*


BC-SOAP needs a parameter called _SoapAction_, unique to each operation. When you generate WSDLs for Jsr181 in Petals Studio, Each operation has the same _SoapAction_ value. This should be fine in our case. But to be completely clear in case of strange behavior, you can edit _HelloWorld.wsdl_ and define \_SoapAction_s. This might be corrected in the future, in Petals Studio or in BC-SOAP.

SELECT:
{code:lang=xml}
<operation name="helloWorld">
<soap:operation soapAction=""/>{code}
REPLACE BY:
{code:lang=xml}
<operation name="helloWorld">
<soap:operation soapAction="helloWorld"/>{code}

SELECT:
{code:lang=xml}
<operation name="listenToTheWorld">
<soap:operation soapAction=""/>{code}
REPLACE BY:
{code:lang=xml}
<operation name="listenToTheWorld">
<soap:operation soapAction="listenToTheWorld"/>{code}
{note}


*Deploy Jsr181 HelloWorld:*
# Fast-Export *su-jsr181-HelloWorld-provide* for Petals.
# [Download|http://doc.petalslink.com/x/t4KK] Petals-SE-Jsr181.
# Deploy _Petals-SE-Jsr181_ in Petals ESB.
# Deploy _su-jsr181-HelloWorld-provide.zip_ in Petals ESB.

*Test HelloWorld:*
# Go to *Webconsole > Server:0 > Test > Send*.
# Send a few test messages to *HelloWorldPort* Endpoint. Use MEP *InOut* for helloWorld operation
{note}Do not test listenToTheWorld as @Oneway annotation is not supported yet.{note}



h2. Hello world over SOAP

*Proxify HelloWorld with SOAP consume:*
# Go to *Petals Studio > File > New Service-Unit*.
# Select *Consume > SOAP > Your_current_version*.
# Click *Next*. It displays the window "Define the JBI properties of the service to consume".
## Click *Select a Service*
## Double click *{_}HelloWorld implements (...)_*. It generates JBI properties for HelloWorld.
# Click *Next > Next*. It displays the window "Define the specific properties for this version of the component."
## *Service Name*: SoapHelloWorld
# Click *Next > F{*}{*}inish*.
# Fast export _su-SOAP-HelloWorld-consume_
# Deploy it into Petals ESB.

*Import the WSDL in SOAPUI and test it:*
# Go to [http://127.0.0.1:8084] in your web browser. (If this is not your adress, find the root URL of the deployed service in Petals ESB traces, and go there).
# Go to *Services List*.
# Copy the URL of SoapHelloWorld WSDL.
# Launch *soapUI*.
# Click *File > New soapUI Project*.
## *Project Name*: PetalsJsr181HelloWorld (any name could fit).
## *Initial WSDL/WADL*: _Paste the WSDL URL_ (might be: [http://127.0.0.1:8084/petals/services/SoapHelloWorld?wsdl]).
# Click *OK*.
# Run the default request of _helloWorld_ operation in soapUI.
{code:lang=xml|title=Test message might look like this|collapse=false}
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:test="http://test.petalslink.com">
<soapenv:Header/>
<soapenv:Body>
<test:helloWorld/>
</soapenv:Body>
</soapenv:Envelope>{code}
{code:lang=xml|title=Response might look like this|collapse=false}
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <dlwmin:helloWorldResponse xmlns:dlwmin="http://test.petalslink.com">
         <returnMessage>Hello World!</returnMessage>
      </dlwmin:helloWorldResponse>
   </soapenv:Body>
</soapenv:Envelope>{code}


h2. Custom JSR181 Class

You just created a standard Jsr181+SOAP Hello World. Next step: implement your own Java class. You will code three methods, to Add, Multiply or Divide two integers.

*Create a new Jsr181 class:*
# Go to *Petals Studio > File > New > Service-Unit Project*.
# Select *Use a Petals Technical Service > Jsr181 > Your_current_version*.
# Click *Next*.
## *Project name*: su-jsr181-MathOperations-provide
# Click *Next*. It displays window "Select creation mode of the JAX Web Service".
## Select *Start with a JAX-WS implementation*;
## *Class name*: com.petalslink.test.MathOperations
# Click *Next > Finish*.

*Code your custom Jsr181 class*:

# Code three Java annotated operations (Go on your own \!). Input parameters: two integers. Output: returns one integer.
## *AddIntegers* adds two integers.
## *DivideIntegers* divides the first integer by the second.
## *MultiplyIntegers* multiplies two integers.
{info: title= Jsr181 Annotation} Main annotations: (go to \[[Petals Jsr181 documentation|petalscomponents:Petals-SE-Jsr181] to get examples)

* The @WebService annotation is mandatory and is used by the Axis2 engine to build the service. You can specialize the service name, target namespace and more with the annotation parameter.
* The @WebMethod annotation is used to delare the that the method will be seen as a JBI operation. You can specialize the operation name and more with the annotation parameters.
* The @WebParam annotation is used to configure an operation parameter.{info}
{info}Annotation Description from [Jsr-181 specification|http://jcp.org/aboutJava/communityprocess/mrel/jsr181/index.html] 2.0:
* javax.jws.WebService: Marks a Java class as implementing a Web Service, or a Java interface as defining a Web Service interface:
* javax.jws.WebMethod: Customizes a method that is exposed as a Web Service operation.
* javax.jws.Oneway: Indicates that the given web method has only an input message and no output. Typically, a oneway method returns the thread of control to the calling application prior to executing the actual business method.
* javax.jws.WebResult: Customizes the mapping of the return value to a WSDL part and XML element.
* javax.jws.HandlerChain: The @HandlerChain annotation associates the Web Service with an externally defined handler chain.
* javax.jws.soap.SOAPBinding: Specifies the mapping of the Web Service onto the SOAP message protocol.
* javax.jws.soap.SOAPMessageHandlers: of JSR-181 2.0 with no replacement. This annotation was originally used to create a JAX-RPC handler chain. In this version, the annotation is ALWAYS ignored.
{info}

Read this sample operation if you need help:
{code:title=MathOperations.java (just one operation)|lang=java|collapse=true}package com.petalslink.test;

//import javax.jws.Oneway;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;

@WebService( serviceName="MathOperations", targetNamespace="http://test.petalslink.com", portName="MathOperationsPort" )
public class MathOperations {

/* (non-Javadoc)
* @see JaxWSInterface#HelloWorld()
*/
@WebMethod( operationName="AddIntegers" ) // @WebMethod: Name of service operations that we will call
@WebResult( name="returnMessage" ) // @WebResult: Name of the message returned by service
public Integer AddIntegers( @WebParam( name="integer1" ) Integer integer1, @WebParam( name="integer2" ) Integer integer2 ) { //@WebParam => Name of service parameters
return integer1+integer2;
}; // Returns the sum of two integers
}{code}

Use this solution in case you get stuck:
{code:title=MathOperations.java|lang=java|collapse=true}
package com.petalslink.test;
 
//import javax.jws.Oneway;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
 
@WebService( serviceName="MathOperations", targetNamespace="http://test.petalslink.com", portName="MathOperationsPort" )
public class MathOperations {
 
     /* (non-Javadoc)
      * @see JaxWSInterface#HelloWorld()
      */
     @WebMethod( operationName="AddIntegers" ) // @WebMethod: Name of service operations we will call
     @WebResult( name="returnMessage" ) // @WebResult: Name of the message returned by service
     public Integer AddIntegers( @WebParam( name="integer1" ) Integer integer1,  @WebParam( name="integer2" ) Integer integer2 ) { //@WebParam => Name of service parameters
          return integer1+integer2;
     }; // Adds two integers
 
     @WebMethod( operationName="DivideIntegers" )
     @WebResult( name="returnMessage" )
     public Integer DivideIntegers( @WebParam( name="integer1" ) Integer integer1,  @WebParam( name="integer2" ) Integer integer2 ) {
          return integer1/integer2;
     }; // Divide two integers
 
     @WebMethod( operationName="MultiplyIntegers" )
     @WebResult( name="returnMessage" )
     public Integer MultiplyIntegers( @WebParam( name="integer1" ) Integer integer1,  @WebParam( name="integer2" ) Integer integer2 ) {
          return integer1*integer2;
     }; // Multiply two integers
}{code}

*Deploy and test in Webconsole:*
# Right click *su-jsr181-MathOperations-provide* in Petals project tree.
# Select *Petals > Generate WSDL(s)*. It displays a pop-up "Also generate a jbi.xml ?"
# Click *Yes*.
{note}Edit MathOperations.wsdl to specify SoapActions. (See known problem above)
SELECT for each operation:
{code:lang=xml}<soap:operation soapAction=""/>{code}
REPLACE BY with a different soapAction name for each operation:
{code:lang=xml}<soap:operation soapAction="UniqueSoapActionName"/>{code}
{note}

# *Fast Export* "su-jsr181-MathOperations-provide".
# Deploy it in Petals ESB.
# Test AddIntegers operation in *Webconsole*:
{code:title=Webconsole AddIntegers Test message|lang=xml}
<AddIntegers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="AddIntegers">
<integer1>1</integer1>
<integer2>2</integer2>
</AddIntegers>{code}
{code:title=Response|lang=xml|collapse=true}
<dlwmin:AddIntegersResponse xmlns:dlwmin="http://test.petalslink.com" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<returnMessage>3</returnMessage>
</dlwmin:AddIntegersResponse>{code}
# Test DivideIntegers.
# Test MultiplyIntegers.


*Test operations with soapUI:*

# Proxify "MathOperations" service over SOAP: Create a SOAP-Consume, export it and deploy it in Petal ESB.
# Test AddIntegers, DivideIntegers and MultiplyIntegers, from soapUI.

*DONE. Bravo \!*
Now you know :
* What are Jsr-181 annotations.
* How to code and deploy a Jsr-181 Java class in Petals ESB.

*Tomorrow you will create a simple process, using Enterprise Integration Patterns (EIP).*