Archive

Archives pour la catégorie ‘WebService’

Setting timeout on generated JAXWS CXF Clients

23/09/2009

When generating client with the CXF (2.2.2 in this case, should apply to all…) Java API without any configuration file, here is the way to set the client timeout :

package org.ow2.petals.kernel.ws.client;
 
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
import org.ow2.petals.kernel.ws.api.RuntimeService;
 
public class Main {
 
    private void createService() {
        long timeout = 10000L;
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(RuntimeService.class);
        factory.setAddress("http://localhost:9999/service/Runtime");
        RuntimeService runtimeService = (RuntimeService) factory.create();
 
        Client client = ClientProxy.getClient(runtimeService);
        if (client != null) {
            HTTPConduit conduit = (HTTPConduit) client.getConduit();
            HTTPClientPolicy policy = new HTTPClientPolicy();
            policy.setConnectionTimeout(timeout);
            policy.setReceiveTimeout(timeout);
            conduit.setClient(policy);
        }
    }
}

Note that here the RuntimeService class is my JAXWS annotated class.

WebService , ,

EasyWSDL 1.3 is out

19/08/2009

One more new release of OW2-EasyWSDL, the WSDL manipulation library.

The EasyWSDL team is pleased to announce the release of EasyWSDL 1.3
You can download it from: http://forge.ow2.org/project/showfiles.php?group_id=334&release_id=3454
Available in this version :

  • Fix some bugs
  • Improve import/include management
  • Use URL instead of URI in WSDL reader
  • Add SimpleContent tag management
  • Change artifact name (More maven compliant…)

More information is available on EasyWSDL website: http://easywsdl.ow2.org/

WebService , ,

EasyWSDL 1.2 is out

09/07/2009

OW2 EasyWSDL WSDL manipulation library has just been released. This release fix many bugs and introduces some new tooling such as java2wsdl (create WSDL from Java interfaces) and xsd2xml (create XML from XSD definition).

EasyWSDL is easy since you can manipulate both WSDL 1.1 and WSDL 2.0 with the same object model.

// Read a WSDL 1.1 or 2.0
WSDLReader reader = WSDLFactory.newInstance().newWSDLReader();
Description desc = reader.readWSDL(new URI("http://file/path/document.wsdl"));
 
// Write a WSDL 1.1 or 2.0 (depend of desc version)
Document doc = WSDLFactory.newInstance().newWSDLWriter().getDocument(desc);
 
// Create a WSDL 1.1 or 2.0
Description desc11 = WSDLFactory.newInstance().newDescription(WSDLVersionConstants.WSDL11);
Description desc20 = WSDLFactory.newInstance().newDescription(WSDLVersionConstants.WSDL20);

Once the Description object is loaded from the WSDL document, you can maniulate all parts of the service description. Let’s look at endpoints :

// Endpoints take place in services.
// Select a service
Service service = desc.getServices().get(0);
 
// List endpoints
List endpoints = service.getEndpoints(); 
 
// Read specific endpoint
Endpoint specificEndpoint = service.getEndpoint("endpointName");
 
// Add endpoint to service
service.addEndpoint(specificEndpoint);
 
// Remove a specific enpoint
service.removeEndpoint("endpointName");
 
// Create endpoint
Endpoint createdEndpoint = service.createEndpoint();
service.addEndpoint(createdEndpoint);

Easy!

WebService, soa , , , ,

An operation with name ” already exists in this service

14/05/2009

Here is a tip on how to avoid this type of exception with JAXWS but before let’s try to understand why your Service construciton fails…

This exception occurs when your service definition (the Java interface in our case) have some duplicates methods without the same number of parameters (ie method overloading). This exception is totally normal since it is quite logic that the resulting Web Service can only have unique operation names :

  • Check a WSDL file. Did you ever see the same operation X times?
  • The Web Service Engine generally tries to get the operation context from the operation name. Then it will unmarshall the parameters (it will not have a look to the operation parameters to choose the operation like it should be done in the Java Runtime).

Here is a service definition sample which will be used in this article :

package com.googlecode.chamerling.blog.jaxws.duplicate;
 
/**
 * @author Christophe HAMERLING
 *
 */
public interface Service {
 
	void foo();
 
	void foo(String bar);
}

So let’s implement this interface :

package com.googlecode.chamerling.blog.jaxws.duplicate;
 
