[[SOAP_over_Jakarta_Messaging]]
= SOAP over Jakarta Messaging

JBoss Web Services allows communication over the _Jakarta Messaging_ transport. The
functionality comes from Apache CXF support for the
http://www.w3.org/TR/soapjms/[SOAP over Java Message Service 1.0]
specification, which is aimed at a set of standards for interoperable
transport of _SOAP_ messages over _Jakarta Messaging_.

On top of Apache CXF functionalities, the JBossWS integration allows
users to deploy WS archives containing both _Jakarta Messaging_ and _HTTP_ endpoints
the same way as they do for basic _HTTP_ WS endpoints (in _war_
archives). The webservices layer of WildFly takes care of looking for
_Jakarta Messaging_ enpdoints in the deployed archive and starts them delegating to
the Apache CXF core similarly as with _HTTP_ endpoints.

[[configuring-soap-over-Jakarta-Messaging]]
== Configuring SOAP over Jakarta Messaging

As per specification, the _SOAP over Jakarta Messaging_ transport configuration is
controlled by proper elements and attributes in the `binding` and
`service` elements of the WSDL contract. So a _Jakarta Messaging_ endpoint is usually
developed using a contract-first approach.

The http://cxf.apache.org/docs/soap-over-jms-10-support.html[Apache CXF
documentation] covers all the details of the supported configurations.
The minimum configuration implies:

* setting a proper Jakarta Messaging URI in the `soap:address` `location` [1]
* providing a JNDI connection factory name to be used for connecting to
the queues [2]
* setting the transport binding [3]

[source,xml,options="nowrap"]
----
<wsdl:definitions name="HelloWorldService" targetNamespace="http://org.jboss.ws/jaxws/cxf/jms"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:tns="http://org.jboss.ws/jaxws/cxf/jms"
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:soapjms="http://www.w3.org/2010/soapjms/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
...
 
<wsdl:binding name="HelloWorldServiceSoapBinding" type="tns:HelloWorld">
  <soap:binding style="document" transport="http://www.w3.org/2010/soapjms/"/> <!-- 3 -->
  <wsdl:operation name="echo">
    <soap:operation soapAction="" style="document"/>
    <wsdl:input name="echo">
      <soap:body use="literal"/>
    </wsdl:input>
    <wsdl:output name="echoResponse">
      <soap:body use="literal"/>
    </wsdl:output>
  </wsdl:operation>
</wsdl:binding>
<wsdl:service name="HelloWorldService">
  <soapjms:jndiConnectionFactoryName>java:/ConnectionFactory</soapjms:jndiConnectionFactoryName> <!-- 2 -->
  <wsdl:port binding="tns:HelloWorldServiceSoapBinding" name="HelloWorldImplPort">
    <soap:address location="jms:queue:testQueue"/> <!-- 1 -->
  </wsdl:port>
</wsdl:service>
----

Apache CXF takes care of setting up the Jakarta Messaging transport for endpoint
implementations whose `@WebService` annotation points to a port declared
for Jakarta Messaging transport as explained above.

[NOTE]

JBossWS currently supports POJO endpoints only for Jakarta Messaging transport use.
The endpoint classes can be deployed as part of _jar_ or _war_ archives.

The _web.xml_ descriptor in _war_ archives doesn't need any entry for
Jakarta Messaging endpoints.

[[examples-soap-over-jms]]
== Examples

[[Jakarta-Messaging-endpoint-only-deployment]]
=== Jakarta Messaging endpoint only deployment

In this example we create a simple endpoint relying on _SOAP over Jakarta Messaging_
and deploy it as part of a jar archive.

The endpoint is created using wsconsume tool from a WSDL contract such
as:

