Arun Gupta, Miles to go ...

Arun Gupta is a technology enthusiast, a passionate runner, and a community guy who works for Sun Microsystems.
Main | Next page »

http://blogs.sun.com/arungupta/date/20090825 Tuesday August 25, 2009

TOTD #98: Create a Metro JAX-WS Web service using GlassFish Tools Bundle for Eclipse


Now that you've installed GlassFish Tools Bundle for Eclipse 1.1, lets use this bundle to create a simple Metro/JAX-WS compliant Web service and deploy on GlassFish. These steps will work with either Eclipse 3.4.2 or 3.5 with WTP Java EE support.

  1. Lets create a simple "Dynamic Web Project" as shown below:


  2. Name the project "HelloMetro" and take all other defaults:



    Click on "Finish" to complete the project creation.
  3. Metro allows to create a Web service from a POJO class. So let's add a POJO to the project by right-clicking on the project and selecting "New", "Class" as shown below:

      

    Specify the package name as "server", class name as "HelloService" and click on "Finish".
  4. Add a simple method to the newly generated class as:

    public String sayHello(String name) {
          return "Hello " + name + "!!";
    }
  5. Expand the project, go to "HelloService.java" in "server" package, right-click, select "Web Services", "Create Web service".
  6. Click on "Web service runtime: Apache Axis" and select "Metro (JAX-WS) Runtime" as the Web service runtime as shown below:

  7. Move the slider on the left to top. This will enable testing of the deployed Web service. The completed configuration looks like:



    and click on "Next >".
  8. Select the checkbox "Copy Metro library jars to the project" to resolve the references correctly as shown below:



    and click on "Next >". This bundles the application and deploys to GlassFish and provides an option to test the deployed Web service as shown below:



    Clicking on the "Launch" button shows the following output in the browser:



    The WSDL is hosted at "http://localhost:8083/HelloMetro/HelloServiceService?wsdl".
  9. Click on "sayHello" method, click on "Add" and enter the value as "Duke" as shown below:



    Click on "Go" and the response is shown as:



    Clicking on "Source" in the response window shows the SOAP request/response messages as shown below:

  10. Alternatively, you can click on "Finish" to complete the dialog. Then click on "Run" menu item, "Launch the Web Services Explorer" to see a screen as:



    Enter the URL of the WSDL in "WSDL URL" box as "http://localhost:8083/HelloMetro/HelloServiceService?wsdl" and click on "Go". Now you are seeing the similar screen to test the Web service within the integrated browser as shown below:


A future blog will cover how to write a database-enabled application using the bundled Dali JPA Tools and MySQL pre-registered JDBC driver.

Please send your questions and comments to users@glassfishplugins.dev.java.net.
Please leave suggestions on other TOTD that you'd like to see. A complete archive of all the tips is available here.

Technorati: totd glassfish eclipse galileo webservices metro jax-ws

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20081017 Friday October 17, 2008

SOAP and REST - both equally important to Sun


"Sun moving away from SOAP to embrace REST" is the misleading title of an article recently published in SD Times. The article provides a good introduction to JAX-RS and Jersey. But I really wonder what motivated the author of this article to use this title. This blog, hopefully, provides a better context.

Jersey is the Reference Implementation of Java API for RESTful Web Services (JAX-RS, JSR 311) and was released earlier this week. The headline indicates that Sun is leaving SOAP and will support REST. The debate between REST and SOAP is not new and there are religious camps on both sides (even within Sun). And that's completely understandable because each technology has its own merits and demerits. But just because a new JSR aimed to make RESTful Web services easy in the Java platform is released, it does not mean Sun Microsystems is leaving existing technology in trenches.

The addition of Jersey to Sun's software portfolio makes the Web services stack from GlassFish community a more compelling and comprehensive offering. This is in contrast  to "moving away" from SOAP as indicated by the title. As a matter of fact, Jersey will be included as part of Metro soon, the Web Services stack of GlassFish. And then you can use JAX-WS (or Metro) if you like to use SOAP or JAX-RS (or Jersey) if you prefer RESTful Web services. It's all about a offering choice to the community instead of showing a direction.

Here are some data points for JAX-WS:

  • The JAX-WS 2.0 specification was released on May 11, 2006. There have been couple of maintenance releases since then and another one brewing.
  • Parts of Metro, the implementation of JAX-WS, are currently baked into GlassFish, embeddable in JBoss WS Stack, and also part of Oracle Weblogic and IBM Websphere.
  • The implementation stack is mature and used in several key customer deployments. 
  • JAX-WS is already included in Java SE 6 and hence available to a much wider audience.
  • As opposed to "moving away", JAX-WS 2.2 (currently being worked upon) will be included in Java EE 6 platform, as will Jersey be.
So I believe both SOAP and REST are here to stay, at least in the near future. And Sun Microsystems is committed to support them!

You still think Sun is moving away from SOAP ?

It seems a personal preference is interpreted as Sun's disinvestment in SOAP. It's good to have increased readership but not at the cost of misleading headlines :)

Technorati: jax-ws rest webservices metro sdtimes glassfish

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20080812 Tuesday August 12, 2008

LOTD #1: Using Silverlight to access GlassFish Metro and JAX-WS Web service endpoints