import javax.jws.WebService;
 
/**
 * @author Christophe HAMERLING
 *
 */
@WebService
public class ServiceKo implements Service {
 
	public void foo() {
	}
 
	public void foo(String bar) {
	}
}

Let’s use the JaxWsServerFactoryBean CXF factory (other WS stacks should throw the same exception…) to expose this service :

import org.apache.cxf.jaxws.JaxWsServerFactoryBean;
 
/**
 * @author Christophe HAMERLING
 */
public class App {
 
	private static final String URL = "http://localhost:9999/chamerling/services/";
 
	public static void main(String[] args) {
		JaxWsServerFactoryBean svrFactory = new JaxWsServerFactoryBean();
		Service space = new ServiceKo();
		svrFactory.setAddress(URL + "ServiceKO");
		svrFactory.setServiceBean(space);
 
		org.apache.cxf.endpoint.Server service = svrFactory.create();
 
		System.out.println("Service is available at "
				+ service.getEndpoint().getEndpointInfo().getAddress());
 
	}
}

You should have a beautiful stack trace :

java.lang.IllegalArgumentException: An operation with name [{http://duplicate.jaxws.blog.chamerling.googlecode.com/}foo] already exists in this service
	at org.apache.cxf.service.model.InterfaceInfo.addOperation(InterfaceInfo.java:71)
	at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.createOperation(ReflectionServiceFactoryBean.java:774)
	at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.createOperation(JaxWsServiceFactoryBean.java:484)
	at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.createInterface(ReflectionServiceFactoryBean.java:766)
	at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.buildServiceFromClass(ReflectionServiceFactoryBean.java:361)
	at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.buildServiceFromClass(JaxWsServiceFactoryBean.java:525)
	at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.initializeServiceModel(ReflectionServiceFactoryBean.java:422)
	at org.apache.cxf.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:190)
	at org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:164)
	at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:100)
	at org.apache.cxf.frontend.ServerFactoryBean.create(ServerFactoryBean.java:117)
	at org.apache.cxf.jaxws.JaxWsServerFactoryBean.create(JaxWsServerFactoryBean.java:168)
	at com.googlecode.chamerling.blog.jaxws.duplicate.AppTest.testKoService(AppTest.java:37)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:585)
	at junit.framework.TestCase.runTest(TestCase.java:154)
	at junit.framework.TestCase.runBare(TestCase.java:127)
	at junit.framework.TestResult$1.protect(TestResult.java:106)
	at junit.framework.TestResult.runProtected(TestResult.java:124)
	at junit.framework.TestResult.run(TestResult.java:109)
	at junit.framework.TestCase.run(TestCase.java:118)
	at junit.framework.TestSuite.runTest(TestSuite.java:208)
	at junit.framework.TestSuite.run(TestSuite.java:203)
	at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)

So the solution is to use the @WebParam @WebMethod annotation. Simply use this annotation to specify unique operation names in your service implementation :

package com.googlecode.chamerling.blog.jaxws.duplicate;
 
import javax.jws.WebMethod;
import javax.jws.WebService;
 
/**
 * @author Christophe HAMERLING
 *
 */
@WebService
public class ServiceOk implements Service {
 
	@WebMethod(operationName = "foo1")
	public void foo() {
	}
 
	@WebMethod(operationName = "foo2")
	public void foo(String bar) {
	}
}

Sources for this example are availble on my google code project (http://code.google.com/p/chamerling/) under http://code.google.com/p/chamerling/source/browse/#svn/trunk/blog/jaxws-duplicate

WebService , ,

Apache CXF Clients : null result when using bad client factory

09/04/2009

Just a quick note to show that the client factory choice is important with Apache CXF 2.1.4.

The service interface definition :

package org.ow2.petals.usecase.soapaddressing.server;
 
import javax.jws.WebMethod;
import javax.jws.WebService;
 
/**
 * @author chamerling - eBM WebSourcing
 *
 */
@WebService
public interface AddressingService {
 
    /**
     * Get the local information
     * 
     * @return
     */
    @WebMethod
    String getInfo();
 
}

The client with the bad client factory :

package org.ow2.petals.usecase.soapaddressing.client;
 
import org.apache.cxf.frontend.ClientProxyFactoryBean;
import org.ow2.petals.usecase.soapaddressing.server.AddressingService;
 
/**
 * @author chamerling - eBM WebSourcing
 *
 */
public class BadFactory {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        ClientProxyFactoryBean factory = new ClientProxyFactoryBean();
        factory.setServiceClass(AddressingService.class);
        factory.setAddress("http://localhost:8084/petals/services/Service01");
        AddressingService client = (AddressingService) factory.create();
        String info = client.getInfo();
        System.out.println(info);
    }
}

