Category: Software

NLJug J-Fall 2010

By Rob, November 18, 2009 11:07 pm

Wednesday the 11th of november I visited JFall for the second time. This is the yearly event of the Dutch Java usergroup next to the JSpring in april. I attended on several sessions targetting especially new Java developments. For example the big improvements in JDK 7 where I was interested in.

  • Keynote – Enterprise 2.0: New Technologies, Innovations and Communities (Reginald Hutcherson)
  • Speed up your applications with Java SE 7 (Jeroen Borgers)
  • Scaling Out with Hadoop and NoSql (Age Mooij)
  • Keynote – Adobe Systems (Christophe Coenraets)
  • The Quest for Parallelism: How To ‘upgrade’ Your Application (Jan-Hendrik Kuperus)
  • JDK 7, What’s in it and what’s not (Simon Ritter)
  • Google Wave: what is it, and how does it work? (Jos Dirksen)

(I translated some of the subjects to English)

Three of them had a lot in common, the speeding up, the parallelism and the jdk7 where the most interesting ones. The other sessions where more informative and for fun.

The subjects I was really excited about, are the new concurrency features in Java. Being this more and more important with the current multicore cpus and the cloud computing hype we can’t ignore it! And it’s not only faster, it’s also very cool and not even hard to give it a try as a normal programmer. I even think that this new stuff makes our live easier then the old fashioned threading stuff in Java 5 and earlier (a lot of new stuff in Java 7 is already available through Java 6 in the updates but often not enabled by default).

Some cool and nice features are:

  • Fork join framework (next step in parallelism, helps you execute task based procedures)
  • Escape analysis (improvement in allocating memory for objects based on the scope of the object)
  • Project jigsaw (module management)
  • Compressed 64 bit pointers (store 64 bit pointers in 32 bit)
  • Garbage first collector (new algorithm for garbage collecting)

That’s it for now, I didn’t have the time to start playing around with the new Beta of jdk7. Hope to get started soon!

Using a custom Oracle collection type with iBatis

By Rob, September 17, 2009 8:28 pm

Some months ago I came across a problem with the more complex custom Oracle types in combination with iBatis. I thought that it would be nice to share it with you. In my case I had to link a list of objects in Java to an array of structs in SQL (Oracle).

The biggest part of the trick is inside a custom type handler, which is actually a helper class with two important methods, the setParameter and the getResult. setParameter if for mapping parameters before firing the query and the getResult is for processing the result (if you use a custom type as an OUT parameter). For the example I used a Quantity class which has two properties, id and quantity. My Oracle types are a struct (Quantity) and a table of that struct (QuantityList)

The code will show you the rest, because once you know how to deal with this, other cases are quite easy.

package nl.tigrou.test;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import java.util.List;
import oracle.jdbc.driver.OracleTypes;
import oracle.sql.ARRAY;
import oracle.sql.ArrayDescriptor;
import oracle.sql.STRUCT;
import oracle.sql.StructDescriptor;

import org.springframework.jdbc.support.nativejdbc.C3P0NativeJdbcExtractor;
import org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor;

import com.ibatis.sqlmap.client.extensions.ParameterSetter;
import com.ibatis.sqlmap.client.extensions.ResultGetter;
import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;
import com.ibatis.sqlmap.engine.type.JdbcTypeRegistry;
import com.mchange.v2.c3p0.impl.NewProxyConnection;

public class QuantityListTypeHandler implements TypeHandlerCallback
{

  private static final String QUANTITY = "QUANTITY";
  private static final String QUANTITYLIST = "QUANTITYLIST";

  static
  {
    JdbcTypeRegistry.setType(QUANTITY, OracleTypes.STRUCT);
    JdbcTypeRegistry.setType(QUANTITYLIST, OracleTypes.ARRAY);
  };  