Following TOTD (Tip Of The Day) pattern, I'm starting LOTD (Link Of The Day) series today. These are light-weight entries with generally a single line description and links to other blogs/articles/tips/whitepapers/screencasts/etc.

Let's start with three recent entries on MSDN that describe how to invoke Metro and JAX-WS Web service endpoints from Microsoft Silverlight and .NET:

All entries will be archived at LOTD.

Technorati: lotd webservices metro jax-ws glassfish msdn

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20080111 Friday January 11, 2008

Java SE 6 Update 4 is released - "Good Riddance" with JAX-WS Endorsed

Java SE 6 Update 4 is now released. Download it here.

If you are a Metro user (either JAX-WS or WSIT) then this is a milestone release for you because it includes JAX-WS 2.1 API in the rt.jar. This means that, as a user, you no longer you need to copy JAX-WS or JAXB API jars in JAVA_HOME/jre/lib/endorsed as described here, here and here. Hurrah!

After you have downloaded and installed JDK 1.6 U4, java -version shows:

java version "1.6.0_04"
Java(TM) SE Runtime Environment (build 1.6.0_04-b12)
Java HotSpot(TM) Client VM (build 10.0-b19, mixed mode, sharing)

wsgen -version shows:

JAX-WS RI 2.1.1 in JDK 6

wsimport -version shows:

JAX-WS RI 2.1.1 in JDK 6

Additionally, you can also verify by greping for javax.xml.ws.Endpoint class in JAVA_HOME/jre/lib/rt.jar. This is a new class introduced in JAX-WS 2.1.

Now after you've installed Java SE U4, you can download Metro 1.1, set JAVA_HOME to point to this new Java SE installation and you can easily import a WSDL as:

wsimport -d temp http://localhost:8080/MetroWithJavaSE6/HelloService?WSDL
parsing WSDL...


generating code...


compiling code...

If you try to import the same WSDL with an earlier release of Java SE 6, then you'll see the error message:

You are running on JDK6 which comes with JAX-WS 2.0 API, but this tool requires JAX-WS 2.1 API. Use the endorsed standards override mechanism (http://java.sun.com/javase/6/docs/technotes/guides/standards/), or use -Xendorsed option.

We hope this will make your life simpler :)

Metro 1.0.1 is anyway baked in GlassFish v2 UR1. You can override it with Metro 1.1 as described in TOTD #21.

Technorati: webservices metro jax-ws glassfish endorsed javase6 jdk

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20071222 Saturday December 22, 2007

Metro 1.0.1 and 1.1 are now available

Metro 1.0.1 (integrated in GlassFish v2 UR1) ad Metro 1.1 are now released. Metro contain stable releases of JAX-WS RI and WSIT. Read Vivek's blog for more details.

Even though Metro 1.1 is a stand-alone release, it can be easily installed on an existing GlassFish instance (for example override on v2ur1). A later release of Metro 1.1 will be integrated in GlassFish v2.1. Metro Roadmap provides all the details.

Please send us your feedback on users@metro or Forum. A pleasant change that happened earlier today was that cross-posting was enabled between user's list and forum. So all the questions posted on user's list are cross-posted to Forum and vice versa. This enables wider audience for your questions and more engineers to respond back :)

Technorati: webservices metro jax-ws wsit glassfish v2ur1

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070910 Monday September 10, 2007

TOTD #8: Generating JSON using JAXB annotations in Jersey

Jersey provides a pluggable type system for the encoding/decoding of a Java type to/from an entity of an HTTP response/request. JSON support was added in Jersey using the BadgerFish convention for encoding/decoding JAXB beans to/from JSON. A new sample was also added in the recently released 0.2.1 that demonstrates this concept.

This TOTD provides provides a trivial sample (using the snippets shown on BadgerFish) that will allow you to experiment with this feature in Jersey. This sample consists of a Resource, Server and "build.xml" to build, deploy, run the server and invoke the endpoint.

Here is the code for the REST resource:

import javax.ws.rs.HttpMethod;
import javax.ws.rs.ProduceMime;
import javax.ws.rs.UriTemplate;

@UriTemplate("/helloworld")
public class HelloWorldResource {

  @HttpMethod
  @ProduceMime("application/xml")
  @UriTemplate("/xml")
  public States getXML() {
    return new alice();
  }

  @HttpMethod
  @ProduceMime("application/json")
  @UriTemplate("/json")
  public States getJSON() {
    return new alice();
  }
}

This resource is published on two URIs - one using XML (/xml) and the other using JSON (/json) representation. Here is the code to start the server:

import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import com.sun.ws.rest.api.container.ContainerFactory;
import java.io.IOException;
import java.net.InetSocketAddress;

public class HelloWorld {
  public static void main(String[] args) throws IOException {
    HttpHandler handler = ContainerFactory.createContainer(
      HttpHandler.class,
      HelloWorldResource.class);

    HttpServer server = HttpServer.create(new InetSocketAddress(9998), 0);
    server.createContext("/", handler);
    server.setExecutor(null);
    server.start();

    System.out.println("Server running");
    System.out.println("Visit: http://localhost:9998/helloworld");
    System.out.println("Hit return to stop...");
    System.in.read();
    System.out.println("Stopping server");
    server.stop(0);
    System.out.println("Server stopped");
  }
}

