Chapter 31. Publishing a Service

Abstract

When you want to deploy a JAX-WS service as a standalone Java application, you must explicitly implement the code that publishes the service provider.

31.1. When to Publish a Service

Apache CXF provides a number of ways to publish a service as a service provider. How you publish a service depends on the deployment environment you are using. Many of the containers supported by Apache CXF do not require writing logic for publishing endpoints. There are two exceptions:

  • deploying a server as a standalone Java application
  • deploying a server into an OSGi container without Blueprint

For detailed information in deploying applications into the supported containers see Part IV, “Configuring Web Service Endpoints”.

31.2. APIs Used to Publish a Service

Overview

The javax.xml.ws.Enddpoint class does the work of publishing a JAX-WS service provider. To publishing an endpoint do the following:

  1. Create an Endpoint object for your service provider.
  2. Publish the endpoint.
  3. Stop the endpoint when application shuts down.

The Endpoint class provides methods for creating and publishing service providers. It also provides a method that can create and publish a service provider in a single method call.

Instantiating an service provider

A service provider is instantiated using an Endpoint object. You instantiate an Endpoint object for your service provider using one of the following methods:

  • staticEndpointcreateObjectimplementor This create() method returns an Endpoint for the specified service implementation. The Endpoint object is created using the information provided by the implementation class' javax.xml.ws.BindingType annotation, if it is present. If the annotation is not present, the Endpoint uses a default SOAP 1.1/HTTP binding.
  • staticEndpointcreateURIbindingIDObjectimplementor This create() method returns an Endpoint object for the specified implementation object using the specified binding. This method overrides the binding information provided by the javax.xml.ws.BindingType annotation, if it is present. If the bindingID cannot be resolved, or it is null, the binding specified in the javax.xml.ws.BindingType is used to create the Endpoint. If neither the bindingID or the javax.xml.ws.BindingType can be used, the Endpoint is created using a default SOAP 1.1/HTTP binding.
  • staticEndpointpublishStringaddressObjectimplementor The publish() method creates an Endpoint object for the specified implementation, and publishes it. The binding used for the Endpoint object is determined by the URL scheme of the provided address. The list of bindings available to the implementation are scanned for a binding that supports the URL scheme. If one is found the Endpoint object is created and published. If one is not found, the method fails.

    Using publish() is the same as invoking one of the create() methods, and then invoking the publish() method used in ???TITLE???.

Important

The implementation object passed to any of the Endpoint creation methods must either be an instance of a class annotated with javax.jws.WebService and meeting the requirements for being an SEI implementation or it must be an instance of a class annotated with javax.xml.ws.WebServiceProvider and implementing the Provider interface.

Publishing a service provider

You can publish a service provider using either of the following Endpoint methods:

  • publishStringaddress This publish() method publishes the service provider at the address specified.

    Important

    The address's URL scheme must be compatible with one of the service provider’s bindings.

  • publishObjectserverContext This publish() method publishes the service provider based on the information provided in the specified server context. The server context must define an address for the endpoint, and the context must also be compatible with one of the service provider’s available bindings.

Stopping a published service provider

When the service provider is no longer needed you should stop it using its stop() method. The stop() method, shown in Example 31.1, “Method for Stopping a Published Endpoint”, shuts down the endpoint and cleans up any resources it is using.

Example 31.1. Method for Stopping a Published Endpoint

stop

Important

Once the endpoint is stopped it cannot be republished.

31.3. Publishing a Service in a Plain Java Application

Overview

When you want to deploy your application as a plain java application you need to implement the logic for publishing your endpoints in the application’s main() method. Apache CXF provides you two options for writing your application’s main() method.

  • use the main() method generated by the wsdl2java tool
  • write a custom main() method that publishes the endpoints

Generating a Server Mainline

The code generators -server flag makes the tool generate a simple server mainline. The generated server mainline, as shown in Example 31.2, “Generated Server Mainline”, publishes one service provider for each port element in the specified WSDL contract.

For more information see Section 44.2, “cxf-codegen-plugin”.

Example 31.2, “Generated Server Mainline” shows a generated server mainline.

Example 31.2. Generated Server Mainline

package org.apache.hello_world_soap_http;

import javax.xml.ws.Endpoint;

public class GreeterServer {

    protected GreeterServer() throws Exception {
        System.out.println("Starting Server");
        Object implementor = new GreeterImpl();
        String address = "http://localhost:9000/SoapContext/SoapPort";
        Endpoint.publish(address, implementor);
    }

    public static void main(String args[]) throws Exception {
        new GreeterServer();
        System.out.println("Server ready...");

        Thread.sleep(5 * 60 * 1000);
        System.out.println("Server exiting");
        System.exit(0);
    }
}

The code in Example 31.2, “Generated Server Mainline” does the following:

Instantiates a copy of the service implementation object.

Creates the address for the endpoint based on the contents of the address child of the wsdl:port element in the endpoint’s contract.

Publishes the endpoint.