  public void setParameter(ParameterSetter setter, Object parameter) throws SQLException
  {
    try
    {
      List<Quantity> quantities = (List<Quantity>) parameter;

      Connection conn = setter. getPreparedStatement(). getConnection();
      if(conn instanceof NewProxyConnection)
      conn = new C3P0NativeJdbcExtractorImpl().getNativeConnection(conn);

      StructDescriptor quantityStruct = StructDescriptor.createDescriptor(QUANTITY, conn);
      ArrayDescriptor quantityList = ArrayDescriptor.createDescriptor(QUANTITYLIST, conn);

      STRUCT[] elements = new STRUCT[quantities == null ? 0 : quantities.size()];

      for (int count = 0; count < elements.length; count++)
      {
        Quantity quantity = quantities.get(count);

        elements[count] = new STRUCT(quantityStruct, conn, new Object[] { quantity.getId(), quantity.getQuantity() });
      }

      ARRAY array = new ARRAY(quantityList, conn, elements);

      setter.setArray(array);
    } catch (SQLException sqle)
    {
      throw sqle;
    }
  }

  private class C3P0NativeJdbcExtractorImpl extends C3P0NativeJdbcExtractor
  {
    public Connection getNativeConnection(Connection con) throws SQLException
    {
      return doGetNativeConnection(con);
    }
  }

  public Object getResult(ResultGetter getter) throws SQLException
  {
    ARRAY array = (oracle.sql.ARRAY) getter.getArray();
    ResultSet rs = array.getResultSet();
    List<Quantity> quantities = new ArrayList<Quantity>();
    while (rs != null &amp;amp;amp;&amp;amp;amp; rs.next())
    {
     STRUCT struct = (STRUCT) rs.getObject(2);
     Object[] attribs = struct.getAttributes();
     Quantity quantity = new Quantity();
     quantity.setId(((java.math.BigDecimal) attribs[0]).longValue());
     quantity.setQuantity(((java.math.BigDecimal) attribs[1]).intValue());
     quantities.add(quantity);
    }
    return quantities;
  }

  public Object valueOf(String value)
  {
    if (value == null)
      return new ArrayList<Quantity>();
    return value;
  }
}

And the corresponding query in one of your xml mapping files. The magic is all inside the inline parameter.

SELECT * FROM sometable x
LEFT JOIN TABLE (
  CAST
  (
    #quantities,handler=quantityListTypeHandler,jdbcType=STRUCT,javaType=Quantity# AS QuantityList
  )
) s ON (s.identifier = x.id)

BTW, if you haven’t noticed it yet, iBatis 3 is about to release. Check out the release candidates because they did an awesome job!

AOP Advices and Aspect combinations

By Rob, June 14, 2009 8:37 pm

It’s about a month ago that I was completely stucked with a Spring AOP configuration. While working on a better transaction management (see older post), I kept struggling in a circle of either a non functioning transaction system or broken AOP aspects. It really drove me nuts so I decided to avoid that pain for somebody else. No examples and code this time, just a simple pointer to the Spring documentation (which clearly took too much time to find :) ).

Let’s start with the note in the documentation:

Advising aspects

In Spring AOP, it is not possible to have aspects themselves be the target of advice from other aspects. The @Aspect annotation on a class marks it as an aspect, and hence excludes it from auto-proxying.

(Source – Spring reference docs)

After searching a bit more information, since the text above not really explains why they’re excluded, I found the following 2 “rules”:

  • Classes with annotations @AspectJ and classes that implement or extend any other AOP component are excluded from the autoproxy. This is because they aren’t target classes, and they perform tasks in Spring AOP infrastructure.
  • Proxy is not applied to beans that implement the interfaces BeanPostProcessor or BeanFactoryPostProcessor. The class AnnotationAwareAspectJAutoProxyCreator implements the interface BeanPostProcessor, which allows the class to modify the life cycle of beans on which a proxy must be created and applied.

The first point here explains why Aspects are not proxied. The second point names another condition.

So, conclusion:

Never use Aspects (@Apects) and proxy based transaction management on the same bean!

It’s simple to avoid by creating a separate Aspect which advices other beans. Something like this:

@Aspect
public class TestAspect
{

  @Before("execution(* someThing) ")
  public void doSomethingElse()
  {

  }
}

That’s it! At the moment I’m working on the website of my local athletics club, with CodeIgniter I’m finally enjoying PHP programming again.

Spring’s ThreadLocalTargetSource

By Rob, May 9, 2009 10:50 am

ThreadLocalTargetSource, as the name already explains, is a proxied ThreadLocal helper class. Spring provides this class together with other pooling mechanisms as a better version of the Sun’s ThreadLocal class. One of the benefits is the already created wrapper class around the threadlocal and much more important, it destroys automatically the old thread references when the BeanFactory is destructed.