[source,xml,options="nowrap"]
----
<?xml version='1.0' encoding='UTF-8'?>
<wsdl:definitions name="HelloWorldService" targetNamespace="http://org.jboss.ws/jaxws/cxf/jms"
  xmlns:ns1="http://schemas.xmlsoap.org/soap/http"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:tns="http://org.jboss.ws/jaxws/cxf/jms"
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:soapjms="http://www.w3.org/2010/soapjms/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
<xs:schema elementFormDefault="unqualified" targetNamespace="http://org.jboss.ws/jaxws/cxf/jms" version="1.0" xmlns:tns="http://org.jboss.ws/jaxws/cxf/jms" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="echo" type="tns:echo"/>
<xs:element name="echoResponse" type="tns:echoResponse"/>
<xs:complexType name="echo">
    <xs:sequence>
      <xs:element minOccurs="0" name="arg0" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
<xs:complexType name="echoResponse">
    <xs:sequence>
      <xs:element minOccurs="0" name="return" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>
  </wsdl:types>
  <wsdl:message name="echoResponse">
    <wsdl:part element="tns:echoResponse" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="echo">
    <wsdl:part element="tns:echo" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="HelloWorld">
    <wsdl:operation name="echo">
      <wsdl:input message="tns:echo" name="echo">
    </wsdl:input>
      <wsdl:output message="tns:echoResponse" name="echoResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="HelloWorldServiceSoapBinding" type="tns:HelloWorld">
    <soap:binding style="document" transport="http://www.w3.org/2010/soapjms/"/>
    <wsdl:operation name="echo">
      <soap:operation soapAction="" style="document"/>
      <wsdl:input name="echo">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="echoResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="HelloWorldService">
    <soapjms:jndiConnectionFactoryName>java:jms/RemoteConnectionFactory</soapjms:jndiConnectionFactoryName>
    <soapjms:jndiInitialContextFactory>org.jboss.naming.remote.client.InitialContextFactory</soapjms:jndiInitialContextFactory>
    <soapjms:jndiURL>http-remoting://myhost:8080</soapjms:jndiURL>
    <wsdl:port binding="tns:HelloWorldServiceSoapBinding" name="HelloWorldImplPort">
      <soap:address location="jms:queue:testQueue"/>
    </wsdl:port>
  </wsdl:service>
  <wsdl:service name="HelloWorldServiceLocal">
    <soapjms:jndiConnectionFactoryName>java:/ConnectionFactory</soapjms:jndiConnectionFactoryName>
    <wsdl:port binding="tns:HelloWorldServiceSoapBinding" name="HelloWorldImplPort">
      <soap:address location="jms:queue:testQueue"/>
    </wsdl:port>
  </wsdl:service>
</wsdl:definitions>
----

[IMPORTANT]

The _HelloWorldImplPort_ here is meant for using the _testQueue_ that
has to be created before deploying the endpoint.

At the time of writing, _java:/ConnectionFactory_ is the default
connection factory JNDI location on WildFly

For allowing remote JNDI lookup of the connection factory, a specific
service ( `HelloWorldService`) for remote clients is added to the WSDL.
The _java:jms/RemoteConnectionFactory_ is the JNDI location of the same
connection factory mentioned above, except it's exposed for remote
lookup. The `soapjms:jndiInitialContextFactory` and `soap:jmsjndiURL`
complete the remote connection configuration, specifying the initial
context factory class to use and the JNDI registry address.

[IMPORTANT]

Have a look at the application server domain for finding out the
configured connection factory JNDI locations.

The endpoint implementation is a basic Jakarta XML Web Services POJO using @WebService
annotation to refer to the consumed contract:

[source,java,options="nowrap"]
----
package org.jboss.test.ws.jaxws.cxf.jms;
 
import jakarta.jws.WebService;
 
@WebService
(
   portName = "HelloWorldImplPort",
   serviceName = "HelloWorldServiceLocal",
   wsdlLocation = "META-INF/wsdl/HelloWorldService.wsdl",
   endpointInterface = "org.jboss.test.ws.jaxws.cxf.jms.HelloWorld",
   targetNamespace = "http://org.jboss.ws/jaxws/cxf/jms"
)
public class HelloWorldImpl implements HelloWorld
{
   public String echo(String input)
   {
      return input;
   }
}
----

[NOTE]

