Tag Archives: java

cxf, spring and http-conf:client problems…

Question:
Is there a way to shorten the timeout in CXF? (http://incubator.apache.org/cxf/)

Answer:
After looking through the CXF documentation, they state that you through Spring (www.springframework.org) can set a timout.

This is done like this (on the client side):

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
	xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="
http://cxf.apache.org/jaxws http://cxf.apache.org/schema/jaxws.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd">

	<http-conf:conduit name="*.http-conduit">>
		<http-conf:client ReceiveTimeout="100" />
	</http-conf:conduit>
</beans>


I use name=”*.http-conduit” to make my life more simple

This example is from a larger example about ssl configuration on the client connection. It was found here: http://cwiki.apache.org/CXF20DOC/client-http-transport-including-ssl-support.html
There are some additional information in their javadoc, about the HTTPConduit we are setting through spring.: http://incubator.apache.org/cxf/javadoc/latest/org/apache/cxf/transport/http/HTTPConduit.html

The Tests:
When testing this, I implemented the small “HelloWorld” webservice from the CXF User’s guide (http://cwiki.apache.org/CXF20DOC/a-simple-jax-ws-service.html), which can receive a text through a sayHi service, and sends back the response: “Hello “+text-you’ve-sent

In order to test this, i’ve made a dynamical client (just to try, and their guides show an example of doing this).
In the project at work, we are using a generated client, so I made this also.

The dynamical client was made as follows:

DynamicClientFactory dcf = DynamicClientFactory.newInstance();
Client client = dcf.createClient("http://localhost/HelloWorld/HelloWorld?wsdl");

Object[] results = client.invoke("sayHi", "tester");
System.out.println("response from ws: "+results[0]);

The generated client was made as follows, using wsdl2java:
wsdl2java -impl -p test.webservice.client http://localhost/HelloWorld/HelloWorld?wsdl

I then wrote a test for the dynamic client and the generated client, just to see if it all worked.

package test;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.dynamic.DynamicClientFactory;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import test.webservice.client.HelloWorld;
import test.webservice.client.HelloWorldImplService;

public class TestClient extends TestCase {
	protected void setUp() throws Exception {
		super.setUp();
	}

	public void testHelloWorldDynamically() throws Exception {
		DynamicClientFactory dcf = DynamicClientFactory.newInstance();
		Client client = dcf.createClient("http://localhost/HelloWorld/HelloWorld?wsdl");
		
        	Object[] results = client.invoke("sayHi", "tester");
	        System.out.println("response from ws: "+results[0]);
	}
	
	public void testHelloWorldGenerated() {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"client-beans.xml"});
		HelloWorldImplService service = new HelloWorldImplService();
		HelloWorld port = service.getHelloWorldImplPort();

		String result = port.sayHi("tester2");
		
		System.out.println(result);
	}
}

I then altered the sayHi() method on the webservice, to have a Thread.sleep(5000) in it. This was done, so I could simulate a long service call.

package test.webservice;

import javax.jws.WebService;

@WebService(endpointInterface = "test.webservice.HelloWorld")
public class HelloWorldImpl implements HelloWorld {

	public String sayHi(String text) {
		try {
			Thread.sleep(5000);
		}
		catch(InterruptedException ie) {

		}
		
		return "Hello " + text;
	}
}

After some testing, I discovered that the spring configuration didn’t work. According to http://issues.apache.org/jira/browse/CXF-922 the issue with spring configurations where closed and submitted in cxf-2.0.3
Even after upgrading to cxf-2.0.4 it didn’t work.

I then decided to try and set the configuration manually on the dynamically generated client. Based on the information about the spring configuration, I was looking for a “http conduit” in their javadoc.

Their javadoc states that, the HTTPConduit has a method called getClient(), which returns a HTTPClientPolicy. On this HTTPClientPolicy I can set the ReceiveTimeout manually.

So i’ve made a some changes to the JUnit test to see if it all worked.

package test;

import junit.framework.TestCase;

import org.apache.cxf.endpoint.Client;
import org.apache.cxf.endpoint.dynamic.DynamicClientFactory;
import org.apache.cxf.frontend.ClientProxy;
import org.apache.cxf.transport.http.HTTPConduit;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import test.webservice.client.HelloWorld;
import test.webservice.client.HelloWorldImplService;