But actually these kind of features always sound to good to be true to me. I really wanted to figure out how safe it is and how far you can go. A simple testapplication showed me that it’s absolutely powerful!

So far I didn’t have much experience with ThreadLocal’s, they sound a bit evil to but on the other hand very useful. And I was afraid for the memory usage, keeping objects in memory per thread must have its cost. But Spring insures me that the objects will be automatically removed as soon as possible, although that still means that objects can live quite some time. Especially the automatically destroy functionality was for me a good reason to use the ThreadLocalTargetSource and not a custom wrapper for a ThreadLocal. If you really would like to use the ThreadLocal, be sure that you don’t forget to unset the object for every requestcycle. Otherwise it’s a just a matter of time before your application will start throwing Java heap space errors :) .

Now it’s time for my example, to start with the bean config:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

<bean id="testBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="targetSource" ref="testThreadLocalTargetSource" />
</bean>
<bean id="testBeanUtil" class="nl.tigrou.threadlocal.TestBeanUtil">
<property name="testBean" ref="testBean" />
</bean>
<bean id="testThreadLocalTargetSource" class="org.springframework.aop.target.ThreadLocalTargetSource"
destroy-method="destroy">
<property name="targetBeanName" value="testTarget" />
</bean>
<bean id="testTarget" class="nl.tigrou.threadlocal.TestBeanImpl" scope="prototype">
<property name="myValue" value="boe!" />
</bean>
</beans>

A simple Pojo:


public class TestBeanImpl implements TestBean {

private String myValue;

public void setMyValue(String myValue) {
this.myValue = myValue;
}

public String getMyValue() {
return myValue;
}

}

A util class to test the proxy’ing even better:


public class TestBeanUtil {

private static TestBean testBean;

public void setTestBean(TestBean testBean) {
TestBeanUtil.testBean = testBean;
}

public static TestBean getTestBean() {
return testBean;
}
}

And a simple testclient with 2 testcases:


public class ThreadLocalTest {

private ClassPathXmlApplicationContext context;

public static void main(String[] args) {
new ThreadLocalTest();
}

public ThreadLocalTest() {

context = new ClassPathXmlApplicationContext("applicationContext.xml");

for(int i=0; i < 10; i++)
{
ThreadTest test = new ThreadTest(i);
test.setName("Thread1-"+i);
test.start();
}

for(int i=0; i < 10; i++)
{
Thread2Test test2 = new Thread2Test(i);
test2.setName("Thread2-"+i);
test2.start();
}
}

private class ThreadTest extends Thread
{
private final int number;

public ThreadTest(int number) {
this.number = number;

}

public void run() {
TestBean testBean = (TestBean) context.getBean("testBean");

testBean.setMyValue(String.valueOf(number));
System.out.println(Thread.currentThread().getName() + ", bean value: " + testBean.getMyValue());

}
}

private class Thread2Test extends Thread
{
private final int number;

public Thread2Test(int number) {
this.number = number;

}

public void run() {

TestBeanUtil.getTestBean().setMyValue(String.valueOf(number));
System.out.println(Thread.currentThread().getName() + ", bean value: " + TestBeanUtil.getTestBean().getMyValue());

}
}

}

The above testclient starts 10 x 2 threads where both different threadclasses read and set the value in the threadlocal. The result in the console is:

Thread1-0, bean value: 0
Thread1-2, bean value: 2
Thread1-3, bean value: 3
Thread2-4, bean value: 4
Thread1-4, bean value: 4
Thread2-5, bean value: 5
Thread1-9, bean value: 9
Thread2-6, bean value: 6
Thread2-2, bean value: 2
Thread1-7, bean value: 7
Thread2-0, bean value: 0
Thread2-1, bean value: 1
Thread2-8, bean value: 8
Thread1-5, bean value: 5
Thread1-8, bean value: 8
Thread1-6, bean value: 6
Thread2-3, bean value: 3
Thread2-7, bean value: 7
Thread2-9, bean value: 9
Thread1-1, bean value: 1

Totally random order of execution as you can expect with threads but never a duplicate combination of threadnumber and value! Very simple but very powerful. You can access the beanvalues from everywhere withing the same thread, even with a static reference in a util class.