With that client code, the Web Service is really invoked, but the result of the getInfo operation is null. So, let’s do it with the right client factory…

The client with the good client factory :

package org.ow2.petals.usecase.soapaddressing.client;
 
import org.apache.cxf.jaxws.JaxWsProxyFactoryBean;
import org.ow2.petals.usecase.soapaddressing.server.AddressingService;
 
/**
 * @author chamerling - eBM WebSourcing
 *
 */
public class GoodFactory {
 
    /**
     * @param args
     */
    public static void main(String[] args) {
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setServiceClass(AddressingService.class);
        factory.setAddress("http://localhost:8084/petals/services/Service01");
        AddressingService client = (AddressingService) factory.create();
        String info = client.getInfo();
        System.out.println(info);
    }
}

This time the result is not null and is really the one expected…

WebService , ,

JSR181 Tip#1

26/11/2008

Here is a tip on the PEtALS JSR181 Service Engine (which is also available for all JSR181 annotated classes outside of PEtALS).

Today, I spent some time on a customer bug which was not really a bug… I was quite surprising when he said me that he was unable to get its annotated class working on the component. The error was at instantiation time (first JBI message handling) :

org.apache.axis2.AxisFault: The service is unable to load the foo.bar.Service service implementation class. at org.apache.axis2.AxisFault.makeFault(AxisFault.java:430) at org.apache.axis2.jaxws.server.JAXWSMessageReceiver.receive(JAXWSMessageReceiver.java:220) at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:176) at org.ow2.petals.se.jsr181.JBIListener.onJBIMessage(JBIListener.java:120) at org.ow2.petals.component.framework.listener.MessageExchangeProcessor.processInOutAsProvider(MessageExchangeProcessor.java:524) at org.ow2.petals.component.framework.listener.MessageExchangeProcessor.processAsProvider(MessageExchangeProcessor.java:421) at org.ow2.petals.component.framework.listener.MessageExchangeProcessor.process(MessageExchangeProcessor.java:308) at org.ow2.petals.component.framework.listener.MessageExchangeProcessor.run(MessageExchangeProcessor.java:145) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:885) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:907) at java.lang.Thread.run(Thread.java:619) Caused by: javax.xml.ws.WebServiceException: The service is unable to load the org.ow2.petals.usecase.jsr181.TestService service implementation class. at org.apache.axis2.jaxws.ExceptionFactory.createWebServiceException(ExceptionFactory.java:173) at org.apache.axis2.jaxws.ExceptionFactory.makeWebServiceException(ExceptionFactory.java:70) at org.apache.axis2.jaxws.ExceptionFactory.makeWebServiceException(ExceptionFactory.java:118) at org.apache.axis2.jaxws.server.endpoint.lifecycle.impl.EndpointLifecycleManagerImpl.createServiceInstance(EndpointLifecycleManagerImpl.java:242) at org.apache.axis2.jaxws.server.endpoint.lifecycle.impl.EndpointLifecycleManagerImpl.createServiceInstance(EndpointLifecycleManagerImpl.java:94) at org.apache.axis2.jaxws.server.ServiceInstanceFactoryImpl.createServiceInstance(ServiceInstanceFactoryImpl.java:49) at org.apache.axis2.jaxws.server.EndpointController.handleRequest(EndpointController.java:253) at org.apache.axis2.jaxws.server.EndpointController.invoke(EndpointController.java:98) at org.apache.axis2.jaxws.server.JAXWSMessageReceiver.receive(JAXWSMessageReceiver.java:159) … 9 more

So what? I launched PEtALS in debug mode, and going step by step until the foo.bar.Service class instantiation. ‘Hey what’s up InstanciationException?’.
This is simply because the foo.bar.Service class contains constructors and not the empty one!

The solution is to remove all the constructors which are not very usefull here (since they can not be used), or add an empty constructor. Now it works!

Non classé, PEtALS, WebService , ,