This is a very standard code that is available in all the bundled samples. And here is the "build.xml":

<project name="json" default="default" basedir=".">
  <property name="jersey.home" value="c:\jersey-0.2.1-ea"/>
  <path id="jersey.classpath">
    <fileset dir="${jersey.home}\lib" includes="*.jar"/>
  </path>
  <property name="build.dir" value="build"/>
  <property name="src.dir" value="src"/>

  <target name="init">
    <mkdir dir="${build.dir}"/>
  </target>

  <target name="build" depends="init">
    <javac srcdir="${src.dir}" destdir="${build.dir}" includes="**/*.java">
      <classpath refid="jersey.classpath"/>
    </javac>
  </target>

  <target name="run" depends="build">
    <java classname="samples.HelloWorld" fork="true">
      <classpath>
        <path refid="jersey.classpath"/>
        <pathelement location="${build.dir}"/>
      </classpath>
    </java>
  </target>

  <target name="get-json">
    <get src="http://localhost:9998/helloworld/json" dest="out.json"/>
  </target>

  <target name="get-xml">
    <get src="http://localhost:9998/helloworld/xml" dest="out.xml"/>
  </target>

  <target name="clean">
    <delete quiet="true" dir="${build.dir}"/>
  </target>
</project>

Make sure to set the value of "jersey.home" property correctly in this file. And now the JAXB bean and corresponding XML and JSON representation:

JAXB Bean XML representation JSON representation
@javax.xml.bind.annotation.XmlRootElement
public class alice {

  @javax.xml.bind.annotation.XmlValue
  protected String value;

  public alice() { this.value = "bob" }
  public String getValue() { return value; }
}

<alice>bob</alice>

{"alice":{"$":"bob"}}
@javax.xml.bind.annotation.XmlRootElement
public class alice {

  @javax.xml.bind.annotation.XmlElement
  protected String bob;

  @javax.xml.bind.annotation.XmlElement
  protected String david;

  public alice() {
    bob = "charlie";
    david = "edgar";
  }

  public String getBob() { return bob; }
  public String getDavid() { return david; }
}
<alice>
  <bob>charlie</bob>
  <david>edgar</david>
</alice>
{"alice":{"bob":{"$":"charlie"},"david":{"$":"edgar"}}}
@javax.xml.bind.annotation.XmlRootElement
public class alice {
  @javax.xml.bind.annotation.XmlValue
  protected String value;

  @javax.xml.bind.annotation.XmlAttribute
  protected String charlie;

  public alice() {
    value = "bob";
    charlie = "david";
  }

  public String getValue() { return value; }
  public String getCharlie() { return charlie; }
}
<alice charlie="david">
  bob
</alice>
{"alice":{"@charlie":"david","$":"bob"}}
@javax.xml.bind.annotation.XmlRootElement(namespace="http://some-namespace")
public class alice {
  @javax.xml.bind.annotation.XmlValue
  protected String value;

  public alice() { value = "bob"; }

  public String getValue() { return value; }
}
<alice xmlns="http://some
-namespace">
  bob
</alice>
{"alice":{"@xmlns":{"$":"http:\/\/some-namespace"},"$":"bob"}}
@javax.xml.bind.annotation.XmlRootElement
public class alice {
  @javax.xml.bind.annotation.XmlElement
  protected java.util.List<String> bob;

  public alice() {
    bob = new java.util.ArrayList<String>();
    bob.add("charlie");
    bob.add("david");
  }

  public java.util.List<String> getBob() { return bob; }
}
<alice>
  <bob>charlie</bob>
  <bob>david</bob>
</alice>
{"alice":{"bob":[{"$":"charlie"},{"$":"david"}]}}

JSON representation can always be constructed using the JSON APIs as shown below and by adding the method to "HelloWorldResource":

import org.codehaus.jettison.json.*;

@HttpMethod("GET")
@ProduceMime("application/json")
@UriTemplate("/json2")
public JSONObject getJSONMessage() throws JSONException {
  JSONObject object = new JSONObject();
  JSONObject content = new JSONObject();
  content.put("$", "bob");
  object.put("alice", content);

  return object;
}

JAX-WS also supports JSON as a pluggable encoding.

Please leave suggestions on other TOTD that you'd like to see. A complete archive is available here.

Technorati: totd jersey json jax-ws REST pluggableencoding restful

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070802 Thursday August 02, 2007

wsHttpDualBinding - a non-interoperable binding

Based upon a user request, I'll explain why wsDualHttpBinding (a system-provided binding in WCF) is not an interoperable binding. This blog entry will explain the service endpoint code, client code, generated WSDL and the SOAP messages exchanged based upon the DualHttp Binding Sample that is bundled with the Windows SDK samples. This is also an update to an earlier attempt to explain wsDualHttpBinding.

In the sample, I replaced the default wsDualHttpBinding with an equivalent custom binding (after removing the security) as:

<bindings>
  <customBinding>
    <binding name="Binding1">
      <reliableSession />
      <compositeDuplex />
      <oneWay />
      <textMessageEncoding
                     messageVersion="Soap12WSAddressing10" 
                     writeEncoding="utf-8" />
      <httpTransport authenticationScheme="Anonymous"
                     bypassProxyOnLocal="false"
                     hostNameComparisonMode="StrongWildcard"
                     proxyAuthenticationScheme="Anonymous"
                     realm=""
                     useDefaultWebProxy="true" />
    </binding>
  </customBinding>
</bindings>

The wsDualHttpBinding, also known as Composite Duplex or Full Duplex Binding, provides a bi-directional communication between Client and Endpoint. In a single direction communication, the client can invoke a set of operations on a service and this interface is referred as primary interface in Duplex binding. The set of operations that a service can invoke on the client is called as callback interface.

The sample in Windows SDK is a trivial calculator service where primitive Math operations are performed in a running session on the "primary" interface and results are returned on the "callback" interface.

Service Endpoint Code

Let's understand the service endpoint code first. The "primary" service endpoint interface looks like:

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples", 
                 SessionMode=SessionMode.Required,
                 CallbackContract=typeof(ICalculatorDuplexCallback))]
public interface ICalculatorDuplex
{
  [OperationContract(IsOneWay=true)]
  void Clear();
  [OperationContract(IsOneWay = true)]
  void AddTo(double n);

  ...
}

Three points to note in this code:

  • A duplex contract requires a session, because a context must be established to correlate the set of messages being sent between client and service. Even though this is specified using SessionMode=SessionMode.Required attribute but the default value of SessionMode=SessionMode.Allowed (equivalent of not specifying) will be sufficient as well. This is because all Duplex bindings in .NET maintain a transport session.

  • Callback interface is specified using CallbackContract attribute.

  • All the methods are declared as One-way operations otherwise the response can be returned on the transport back channel itself. The documentation on this particular binding is limited.

The "callback" interface is defined as:

public interface ICalculatorDuplexCallback
{
  [OperationContract(IsOneWay = true)]
  void Result(double result);

  ...
}

In order for a service endpoint to establish a connection with the "callback" interface on client, a CallbackChannel is obtained from the OperationContext in the implementation of the "primary" interface as:

public class CalculatorService : ICalculatorDuplex
{
  double result;
  ICalculatorDuplexCallback callback = null;

  public CalculatorService()
  {
    result = 0.0D;
    callback = OperationContext.Current.GetCallbackChannel<ICalculatorDuplexCallback>();
  }

Another variable is initialized to return the running result. The implementation of each method in the "primary" interface then invokes a method on the "callback" interface to return the running result as:

public void AddTo(double n)
{
  result += n;
  callback.Result(result);
}

Generated WSDL

Now let's look at the generated WSDL fragments. The policy assertion elements are:

<wsp:All>
  <wsrm:RMAssertion xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
    <wsrm:InactivityTimeout Milliseconds="600000" /> 
    <wsrm:AcknowledgementInterval Milliseconds="200" /> 
  </wsrm:RMAssertion>
  <cdp:CompositeDuplex xmlns:cdp="http://schemas.microsoft.com/net/2006/06/duplex" /> 
  <ow:OneWay xmlns:ow="http://schemas.microsoft.com/ws/2005/05/routing/policy" /> 
  <wsaw:UsingAddressing /> 
</wsp:All>

The wsrm:RMAssertion and wsaw:UsingAddressing elements are bound to a known namespace and their behavior is clearly documented. However the specification of cdp:CompositeDuplex and ow:OneWay elements are unclear at this time. This does not allow any WSDL-based interoperability whenever these elements are included.

All methods from the "primary" and the "callback" interface are generated in one wsdl:portType. The methods from the "primary" interface are generated as One-way operations. But methods from the "callback" interface are generated as Notification operation. For example, one of the methods from "callback" interface looks like:

<wsdl:operation msc:isInitiating="true" msc:isTerminating="false" name="Result">
  <wsdl:output
      wsaw:Action="http://Microsoft.ServiceModel.Samples/ICalculatorDuplex/Result"
      message="tns:ICalculatorDuplex_Result_OutputCallbackMessage"/>
</wsdl:operation>

JAX-WS, the core of Metro, supports only Request-Response and One-way operations. This is the second place where WSDL-based interoperability will not work with any JAX-WS-based WSDL import tool, such as wsimport. Moreover, the WSDL-to-Java mapping defined by the JAX-WS specification requires each wsdl:portType map to a single Java interface. This WSDL design pattern requires two interfaces to be generated from a single wsdl:portType.

There are some other elements in namespace prefix bound to "http://schemas.microsoft.com/ws/2005/12/wsdl/contract" and their purpose is also unclear. Rest of the WSDL is pretty straight-forward.

Client side code

On the client side, svcutil (WSDL importing tool for .NET 3.0) generates the "primary" and "callback" interface from the WSDL. The "callback" is implemented as:

public class CallbackHandler : ICalculatorDuplexCallback
{
  public void Result(double result)
  {
    Console.WriteLine("Result({0})", result);
  }