Next subject, my AOP headache issue with a combination of Advices and Aspects.

Nested transactions and their db connections

By Rob, April 28, 2009 10:21 pm

Last week I was researching the AOP config from an big application because I wasn’t really happy with the way it was implemented right now. The idea was to improve the performance by reducing the number of calls initiated by the AOP proxy. But there was a thing I wasn’t really sure about. How does Spring handle transactions when there are nested service class calls from one service to the other?

When I don’t how something exactly works, I create a small sample application. Nothing shocking, just a sample app which gives me the possibility to look to the different transaction propagations. And who knows if it could help other people as well, so I added the idea to my blog.

Let’s start with the Spring application context:


<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

http://www.springframework.org/schema/aop

http://www.springframework.org/schema/aop/spring-aop-2.5.xsd

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

<aop:aspectj-autoproxy/>

<tx:advice id="txAdvice" transaction-manager="txManager">

<tx:attributes>
<!-- normally you would exclude read actions from required transactions but I only wrote a get method for testing purpose -->
<!-- tx:method name="get*" propagation="SUPPORTS" read-only="true" /-->
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>

<aop:config>
<aop:pointcut id="serviceOperation" expression="bean(*Service)"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOperation"/>
</aop:config>

<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost/world" />
<property name="user" value="" />
<property name="password" value="" />
</bean>

<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="WEB-INF/sqlmapconfig.xml" />
<property name="dataSource" ref="dataSource" />
</bean>

<bean id="countryService" class="nl.tigrou.test.service.CountryServiceImpl">
<property name="countryDao" ref="countryDao" />
<property name="cityService" ref="cityService" />
</bean>

<bean id="countryDao" class="nl.tigrou.test.persistence.CountryDaoImpl">
<property name="sqlMapClient" ref="sqlMapClient" />
</bean>

<bean id="cityService" class="nl.tigrou.test.service.CityServiceImpl">
<property name="cityDao" ref="cityDao" />
</bean>

<bean id="cityDao" class="nl.tigrou.test.persistence.CityDaoImpl">
<property name="sqlMapClient" ref="sqlMapClient" />
</bean>

</beans>

The only interesting thing in here is the tx:advice element defining the right propagation settings.

Now the pieces of Java code:


// grab countries
List<Country> countries = countryService.getCountries();

// this is the getCountries method
// which is btw a good example of how you shouldn't do this with iBatis
// always try to avoid N+1 selects!
List<Country> countries = countryDao.getCountries();
for(Country country: countries){
List<City> cities = cityService.getCities(country.getCode());
country.setCities(cities);
}

That’s all! Now enable the debug logging on for example the org.springframework.jdbc.datasource package and you’ll see something like this:

2009-04-28 22:07:47,591 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Creating new transaction with name [nl.tigrou.test.service.CountryService.getCountries]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
2009-04-28 22:07:48,684 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Acquired Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@46d0cc] for JDBC transaction
2009-04-28 22:07:48,821 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Participating in existing transaction
2009-04-28 22:07:48,829 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Participating in existing transaction
2009-04-28 22:07:48,832 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Participating in existing transaction
2009-04-28 22:07:48,834 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Participating in existing transaction
2009-04-28 22:07:48,837 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Participating in existing transaction
2009-04-28 22:07:48,839 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Participating in existing transaction
2009-04-28 22:07:48,840 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Participating in existing transaction
2009-04-28 22:07:48,842 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Participating in existing transaction
2009-04-28 22:07:49,376 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Initiating transaction commit
2009-04-28 22:07:49,376 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Committing JDBC transaction on Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@46d0cc]
2009-04-28 22:07:49,376 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceTransactionManager - Releasing JDBC Connection [com.mchange.v2.c3p0.impl.NewProxyConnection@46d0cc] after transaction
2009-04-28 22:07:49,378 [http-8080-1] DEBUG org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource

As you see, Spring initializes a transaction and when another transaction is about to start, Spring runs these other db calls inside the existing transaction. Of course you can heavily influence this by changing the transaction propagation.

Conclusion: Spring did the job exactly as expected and I’m pretty happy with the solution as well.

btw, next subject is probably the use of Spring’s ThreadLocalTargetSource.

Panorama Theme by Themocracy