Writing a Server Mainline

If you used the Java first development model or you do not want to use the generated server mainline you can write your own. To write your server mainline you must do the following:

  1. the section called “Instantiating an service provider” an javax.xml.ws.Endpoint object for the service provider.
  2. Create an optional server context to use when publishing the service provider.
  3. the section called “Publishing a service provider” the service provider using one of the publish() methods.
  4. Stop the service provider when the application is ready to exit.

Example 31.3, “Custom Server Mainline” shows the code for publishing a service provider.

Example 31.3. Custom Server Mainline

package org.apache.hello_world_soap_http;

import javax.xml.ws.Endpoint;

public class GreeterServer
{
  protected GreeterServer() throws Exception
  {
  }

  public static void main(String args[]) throws Exception
  {
    GreeterImpl impl = new GreeterImpl();
    Endpoint endpt.create(impl);
    endpt.publish("http://localhost:9000/SoapContext/SoapPort");

    boolean done = false;
   while(!done)
    {
      ...
    }

   endpt.stop();
    System.exit(0);
  }
}

The code in Example 31.3, “Custom Server Mainline” does the following:

Instantiates a copy of the service’s implementation object.

Creates an unpublished Endpoint for the service implementation.

Publishes the service provider at http://localhost:9000/SoapContext/SoapPort.

Loops until the server should be shutdown.

Stops the published endpoint.

31.4. Publishing a Service in an OSGi Container

Overview

When you develop an application that will be deployed into an OSGi container, you need to coordinate the publishing and stopping of your endpoints with the life-cycle of the bundle in which it is packaged. You want your endpoints published when the bundle is started and you want the endpoints stopped when the bundle is stopped.

You tie your endpoints life-cycle to the bundle’s life-cycle by implementing an OSGi bundle activator. A bundle activator is used by the OSGi container to create the resource for a bundle when it is started. The container also uses the bundle activator to clean up the bundles resources when it is stopped.

The bundle activator interface

You create a bundle activator for your application by implementing the org.osgi.framework.BundleActivator interface. The BundleActivator interface, shown in Example 31.4, “Bundle Activator Interface”, it has two methods that need to be implemented.

Example 31.4. Bundle Activator Interface

interface BundleActivator
{
  public void start(BundleContext context)
  throws java.lang.Exception;

  public void stop(BundleContext context)
  throws java.lang.Exception;
}

The start() method is called by the container when it starts the bundle. This is where you instantiate and publish the endpoints.

The stop() method is called by the container when it stops the bundle. This is where you would stop the endpoints.

Implementing the start method

The bundle activator’s start method is where you publish your endpoints. To publish your endpoints the start method must do the following:

  1. the section called “Instantiating an service provider” an javax.xml.ws.Endpoint object for the service provider.
  2. Create an optional server context to use when publishing the service provider.
  3. the section called “Publishing a service provider” the service provider using one of the publish() methods.

Example 31.5, “Bundle Activator Start Method for Publishing an Endpoint” shows code for publishing a service provider.

Example 31.5. Bundle Activator Start Method for Publishing an Endpoint

package com.widgetvendor.osgi;

import javax.xml.ws.Endpoint;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class widgetActivator implements BundleActivator
{
  private Endpoint endpt;
  ...

  public void start(BundleContext context)
  {
    WidgetOrderImpl impl = new WidgetOrderImpl();
    endpt = Endpoint.create(impl);
    endpt.publish("http://localhost:9000/SoapContext/SoapPort");
  }

  ...

}

The code in Example 31.5, “Bundle Activator Start Method for Publishing an Endpoint” does the following:

Instantiates a copy of the service’s implementation object.

Creates an unpublished Endpoint for the service implementation.

Publish the service provider at http://localhost:9000/SoapContext/SoapPort.

Implementing the stop method

The bundle activator’s stop method is where you clean up the resources used by your application. Its implementation should include logic for stopping all of the endpoint’s published by the application.

Example 31.6, “Bundle Activator Stop Method for Stopping an Endpoint” shows a stop method for stopping a published endpoint.

Example 31.6. Bundle Activator Stop Method for Stopping an Endpoint

package com.widgetvendor.osgi;

import javax.xml.ws.Endpoint;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;

public class widgetActivator implements BundleActivator
{
  private Endpoint endpt;
  ...

  public void stop(BundleContext context)
  {
    endpt.stop();
  }

  ...

}

Informing the container

You must add inform the container that the application’s bundle includes a bundle activator. You do this by adding the Bundle-Activator property to the bundle’s manifest. This property tells the container which class in the bundle to use when activating the bundle. Its value is the fully qualified name of the class implementing the bundle activator.

Example 31.7, “Bundle Activator Manifest Entry” shows a manifest entry for a bundle whose activator is implemented by the class com.widgetvendor.osgi.widgetActivator.

Example 31.7. Bundle Activator Manifest Entry

Bundle-Activator: com.widgetvendor.osgi.widgetActivator