igarashitm.log

igarashitm, a Japanese software engineer writes something in English here.

Debugging around JBossWS & apache-cxf without JBoss instance on Eclipse

Just a note for debugging SWITCHYARD-600.
Don't forget to mkdir ${project}/resources and add it to the build path.

Add system property when run/debug

-Djavax.xml.ws.spi.Provider=org.jboss.wsf.stack.cxf.client.ProviderImpl

resources/META-INF/cxf/bus-extensions.txt

org.apache.cxf.wsdl11.WSDLManagerImpl:org.apache.cxf.wsdl.WSDLManager:true
org.apache.cxf.phase.PhaseManagerImpl:org.apache.cxf.phase.PhaseManager:true
org.apache.cxf.workqueue.WorkQueueManagerImpl:org.apache.cxf.workqueue.WorkQueueManager:true
org.apache.cxf.buslifecycle.CXFBusLifeCycleManager:org.apache.cxf.buslifecycle.BusLifeCycleManager:true   	   
org.apache.cxf.endpoint.ServerRegistryImpl:org.apache.cxf.endpoint.ServerRegistry:true
org.apache.cxf.transport.http.QueryHandlerRegistryImpl:org.apache.cxf.transports.http.QueryHandlerRegistry:true 
org.apache.cxf.endpoint.EndpointResolverRegistryImpl:org.apache.cxf.endpoint.EndpointResolverRegistry:true
org.apache.cxf.headers.HeaderManagerImpl:org.apache.cxf.headers.HeaderManager:true
org.apache.cxf.catalog.OASISCatalogManager:org.apache.cxf.catalog.OASISCatalogManager:true
org.apache.cxf.service.factory.FactoryBeanListenerManager::true
org.apache.cxf.endpoint.ServerLifeCycleManagerImpl:org.apache.cxf.endpoint.ServerLifeCycleManager:true
org.apache.cxf.endpoint.ClientLifeCycleManagerImpl:org.apache.cxf.endpoint.ClientLifeCycleManager:true
org.apache.cxf.bus.resource.ResourceManagerImpl:org.apache.cxf.resource.ResourceManager:true

org.apache.cxf.binding.soap.SoapBindingFactory::true
org.apache.cxf.binding.soap.SoapTransportFactory::true

org.apache.cxf.transport.http.HTTPTransportFactory::true
org.apache.cxf.transport.http.HTTPWSDLExtensionLoader::true
org.apache.cxf.transport.http.policy.HTTPClientAssertionBuilder::true
org.apache.cxf.transport.http.policy.HTTPServerAssertionBuilder::true
org.apache.cxf.transport.http.policy.NoOpPolicyInterceptorProvider::true

org.jboss.wsf.stack.cxf.addons.transports.httpserver.HttpServerDestinationFactory::true

resources/wsdl.wsdl

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions 
    targetNamespace="urn:test" 
    xmlns="http://schemas.xmlsoap.org/wsdl/" 
    xmlns:tns="urn:test"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
    
  <types>
    <xsd:schema 
        targetNamespace="urn:test" 
        xmlns:tns="urn:test" 
        xmlns:xs="http://www.w3.org/2001/XMLSchema">
        <xs:element name="input" type="xs:string"/>
  </xsd:schema>
  </types>
  
  <message name="message">
    <part name="input" element="tns:input"/>
  </message>
  
  <portType name="service">
    <operation name="message">
      <input message="tns:message"/>
    </operation>
  </portType>
  
  <binding name="serviceBinding" type="tns:service">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"/>
    <operation name="message">
      <soap:operation soapAction="urn:test"/>
      <input>
        <soap:body use="literal"/>
      </input>
    </operation>
  </binding>
  
  <service name="service">
    <port name="port" binding="tns:serviceBinding">
      <soap:address location="http://localhost:18080/test"/>
    </port>
  </service>
</definitions>

src/PublishWebService.java

Test code for javax.xml.ws.{Provider,Endpoint}. Using TCP socket to invoke the service.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.soap.SOAPMessage;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.ws.Endpoint;
import javax.xml.ws.Provider;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.Service.Mode;
import javax.xml.ws.WebServiceProvider;
import javax.wsdl.Definition;
import javax.wsdl.Port;
import javax.wsdl.Service;
import javax.wsdl.factory.WSDLFactory;
import javax.wsdl.xml.WSDLReader;

import org.w3c.dom.Document;
import org.xml.sax.InputSource;