The endpoint implementation references the `HelloWorldServiceLocal` wsdl
service, so that the local JNDI connection factory location is used for
starting the endpoint on server side.

That's pretty much all. We just need to package the generated service
endpoint interface, the endpoint implementation and the WSDL file in a
_jar_ archive and deploy it:

....
alessio@inuyasha /dati/jbossws/stack/cxf/trunk $ jar -tvf ./modules/testsuite/cxf-tests/target/test-libs/jaxws-cxf-jms-only-deployment.jar
     0 Thu Jun 23 15:18:44 CEST 2011 META-INF/
   129 Thu Jun 23 15:18:42 CEST 2011 META-INF/MANIFEST.MF
     0 Thu Jun 23 15:18:42 CEST 2011 org/
     0 Thu Jun 23 15:18:42 CEST 2011 org/jboss/
     0 Thu Jun 23 15:18:42 CEST 2011 org/jboss/test/
     0 Thu Jun 23 15:18:42 CEST 2011 org/jboss/test/ws/
     0 Thu Jun 23 15:18:42 CEST 2011 org/jboss/test/ws/jaxws/
     0 Thu Jun 23 15:18:42 CEST 2011 org/jboss/test/ws/jaxws/cxf/
     0 Thu Jun 23 15:18:42 CEST 2011 org/jboss/test/ws/jaxws/cxf/jms/
   313 Thu Jun 23 15:18:42 CEST 2011 org/jboss/test/ws/jaxws/cxf/jms/HelloWorld.class
  1173 Thu Jun 23 15:18:42 CEST 2011 org/jboss/test/ws/jaxws/cxf/jms/HelloWorldImpl.class
     0 Thu Jun 23 15:18:40 CEST 2011 META-INF/wsdl/
  3074 Thu Jun 23 15:18:40 CEST 2011 META-INF/wsdl/HelloWorldService.wsdl
....

[NOTE]

A dependency on `org.hornetq` module needs to be added in MANIFEST.MF
when deploying to WildFly.

....
Manifest-Version: 1.0

Ant-Version: Apache Ant 1.7.1

Created-By: 17.0-b16 (Sun Microsystems Inc.)

Dependencies: org.hornetq
....

A Jakarta XML Web Services client can interact with the Jakarta Messaging endpoint the usual way:

[source,java,options="nowrap"]
----
URL wsdlUrl = ...
//start another bus to avoid affecting the one that could already be assigned to the current thread - optional but highly suggested
Bus bus = BusFactory.newInstance().createBus();
BusFactory.setThreadDefaultBus(bus);
try
{
   QName serviceName = new QName("http://org.jboss.ws/jaxws/cxf/jms", "HelloWorldService");
   Service service = Service.create(wsdlUrl, serviceName);
   HelloWorld proxy = (HelloWorld) service.getPort(new QName("http://org.jboss.ws/jaxws/cxf/jms", "HelloWorldImplPort"), HelloWorld.class);
   setupProxy(proxy);
   proxy.echo("Hi");
}
finally
{
   bus.shutdown(true);
}
----

[IMPORTANT]

The WSDL location URL needs to be retrieved in a custom way, depending
on the client application. Given the endpoint is Jakarta Messaging only, there's no
automatically published WSDL contract.

in order for performing the remote invocation (which internally goes
through remote JNDI lookup of the connection factory), the calling user
credentials need to be set into the Apache CXF JMSConduit:

[source,java,options="nowrap"]
----
private void setupProxy(HelloWorld proxy) {
   JMSConduit conduit = (JMSConduit)ClientProxy.getClient(proxy).getConduit();
   JNDIConfiguration jndiConfig = conduit.getJmsConfig().getJndiConfig();
   jndiConfig.setConnectionUserName("user");
   jndiConfig.setConnectionPassword("password");
   Properties props = conduit.getJmsConfig().getJndiTemplate().getEnvironment();
   props.put(Context.SECURITY_PRINCIPAL, "user");
   props.put(Context.SECURITY_CREDENTIALS, "password");
}
----