  public void Equation(string eqn)
  {
    Console.WriteLine("Equation({0})", eqn);
  }
}

This client instance is initialized with the callback implementation as:

class Client
{
  static void Main()
  {
    // Construct InstanceContext to handle messages on callback interface
    InstanceContext instanceContext = new InstanceContext(new CallbackHandler());

    // Create a client with given client endpoint configuration
    CalculatorDuplexClient client = new CalculatorDuplexClient(instanceContext);

And then the client invokes the service endpoint normally as shown below:

// Call the AddTo service operation.
double value = 100.00D;
client.AddTo(value);

...

SOAP messages

Lets look at the SOAP messages exchanged between client and endpoint now. The first call from the client to an endpoint triggers a protocol handshake for establishing a session. The CreateSequence protocol message looks like:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequence</a:Action>
    <a:ReplyTo>
      <a:Address>http://iamfine.sfbay.sun.com/Temporary_Listen_Addresses/bfd8c103-b0f9-4c65-9cb6-fbebb7d1517b/4e0cdb31-2451-4fb6-84b8-dc286e5f26c8</a:Address>
    </a:ReplyTo>
    <a:MessageID>urn:uuid:51918652-9a78-4ba3-82f5-e68ecd664d42</a:MessageID>
    <a:To s:mustUnderstand="1">http://localhost:8888/</a:To>
  </s:Header>
  <s:Body>
    <CreateSequence xmlns="http://schemas.xmlsoap.org/ws/2005/02/rm">
      <AcksTo>
        <a:Address>http://iamfine.sfbay.sun.com/Temporary_Listen_Addresses/bfd8c103-b0f9-4c65-9cb6-fbebb7d1517b/4e0cdb31-2451-4fb6-84b8-dc286e5f26c8</a:Address>
      </AcksTo>
      <Offer>
        <Identifier>urn:uuid:b1116e69-f1dd-45b0-8495-129645038160</Identifier>
      </Offer>
    </CreateSequence>
  </s:Body>
</s:Envelope>

The WCF runtime uses the Windows HTTP.SYS library to host an endpoint at the address specified in a:ReplyTo. This address is used for all subsequent messages sent on the callback channel. This message is used to create a session for the "primary" interface. The message also carries an offer, in the SOAP Body, to create a "callback" interface session.

The CreateSequenceResponse protocol message returns "primary" interface session identifier and also accepts the offered "callback" session. The message looks like:

<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://schemas.xmlsoap.org/ws/2005/02/rm/CreateSequenceResponse</a:Action>
    <a:RelatesTo>urn:uuid:51918652-9a78-4ba3-82f5-e68ecd664d42</a:RelatesTo>
    <a:To s:mustUnderstand="1">http://iamfine.sfbay.sun.com/Temporary_Listen_Addresses/bfd8c103-b0f9-4c65-9cb6-fbebb7d1517b/4e0cdb31-2451-4fb6-84b8-dc286e5f26c8</a:To>
  </s:Header>
  <s:Body>
    <CreateSequenceResponse xmlns="http://schemas.xmlsoap.org/ws/2005/02/rm">
      <Identifier>urn:uuid:d483898c-4bd3-4077-ba04-07a9010ab27f</Identifier>
      <Accept>
        <AcksTo>
          <a:Address>http://localhost:8888/</a:Address>
        </AcksTo>
      </Accept>
    </CreateSequenceResponse>
  </s:Body>
</s:Envelope>

Now, because of the way each method is implemented (invoking callback.Result(result) method at the end of each "primary" operation), a response to a request received by an endpoint is returned over the callback channel. This happens under-the-cover even though all messages in the "primary" interface are defined as One-way operations.

The behavior is quite analogous to a Request-Response operation primitive. I wonder what are the usecases of wsDualHttpBinding ?

Summary

Finally, I summarize the reasons that makes wsDualHttpBinding a non-interoperable binding:

  1. The specifications of cdp:CompositeDuplex and ow:OneWay are not available and these elements will thus be ignored by the Metro WSDL importing tool.

  2. The operations from "callback" interface are mapped as Notification operation in the WSDL. This operation primitive is not supported by Metro.

  3. On the service endpoint, all the operations from "primary" and "callback" interface are mapped to a single wsdl:portType. On the client side, wsdl:portType is mapped to separate "primary" and "callback" interfaces. The Java-to-WSDL mapping defined by the JAX-WS specification allows one-to-one mapping between Java interface and wsdl:portType.

Technorati: webservices interoperability wcf metro jax-ws wsit

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070722 Sunday July 22, 2007

Metro on Tomcat 6.x

Rama described how to run JAX-WS samples with Tomcat 6.x. JAX-WS is part of Metro - the Web services stack in GlassFish. Another key component of Metro is WSIT (aka Project Tango) that provides Secure, Reliable, Transactional and Interoperable Web service. Read more about Project Tango in this 26-page article.

A stable version of Metro is integrated in GlassFish V2 and the latest nightlies of stand-alone bundle are also available. The stand-alone bundle comes with an install scipt (wsit-on-tomcat.xml) that allows it install on Tomcat 5.x. I followed the steps in Rama's blog to install Metro on Tomcat 6.x. But first, a little bit of explanation and then the actual code fragments.

Tomcat's classloading mechanism has changed slightly between 5.x and 6.x. The first change is that Tomcat 5.x used to have shared/lib directory to share classes across all web applications. This directory in turn used to be specified as value of shared.loader property in  conf/catalina.properties. In Tomcat 6.x, the property still exists but it's value is set to nothing and shared/lib directory no longer exists in the default installation. I see the motivation behind this change as it keeps the Tomcat installation directory clean and any shared resources can still be specified in conf/catalina.properties. But this means that wsit-on-tomcat.xml script, that copies the files in shared/lib directory, will work on Tomcat 5.x only. In order for this script to work on Tomcat 6.x, the value of shared.loader property need to be changed to include Metro jars.

Now, the code fragments! The value of shared.loader property in Tomcat 5.x is:

shared.loader=${catalina.base}/shared/classes,${catalina.base}/shared/lib/*.jar

And in Tomcat 6.x is the value of this property is:

shared.loader=

If Metro is installed in c:\metro then changing its value to:

shared.loader=file:///c:/metro/lib/*.jar

will enable Tomcat 6.x to host Secure, Reliable, Transactional and .NET 3.0-Interoperable Web services. And this mechanism will work for Tomcat 5.x too, so changing the value of this property in Tomcat 5.x installation to:

shared.loader=${catalina.base}/shared/classes,${catalina.base}/shared/lib/*.jar,file:///c:/metro/lib/*.jar

instead of copying the files in shared/lib will be sufficient as well.

The second change in Tomcat's classloading mechanism is required if you are using Java SE 6. Tomcat 5.x used to have common/endorsed directory which no longer exists in Tomcat 6.x. Java SE 6 is bundled with JAX-WS 2.0 and Metro needs JAX-WS 2.1. So if you are using Java SE 6 then copy webservices-api.jar in c:/jdk6/jre/lib/endorsed directory. Read Endorsed Directory Mechanism for more details.

Several screencasts are available that show how to develop Secure, Reliable and Transactional and Interoperable Web service. All the screencasts use NetBeans IDE but if you are more of a command-line user then follow this entry that shows how to develop a reliable endpoint and invoke it from WCF and vice versa.

Technorati: metro webservices wsit jax-ws glassfish tomcat

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070713 Friday July 13, 2007

users@metro = users@wsit + users@jax-ws

Metro - the Web services stack in GlassFish - was announced recently. It was basically creating a single entity for two related projects - JAX-WS RI and Project Tango. The next logical step is to create a single place where users can ask questions and search for already existing answers. Here are some of the changes Koshuke made in that direction:

We are working on consolidating the JAX-WS and JAXB and WSIT forums as well.

Technorati: metro webservices wsit jax-ws glassfish

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070629 Friday June 29, 2007

Screencast #WS6: Eclipse Europa and GlassFish

Eclipse 3.3 (codename Europa) was released earlier today. As mentioned earlier, we have an exciting news for GlassFish developers!

Starting today, Eclipse IDE for Java EE developers has the capability to register GlassFish V1, V2 and V3 containers from within the IDE. It supports web application directory deployment and has a fully integrated debugger.  Ludo published detail instructions on how to configure Eclipse 3.3 for GlassFish, deploy a Web project and debug a JSP. You can also watch the same steps in this screen cast with an additional detail on how to deploy a JAX-WS compliant Web service on GlassFish using Eclipse IDE.

Enjoy it here!



Technorati: eclipse europa glassfish webservices jax-ws screencast

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070619 Tuesday June 19, 2007

Announcing Metro - Naming the Web Services stack in GlassFish

The GlassFish V2 Web services stack consists of JAX-WS as the core platform and Project Tango (aka Web Services Interoperability Technology, WSIT) as an implementation of key WS-* specifications on top of it. This stack, so far referred as "JAX-WS RI + Project Tango", now has a new name - Project Metro.

Why name Project Metro ? - JAX-WS, the core platform, uses Tube as a basic processing unit that represents SOAP-level protocol handling code such as MustUnderstand and WS-Addressing processing. Multiple tubes are put together in a sequential fashion to complete the SOAP message handling. Project Tango uses this extensible architecture to implement they key WS-* specs, such as Reliable Messaging and Atomic Transactions, as Tubes as well. Effectively, all your SOAP messages are moved from one point (client) to another (endpoint), potentially spanning intermediaries, through Tubes. This is a direct correlation to Metro (aka Rapid Transport) that exists all over the world.

What is Metro ? - A picture is worth a thousand words - this shows all the components of Metro.

The two main components of Metro are:

  • JAX-WS - The Core Web services platform
  • WSIT - Implementation of key WS-* specs and interoperability with .NET 3.0

The Core Web services that provides all the SOAP message functionality, including WS-Addressing and MTOM, is available from JAX-WS. Project Tango implements Security, Reliability and Transactions on this Core layer that interoperate with Windows Communication Foundation. All the applications on Metro can be easily developed using NetBeans 5.5.1 and deployed on GlassFish V2.

How does Metro provide interoperability with .NET 3.0 ? - Metro provides a complete Web services solution for both homogeneous and heterogeneous architectures. For any Web service, there is a Client that invokes an Endpoint. The Endpoint advertises the metadata which the Client uses to bootstrap communication with the Endpoint. This metadata indicates which of the capabilities - security, reliability and transactions - are supported at the Endpoint. For a Metro Client or Endpoint, NetBeans IDE 5.5.1 or later takes care of processing all the details.

 

The figure shows a pair of Client and Endpoint - one using the Metro Web services stack and the other using .NET 3.0. The Metro Client and Endpoint can be deployed on any of the GlassFish V2 supported platforms (Solaris Sparc, Solaris X86, Windows, Linux and MacOS). The .NET 3.0 Client and Endpoint can be deployed on any of the .NET 3.0 supported platforms (Windows Vista, Windows 2003 Server and Windows XP + SP2).

For a homogeneous architecture, where both Client and Endpoint are using Metro, the arrow labeled 1 shows a Metro Client invoking a Metro Endpoint. If this serves your purpose, then all you need is GlassFish V2 for WSIT runtime, NetBeans IDE for tooling and WSIT tutorial.

For a heterogeneous architecture, where only one of Client or Endpoint is using Metro and the other is based on .NET 3.0, the arrow labeled 2 and 3 shows a Metro client can invoke a .NET 3.0 endpoint and a .NET 3.0 client can invoke a Metro endpoint respectively. This use case has been extensively tested as well by participating in multiple plug-fests with Microsoft.

What is the change ? - The biggest change you'll notice is a unified single name for what was called "GlassFish Web services stack" or "JAX-WS RI + Tango" so far. This is only a consolidation of our multiple offerings and is backed up high quality, high-performance and production-ready Web services stack integrated in GlassFish V2. This stack is also tested on Tomcat and has been reported to run on Jetty and JavaSE as well.

Metro Binary 1.0 M5, aligned with Tango Milestone 5, already integrated in GlassFish V2 b50, is available for download. The JAX-WS and Tango binaries and documentation are still available for download but will be aligned with Metro over time.


Discover Metro

Use Metro

Extend Metro

Technorati: webservices glassfish metro wsit jax-ws

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070618 Monday June 18, 2007

Tango on JavaSE 6

Fabian explained how WSIT features can be configured on Java SE 6 Endpoint API exposed as part of JAX-WS 2.1. In this blog, I start with a Reliable Messaging-enabled endpoint developed using NetBeans IDE 5.5.1 and WSIT plug-in and then provide detailed steps, along with code, to deploy it in Java SE 6.

  1. Create a Reliable Web service endpoint using WSIT plug-in and NetBeans 5.5.1 by watching this screencast.
  2. Download and install WSIT Milestone 5. Copy webservices-api.jar in Java SE 6 'jre\lib\endorsed' directory.
  3. All the capabilities enabled at an endpoint, such as Reliable Messaging for this one, are stored in the WSIT configuration file. In NetBeans IDE, expand your Project, 'Web Pages', 'WEB-INF'. The configuration file be named something similar to 'wsit-server.HelloWebService.xml' following the format 'wsit-<packageName>.<ServiceName>.xml'. Here is how the config file looks like:
    	
    <?xml version="1.0" encoding="UTF-8"?> <definitions
    xmlns="http://schemas.xmlsoap.org/wsdl/"
    xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" name="HelloWebServiceService" targetNamespace="http://server/" xmlns:tns="http://server/" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:wsaws="http://www.w3.org/2005/08/addressing" xmlns:wsrm="http://schemas.xmlsoap.org/ws/2005/02/rm/policy">
    <message name="sayHello"/>
    <message name="sayHelloResponse"/>
    <portType name="HelloWebService">
    <wsdl:operation name="sayHello">
    <wsdl:input message="tns:sayHello"/>
    <wsdl:output message="tns:sayHelloResponse"/>
    </wsdl:operation>
    </portType>
    <binding name="HelloWebServicePortBinding" type="tns:HelloWebService">
    <wsp:PolicyReference URI="#HelloWebServicePortBindingPolicy"/>
    <wsdl:operation name="sayHello">
    <wsdl:input/>
    <wsdl:output/>
    </wsdl:operation>
    </binding>
    <service name="HelloWebServiceService">
    <wsdl:port name="HelloWebServicePort" binding="tns:HelloWebServicePortBinding"/>
    </service>
    <wsp:Policy wsu:Id="HelloWebServicePortBindingPolicy">
    <wsp:ExactlyOne>
    <wsp:All>
    <wsaws:UsingAddressing xmlns:wsaws="http://www.w3.org/2006/05/addressing/wsdl"/>
    <wsrm:RMAssertion/>
    </wsp:All>
    </wsp:ExactlyOne>
    </wsp:Policy>
    </definitions>
    Copy this config file by the name wsit-server.HelloWebService.xml in META-INF directory in your classpath.
  4. The Web service implementation class looks like:
    package server;

    import javax.jws.*;

    @WebService(targetNamespace="http://server/")
    public class HelloWebService {
        @WebMethod
        public String hello(@WebParam(name="name")String text) {
            return "Hello " + text;
        }
    }
    As you see, this is a plain JAX-WS Web service endpoint class.
  5. The JAX-WS Endpoint code that starts the Web service endpoint looks like:
    package server;
    
    import java.io.IOException;
    import javax.xml.ws.Endpoint;
    
    public class Main {
    
       private static final int PORT = 58888;
       private static final String HOST = "localhost";
    
       public static void main(String[] args) {
            Endpoint endpoint = Endpoint.create(new HelloWebService());
            String address = "http://" + HOST + ":" + PORT + "/";
            endpoint.publish(address);
            System.out.println("Endpoint hosted at ... " + address);
       }
    }
    
  6. The sequence of commands to deploy the endpoint is:
    "\Program Files\Java\jdk1.6.0_01\bin\javac.exe" -d . server\*.java
    "\Program Files\Java\jdk1.6.0_01\bin\wsgen.exe" -cp . server.HelloWebService
    java -classpath .;\jax-ws-latest-wsit\lib\webservices-rt.jar server.Main
  7. And then you see the following output on the command prompt:
    java -classpath .;C:\testbed\jax-ws-latest-wsit\lib\webservices-rt.jar server.Main
    Jun 18, 2007 4:46:34 PM [com.sun.xml.ws.policy.jaxws.PolicyConfigParser] parse
    INFO: WSP1049: Loaded WSIT configuration from file:
    file:/C:/workarea/wsit/javase6/META-INF/wsit-server.HelloWebService.xml
    Jun 18, 2007 4:46:34 PM [com.sun.xml.ws.tx.common.TxMapUpdateProvider] update
    INFO: WSTX-COMMON-2005: running in a non Java EE container; disable mapping of Container Managed Transaction EJB to WS-AT Policy assertions due to 'javax/ejb/TransactionManagement'
    Endpoint hosted at ... http://localhost:58888/

That's it, the endpoint now deployed at 'http://localhost:58888/MyService?wsdl' is Reliable Messaging enabled. This endpoint can be invoked using any of the methods shown here.

Technorati: webservices wsit jax-ws glassfish javase6

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070513 Sunday May 13, 2007

Salesforce is now JAX-WS enabled!

29,800 customers and 646,000 subscribers of salesforce.com - they can now use fast and furious JAX-WS tools and runtime to access and interact with their applications programmatically. The JAX-WS team at Sun has worked closely with Salesforce team to create QuickStart, Enterprise and Partners (to be hosted soon) bundles using JAX-WS 2.1.1. Each bundle is

  • Self-contained, with all pre-generated client-side artifacts and JAX-WS libraries required to invoke a standard (quickstart, enterprise and partner) WSDL
  • Scripts to invoke the endpoint in the main directory
  • Instructions (in etc directory) on how to re-generate your artifacts if you have a custom WSDL using
    • Scripts in the bin directory
    • A template build.xml (in etc directory) for Ant scripts

salesforce.com processes more API transactions than it does Web browser / UI requests and JAX-WS bundles are very well equipped to handle that. This is the same JAX-WS that is also available in GlassFish v2.

Use these bundles and let us know your feedback.

Read more details here.

Technorati: jaxws webservices salesforce glassfish

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070428 Saturday April 28, 2007

Sun Web Services @ JavaOne 2007

Follow up post from here.

Here is a complete list of Sun Web services technical sessions/birds-of-feather sessions, including date and time, at JavaOne 2007:

Monday May 7, 2007
 10:30am-7:30pm   GlassFish Day
Tuesday May 8, 2007
 6:00pm-7:00pm TS-6411 JSR 311: The Java API for RESTful Web Services
 8:00pm-8:50pm BOF-8034 Extending and Embedding the Java API for XML Web Services (JAX-WS) 2.1 Reference Implementation
Wednesday May 9, 2007
 3:50pm-5:20pm LAB-3350 Make Java Technology and .NET 3.0 Interoperability Work With WSIT
 4:10pm-5:10pm TS-4865 Takes two to Tango: Java Web Services and .NET Interoperability
 7:55pm-8:45pm BOF-6412 Describing RESTful Applications: WADLing with Java
 8:55pm-9:45pm BOF-4612 Java Platform, Enterprise Edition (Java EE): Meet the Experts (Part 2)
Thursday May 10, 2007
 9:35am-11:35am LAB-5410 Using Identity to Secure Web Services
 10:55am-11:55am TS-8897 Designing Service Collaborations: The Design of "Wire"-Centric Integration
 2:50pm-3:50pm TS-4948 Unleashing the Power of JAX-WS RI: Spring, Stateful Web Services, SMTP, and More
 5:30pm-6:30pm TS-8840 Services Interoperability with Java Technology and .NET: Technologies and Tools for Web 2.0
 7:55pm-8:45pm BOF-4108 Reliable, Transacted, and Secure Web Services Between Java and .NET, Using WSIT
Friday May 11, 2007
1:30pm-2:20pm TS-4865 Takes two to Tango: Java Web Services and .NET Interoperability

Note, TS-4865 is a repeat session.

Technorati: Javaone WSIT JAX-WS JAXWS presos

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070405 Thursday April 05, 2007

JAX-WS in Glassfish - way to go

Redirecting you to Joe Ottinger's (editor of The Server Side) blog.

Technorati: jax-ws glassfish webservices

del.icio.us | furl | simpy | slashdot | technorati | digg |
|
Main | Next page »

Valid HTML! Valid CSS!

This is a personal weblog, I do not speak for my employer.