@WebServiceProvider
@ServiceMode(Mode.MESSAGE)
public class PublishWebService implements Provider<SOAPMessage> {
    private static final String PUBLISH_URL = "http://127.0.0.1:18080/context/test";
    private static final String WSDL = "wsdl.wsdl";
    private static final String REQUEST_BODY =
            "<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">\r\n" +
            "    <soap:Body>\r\n" +
            "        <test:input xmlns:test=\"urn:test\">foobar</test:input>\r\n" +
            "    </soap:Body>\r\n" +
            "</soap:Envelope>";

    @Override
    public SOAPMessage invoke(SOAPMessage request) {
        return null;
    }

    public void perform() throws Exception {
        Endpoint _endpoint = createEndpoint(WSDL);
        _endpoint.publish(PUBLISH_URL);
        
        Socket sock = new Socket("127.0.0.1", 18080);
        BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream()));
        Thread t = new MyReader(reader);
        t.start();
        OutputStream out = sock.getOutputStream();
        String method = "POST /context/test HTTP/1.1\r\n";
        out.write(method.getBytes(), 0, method.getBytes().length);
        String contentLength = "Content-Length: " + REQUEST_BODY.length() + "\r\n";
        out.write(contentLength.getBytes(), 0, contentLength.getBytes().length);
        String contentType = "Content-Type: text/xml; charset=\"utf-8\"\r\n\r\n";
        out.write(contentType.getBytes(), 0, contentType.getBytes().length);
        
        out.write(REQUEST_BODY.getBytes(), 0, REQUEST_BODY.getBytes().length);
        String eof = "\r\n\r\n";
        out.write(eof.getBytes(), 0, eof.getBytes().length);
        out.flush();

        Thread.sleep(1000);
        sock.close();
        _endpoint.stop();
        System.out.println(">>>>> end.");
        System.exit(0);
    }
    
    private Endpoint createEndpoint(String wsdl) throws Exception {
        URL wsdlUrl = this.getClass().getResource(wsdl);
        javax.wsdl.Service wsdlService = getService(wsdlUrl);
        Port _wsdlPort = (Port) wsdlService.getPorts().values().iterator().next();

        List<Source> metadata = new ArrayList<Source>();
        StreamSource source = new StreamSource(this.getClass().getResourceAsStream(wsdl));
        source.setSystemId(wsdlUrl.toExternalForm());
        
        metadata.add(source);
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(Endpoint.WSDL_SERVICE, wsdlService.getQName());
        properties.put(Endpoint.WSDL_PORT, new QName(wsdlService.getQName().getNamespaceURI(), _wsdlPort.getName()));
        properties.put("javax.xml.ws.wsdl.description", wsdlUrl.toExternalForm());

        Endpoint _endpoint = Endpoint.create(this);
        _endpoint.setMetadata(metadata);
        _endpoint.setProperties(properties);
        return _endpoint;
    }
    
    private Service getService(URL wsdlUrl) throws Exception {
        DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
        docBuilderFactory.setNamespaceAware(true);
        DocumentBuilder builder = docBuilderFactory.newDocumentBuilder();

        InputStream inputStream = wsdlUrl.openStream();
        InputSource source = new InputSource(inputStream);
        source.setSystemId(wsdlUrl.toString());
        Document wsdlDoc = builder.parse(source);
        WSDLFactory wsdlFactory = WSDLFactory.newInstance();
        WSDLReader reader = wsdlFactory.newWSDLReader();
        reader.setFeature("javax.wsdl.verbose", false);

        Definition definition = reader.readWSDL(wsdlUrl.toString(), wsdlDoc);
        Service service = null;
        service = (Service) definition.getServices().values().iterator().next();
        return service;
    }
    
    public static void main(String[] args) throws Exception {
        new PublishWebService().perform();
    }
}

class MyReader extends Thread {
    private BufferedReader reader;
    String line;
    
    public MyReader(BufferedReader reader) {
        this.reader = reader;
    }
    public void run() {
        while(true) {
            try {
                if ((line = reader.readLine()) != null) {
                    System.out.println(">>>>> received [" + line + "]");
                }
            } catch (IOException ignore) {break;}
        }
    }
}

resources/log4j.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>

	<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="%d{HH:mm:ss,SSS} %-5p [%c] %m%n"/>
		</layout>
	</appender>

	<root>
		<level value="FINE"/>
		<appender-ref ref="STDOUT"/>
	</root>

</log4j:configuration>