[IMPORTANT]

Have a look at the WildFly domain and messaging configuration for
finding out the actual security requirements. At the time of writing, a
user with `guest` role is required and that's internally checked using
the `other` security domain.

Of course once the endpoint is exposed over Jakarta Messaging transport, any plain Jakarta Messaging
client can also be used to send messages to the webservice endpoint. You
can have a look at the SOAP over Jakarta Messaging spec details and code the client
similarly to

[source,java,options="nowrap"]
----
Properties env = new Properties();
env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
env.put(Context.PROVIDER_URL, "http-remoting://myhost:8080");
env.put(Context.SECURITY_PRINCIPAL, "user");
env.put(Context.SECURITY_CREDENTIALS, "password");
InitialContext context = new InitialContext(env);
QueueConnectionFactory connectionFactory = (QueueConnectionFactory)context.lookup("jms/RemoteConnectionFactory");
Queue reqQueue = (Queue)context.lookup("jms/queue/test");
Queue resQueue = (Queue)context.lookup("jms/queue/test");
QueueConnection con = connectionFactory.createQueueConnection("user", "password");
QueueSession session = con.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
QueueReceiver receiver = session.createReceiver(resQueue);
ResponseListener responseListener = new ResponseListener(); //a custom response listener...
receiver.setMessageListener(responseListener);
con.start();
TextMessage message = session.createTextMessage(reqMessage);
message.setJMSReplyTo(resQueue);
 
//setup SOAP-over-JMS properties...
message.setStringProperty("SOAPJMS_contentType", "text/xml");
message.setStringProperty("SOAPJMS_requestURI", "jms:queue:testQueue");
 
QueueSender sender = session.createSender(reqQueue);
sender.send(message);
sender.close();
 
...
----

[[Jakarta-Messaging-and-http-endpoints-deployment]]
=== Jakarta Messaging and HTTP endpoints deployment

In this example we create a deployment containing an endpoint that
serves over both HTTP and Jakarta Messaging transports.

We from a WSDL contract such as below (please note we've two `binding` /
`portType` for the same `service`):

[source,xml,options="nowrap"]
----
<?xml version='1.0' encoding='UTF-8'?>
<wsdl:definitions name="HelloWorldService" targetNamespace="http://org.jboss.ws/jaxws/cxf/jms"
  xmlns:ns1="http://schemas.xmlsoap.org/soap/http"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:tns="http://org.jboss.ws/jaxws/cxf/jms"
  xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
  xmlns:soapjms="http://www.w3.org/2010/soapjms/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <wsdl:types>
<xs:schema elementFormDefault="unqualified" targetNamespace="http://org.jboss.ws/jaxws/cxf/jms" version="1.0"
  xmlns:tns="http://org.jboss.ws/jaxws/cxf/jms" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="echo" type="tns:echo"/>
<xs:element name="echoResponse" type="tns:echoResponse"/>
<xs:complexType name="echo">
    <xs:sequence>
      <xs:element minOccurs="0" name="arg0" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
<xs:complexType name="echoResponse">
    <xs:sequence>
      <xs:element minOccurs="0" name="return" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
