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:
-
Create an
Endpoint
object for your service provider. - Publish the endpoint.
- 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:
-
static
Endpoint
create
Object
implementor
Thiscreate()
method returns anEndpoint
for the specified service implementation. TheEndpoint
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, theEndpoint
uses a default SOAP 1.1/HTTP binding. -
static
Endpoint
create
URI
bindingID
Object
implementor
Thiscreate()
method returns anEndpoint
object for the specified implementation object using the specified binding. This method overrides the binding information provided by thejavax.xml.ws.BindingType
annotation, if it is present. If thebindingID
cannot be resolved, or it isnull
, the binding specified in thejavax.xml.ws.BindingType
is used to create theEndpoint
. If neither thebindingID
or thejavax.xml.ws.BindingType
can be used, theEndpoint
is created using a default SOAP 1.1/HTTP binding. static
Endpoint
publish
String
address
Object
implementor
Thepublish()
method creates anEndpoint
object for the specified implementation, and publishes it. The binding used for theEndpoint
object is determined by the URL scheme of the providedaddress
. The list of bindings available to the implementation are scanned for a binding that supports the URL scheme. If one is found theEndpoint
object is created and published. If one is not found, the method fails.Using
publish()
is the same as invoking one of thecreate()
methods, and then invoking thepublish()
method used in ???TITLE???.
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:
publish
String
address
Thispublish()
method publishes the service provider at the address specified.ImportantThe
address
's URL scheme must be compatible with one of the service provider’s bindings.-
publish
Object
serverContext
Thispublish()
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
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 thewsdl2java
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:
-
the section called “Instantiating an service provider” an
javax.xml.ws.Endpoint
object for the service provider. - Create an optional server context to use when publishing the service provider.
-
the section called “Publishing a service provider” the service provider using one of the
publish()
methods. - 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:
-
the section called “Instantiating an service provider” an
javax.xml.ws.Endpoint
object for the service provider. - Create an optional server context to use when publishing the service provider.
-
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