public class HelloWorldClientTest extends TestCase {
    protected void setUp() throws Exception {
		super.setUp();
	}

    public void testHelloWorldDynamically() throws Exception {
        // creating the client
        DynamicClientFactory dcf = DynamicClientFactory.newInstance();
        Client client = dcf.createClient("http://localhost/HelloWorld/HelloWorld?wsdl");
        
        // Testing the current values
        HTTPConduit httpConduit = (HTTPConduit)client.getConduit();
        System.out.println("ReceiveTimeout: "+httpConduit.getClient().getReceiveTimeout());
        
        // setting the new values
        httpConduit.getClient().setReceiveTimeout(100);
        System.out.println("ReceiveTimeout: "+httpConduit.getClient().getReceiveTimeout());
        
        Object[] results = client.invoke("sayHi", "tester");
        System.out.println("response from ws: "+results[0]);
    }
    
    public void testHelloWorldGenerated() {
		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"client-beans.xml"});
		HelloWorldImplService service = new HelloWorldImplService();
		HelloWorld port = service.getHelloWorldImplPort();
        
		// setting the timeout
		Client c = ClientProxy.getClient(port);
		HTTPConduit httpConduit = (HTTPConduit) c.getConduit();
		httpConduit.getClient().setReceiveTimeout(100);

		String result = port.sayHi("tester2");
		
		System.out.println(result);
	}
}

The tests now throws two java.net.SocketTimeoutException, which means that my changes are now working. Cheers!

JCS and performance

JCS is a caching system maintained at apache and is located here: http://jakarta.apache.org/jcs/

When using JCS in a large project, we did a lot of performance testing, and the cache seemed to perform just fine. After some more testing and the use of JProfiler (gotta love that tool) for optimizing, I discovered that lookups in the JCS cache (LRU) where really slow.

After some searching on google, I found a mailing list, where a person had similar performance problems with JCS. They eventually found out, that JCS uses log4j and has DEBUG turned on by default. When DEBUG logging was turned on, JCS did a verifyCache() on the cache, and then I tried to turn off the DEBUG logging on org.apache.jcs, and then I got a factor 475 improvement on the lookups!

Performance chart:
Before removing the debug logging on JCS: (Didn’t set any log4j up on the jcs cache)
1980 lookups took 10458ms.

After removing the debug logging on JCS: (Set the following log4j on the jcs cache this time: log4j.logger.org.apache.jcs=info,CONSOLE)
1980 lookups took 22ms.
Factor calculation is: 10458 / 22 = 475.36

Thanks to the guys on the mailinglist http://www.mail-archive.com/turbine-jcs-user@jakarta.apache.org/msg00464.html and especially to Jean-Marc Spaggiari for finding the actual error.

Strange Hibernate behaviour

At work I decided to implement some DAO files in Hibernate. I started by making the smallest DAO first, and began with the work.
After making two HibernateDAO classes and beginning the third (file2DAO), which does nearly the same as second one (file1DAO). I simply copied all the data from the file1.hbm.xml file to the final file2.hbm.xml and edited the file to adjust it to the file2’s class.

File1.hbm.xml:

<?xml version="1.0"encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mappingdefault-lazy="false">
      <!—- omitted -->
      </class>

      <query name="xxx"><![CDATA[
            omitted
      ]]></query>
</hibernate-mapping>

File2.hbm.xml:

<?xml version="1.0"encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mappingdefault-lazy="false">
      <!—- omitted -->
      <query name="xxx1"><![CDATA[
            omitted
      ]]></query>
</hibernate-mapping>

This however, resulted in a 20mins debugging session, because the hiberbate.cfg file could not read the mapping… I started to uncomment the changes in the file2.hbm.xml file and found out that when I uncommented the query at the bottom, the junit tests could run. After a little extra debugging I found out, that hibernate cannot have two hbm.xml files, which have the same NamedQuery name. The contents of the NamedQueries where different, only the name where identical.

So… I’ve now changed the file2.hbm.xml file’s namedQuery to xxx1 instead of xxx as in file1.hbm.xml

Why is this?

Why can’t I have two namedQueries, that share the name, but have different content? Aren’t they in their own namespace?