</xs:schema>
  </wsdl:types>
  <wsdl:message name="echoResponse">
    <wsdl:part element="tns:echoResponse" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:message name="echo">
    <wsdl:part element="tns:echo" name="parameters">
    </wsdl:part>
  </wsdl:message>
  <wsdl:portType name="HelloWorld">
    <wsdl:operation name="echo">
      <wsdl:input message="tns:echo" name="echo">
    </wsdl:input>
      <wsdl:output message="tns:echoResponse" name="echoResponse">
    </wsdl:output>
    </wsdl:operation>
  </wsdl:portType>
  <wsdl:binding name="HelloWorldServiceSoapBinding" type="tns:HelloWorld">
    <soap:binding style="document" transport="http://www.w3.org/2010/soapjms/"/>
    <wsdl:operation name="echo">
      <soap:operation soapAction="" style="document"/>
      <wsdl:input name="echo">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="echoResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:binding name="HttpHelloWorldServiceSoapBinding" type="tns:HelloWorld">
    <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
    <wsdl:operation name="echo">
      <soap:operation soapAction="" style="document"/>
      <wsdl:input name="echo">
        <soap:body use="literal"/>
      </wsdl:input>
      <wsdl:output name="echoResponse">
        <soap:body use="literal"/>
      </wsdl:output>
    </wsdl:operation>
  </wsdl:binding>
  <wsdl:service name="HelloWorldService">
    <soapjms:jndiConnectionFactoryName>java:jms/RemoteConnectionFactory</soapjms:jndiConnectionFactoryName>
    <soapjms:jndiInitialContextFactory>org.jboss.naming.remote.client.InitialContextFactory</soapjms:jndiInitialContextFactory>
    <soapjms:jndiURL>http-remoting://localhost:8080</soapjms:jndiURL>
    <wsdl:port binding="tns:HelloWorldServiceSoapBinding" name="HelloWorldImplPort">
      <soap:address location="jms:queue:testQueue"/>
    </wsdl:port>
    <wsdl:port binding="tns:HttpHelloWorldServiceSoapBinding" name="HttpHelloWorldImplPort">
      <soap:address location="http://localhost:8080/jaxws-cxf-jms-http-deployment"/>
    </wsdl:port>
  </wsdl:service>
  <wsdl:service name="HelloWorldServiceLocal">
    <soapjms:jndiConnectionFactoryName>java:/ConnectionFactory</soapjms:jndiConnectionFactoryName>
    <wsdl:port binding="tns:HelloWorldServiceSoapBinding" name="HelloWorldImplPort">
      <soap:address location="jms:queue:testQueue"/>
    </wsdl:port>
</wsdl:definitions>
----

The same considerations of the previous example regarding the Jakarta Messaging queue
and JNDI connection factory still apply. +
Here we can implement the endpoint in multiple ways, either with a
common implementation class that's extended by the Jakarta Messaging and HTTP ones, or
keep the two implementation classes independent and just have them
implement the same service endpoint interface:

[source,java,options="nowrap"]
----
package org.jboss.test.ws.jaxws.cxf.jms_http;
 
import jakarta.jws.WebService;
 
@WebService
(
   portName = "HelloWorldImplPort",
   serviceName = "HelloWorldServiceLocal",
   wsdlLocation = "WEB-INF/wsdl/HelloWorldService.wsdl",
   endpointInterface = "org.jboss.test.ws.jaxws.cxf.jms_http.HelloWorld",
   targetNamespace = "http://org.jboss.ws/jaxws/cxf/jms"
)
public class HelloWorldImpl implements HelloWorld
{
   public String echo(String input)
   {
      System.out.println("input: " + input);
      return input;
   }
}
----

[source,java,options="nowrap"]
----
package org.jboss.test.ws.jaxws.cxf.jms_http;
 
import jakarta.jws.WebService;
 
@WebService
(
   portName = "HttpHelloWorldImplPort",
   serviceName = "HelloWorldService",
   wsdlLocation = "WEB-INF/wsdl/HelloWorldService.wsdl",
   endpointInterface = "org.jboss.test.ws.jaxws.cxf.jms_http.HelloWorld",
   targetNamespace = "http://org.jboss.ws/jaxws/cxf/jms"
)
public class HttpHelloWorldImpl implements HelloWorld
{
   public String echo(String input)
   {
      System.out.println("input (http): " + input);
      return "(http) " + input;
   }
}
----

Both classes are packaged together the service endpoint interface and
the WSDL file in a _war_ archive:

