Programming and So

Tips and tricks in Java

Archive for August 2008

The encoding chain

without comments

UTF-8 charset is normally used as default in all the components of a Java software system from database to web browser.  Refer these links in order to get information about it.

However, external files can be served by other systems in any charset different to UTF-8. To preserve encoding chain, file reading must be done specifying external charset in these terms.

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class TestEncoding {

  public static void processFile(String filename, String charset) throws IOException {

    FileInputStream fstreamIn = new FileInputStream(filename);
    DataInputStream in = new DataInputStream(fstreamIn);

    // Specify charset for the InputStream
    BufferedReader br = new BufferedReader(
        new InputStreamReader(in, charset));

    String strLine;
    while ((strLine = br.readLine()) != null)   {
      // Do something with the line: insert into database, ...
    }

    fstreamIn.close();

  }

  public static void main(String...strings) throws IOException {

    String filename = "/hosts/data.input";
    String charset = "ISO-8859-15";

    processFile(filename, charset);

  }

}

Written by angelborroy

August 21, 2008 at 11:23 am

Posted in java

Tagged with

Loading Spring context and its consequences

without comments

Let’s say we have an application trying to insert a row on some table. Using Spring JDBC techniques, we must define one Spring XML context file as next.

< ?xml version="1.0" encoding="UTF-8"?>
< !DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

  <bean id="datasource"
    class="org.springframework.jdbc.datasource.SingleConnectionDataSource"
    destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:SID" />
<property name="username" value="user" />
<property name="password" value="pass" />
  </bean>

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

  <bean id="transactionTemplate"
    class="org.springframework.transaction.support.TransactionTemplate">
<property name="transactionManager"><ref bean="transactionManager" /></property>
  </bean>

  <bean id="someDAO" class="es.foo.db.dao.ComercioDAO" />

</beans>

We can define too a class in order to simplify the process of getting transactions and DAOs from Spring Context. Below two alternatives are shown: DBManager class and StaticDBManager class.

DBManager is coded in a dynamic way…

public class DBManager {

  private ClassPathResource resource;
  private XmlBeanFactory xmlFactory;

  public DBManager() {
    resource = new ClassPathResource("/es/foo/db/spring-config.xml", DBManager.class);
        xmlFactory = new XmlBeanFactory(resource);
  }

  public JdbcDaoSupport getDAO(String daoName) {
        DataSource dataSource = (DataSource)xmlFactory.getBean("datasource");
        JdbcDaoSupport dao = (JdbcDaoSupport)xmlFactory.getBean(daoName);
        dao.setDataSource(dataSource);
        return dao;
  }

  public TransactionTemplate getTransactionTemplate() {
    return (TransactionTemplate)xmlFactory.getBean("transactionTemplate");
  }

}

… while StaticDBManager is coded in a static way.

public class StaticDBManager {

  public static JdbcDaoSupport getDAO(String daoName) {
    ClassPathResource resource = new ClassPathResource("/es/foo/db/spring-config.xml", StaticDBManager.class);
    XmlBeanFactory xmlFactory = new XmlBeanFactory(resource);
    DataSource dataSource = (DataSource)xmlFactory.getBean("datasource");
    JdbcDaoSupport dao = (JdbcDaoSupport)xmlFactory.getBean(daoName);
    dao.setDataSource(dataSource);
    return dao;
  }

  public static TransactionTemplate getTransactionTemplate() {
    ClassPathResource resource = new ClassPathResource("/es/foo/db/spring-config.xml", StaticDBManager.class);
    XmlBeanFactory xmlFactory = new XmlBeanFactory(resource);
    return (TransactionTemplate)xmlFactory.getBean("transactionTemplate");
  }

}

Without thinking of it deeply, we can imagine both solutions working in the same way.

public class SpringDBTest {

  class DoWork implements TransactionCallback {

    private DBManager db;

    public DoWork(DBManager db) {
      this.db = db;
    }

    public Object doInTransaction(TransactionStatus ts) {
      SomeDAO someDAO = (SomeDAO) db.getDAO("someDAO");
      someDAO.insert();
      return null;
    }

  }

  public static void main(String... args) throws Exception {

    // Test 1 - Load Spring Context once
    DBManager db = new DBManager();
    TransactionTemplate ttDynamic = db.getTransactionTemplate();
    ttDynamic.execute(new SpringDBTest().new DoWork(db));

    // Test 2 - Load Spring Context statically twice
    TransactionTemplate ttStatic = StaticDBManager.getTransactionTemplate();
    ttStatic.execute(new TransactionCallback() {
      public Object doInTransaction(TransactionStatus ts) {
        try {
          SomeDAO someDAO = (SomeDAO) StaticDBManager.getDAO("someDAO");
          someDAO.insert();
        } catch (RuntimeException re) {
          ts.setRollbackOnly();
          re.printStackTrace();
        }
        return null;
      }
    });

  }

}

However, running the code, no rollback is performed on Runtime Exception for Test 2.

This behavior is caused by Spring Context load in StaticDBManager class. Doing the initialization so, two different instances of datasource object are generated (one for the transaction and another one for the DAO) due to Spring Injection mechanism. So, in Test 2, transactional context is lost on execution.

Written by angelborroy

August 19, 2008 at 4:50 pm

Posted in java

Tagged with

Using Portecle to replace command line Keytool interface

without comments

Usually default keytool from Sun’s JDK is used to perform local testing on applications involving crytographic operations. Portecle is a nice alternative to achieve a Windows-like behaviour of this tool. It can be launched writing a simple CMD script and executing it from desktop.

START javaw -jar C:\portecle-1.3\portecle.jar
EXIT

Written by angelborroy

August 18, 2008 at 4:47 pm

Posted in java

Tagged with