....
alessio@inuyasha /dati/jbossws/stack/cxf/trunk $ jar -tvf ./modules/testsuite/cxf-spring-tests/target/test-libs/jaxws-cxf-jms-http-deployment.war
     0 Thu Jun 23 15:18:44 CEST 2011 META-INF/
   129 Thu Jun 23 15:18:42 CEST 2011 META-INF/MANIFEST.MF
     0 Thu Jun 23 15:18:44 CEST 2011 WEB-INF/
   569 Thu Jun 23 15:18:40 CEST 2011 WEB-INF/web.xml
     0 Thu Jun 23 15:18:44 CEST 2011 WEB-INF/classes/
     0 Thu Jun 23 15:18:42 CEST 2011 WEB-INF/classes/org/
     0 Thu Jun 23 15:18:42 CEST 2011 WEB-INF/classes/org/jboss/
     0 Thu Jun 23 15:18:42 CEST 2011 WEB-INF/classes/org/jboss/test/
     0 Thu Jun 23 15:18:42 CEST 2011 WEB-INF/classes/org/jboss/test/ws/
     0 Thu Jun 23 15:18:42 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/
     0 Thu Jun 23 15:18:42 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/cxf/
     0 Thu Jun 23 15:18:42 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/cxf/jms_http/
   318 Thu Jun 23 15:18:42 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/cxf/jms_http/HelloWorld.class
  1192 Thu Jun 23 15:18:42 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/cxf/jms_http/HelloWorldImpl.class
  1246 Thu Jun 23 15:18:42 CEST 2011 WEB-INF/classes/org/jboss/test/ws/jaxws/cxf/jms_http/HttpHelloWorldImpl.class
     0 Thu Jun 23 15:18:40 CEST 2011 WEB-INF/wsdl/
  3068 Thu Jun 23 15:18:40 CEST 2011 WEB-INF/wsdl/HelloWorldService.wsdl
....

A trivial web.xml descriptor is also included to trigger the HTTP
endpoint publish:

[source,xml,options="nowrap"]
----
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
  version="2.4">
  <servlet>
    <servlet-name>EndpointServlet</servlet-name>
    <servlet-class>org.jboss.test.ws.jaxws.cxf.jms_http.HttpHelloWorldImpl</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>EndpointServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>
</web-app>
----

[IMPORTANT]

Here too the MANIFEST.MF needs to declare a dependency on _org.hornetq_
module when deploying to WildFly.

Finally, the Jakarta XML Web Services client can ineract with both Jakarta Messaging and HTTP endpoints
as usual:

[source,java,options="nowrap"]
----
//start another bus to avoid affecting the one that could already be assigned to current thread - optional but highly suggested
Bus bus = BusFactory.newInstance().createBus();
BusFactory.setThreadDefaultBus(bus);
try
{
   QName serviceName = new QName("http://org.jboss.ws/jaxws/cxf/jms", "HelloWorldService");
   Service service = Service.create(wsdlUrl, serviceName);
 
   //JMS test
   HelloWorld proxy = (HelloWorld) service.getPort(new QName("http://org.jboss.ws/jaxws/cxf/jms", "HelloWorldImplPort"), HelloWorld.class);
   setupProxy(proxy);
   proxy.echo("Hi");
   //HTTP test
   HelloWorld httpProxy = (HelloWorld) service.getPort(new QName("http://org.jboss.ws/jaxws/cxf/jms", "HttpHelloWorldImplPort"), HelloWorld.class);
   httpProxy.echo("Hi");
}
finally
{
   bus.shutdown(true);
}
----

[[use-of-endpoint.publish-api]]
=== Use of Endpoint.publish() API

An alternative to deploying an archive containing Jakarta Messaging endpoints is in
starting them directly using the Jakarta XML Web Services `Endpoint.publish(..)` API.

That's as easy as doing:

[source,java,options="nowrap"]
----
Object implementor = new HelloWorldImpl();
Endpoint ep = Endpoint.publish("jms:queue:testQueue", implementor);
try
{
   //use or let others use the endpoint
}
finally
{
   ep.stop();
}
----

where `HelloWorldImpl` is a POJO endpoint implementation referencing a
Jakarta Messaging _port_ in a given WSDL contract, as explained in the previous
examples.

The main difference among the deployment approach is in the direct
control and responsibility over the endpoint lifecycle ( _start/publish_
and _stop_).
