Archive for the ‘Java’ Category

Java: Image IO, JAI

Friday, August 21st, 2009

Docs

Sample code links:

  • The Perils of Image.getScaledInstance() (Best algorigthm to scale down/up images with ImageIO)
    • “… be aware that if you try to downscale an image by a factor of more than two (i.e., the scaled instance is less than half the size of the original), and you are using the BILINEAR or BICUBIC hint, the quality of the scaled instance may not be as smooth as you might like…. To combat this issue, you can use a multi-step approach when downscaling by more than two times; this helps prevent the information loss issue and produces a much higher quality result that is visually quite close to that produced by Image.SCALE_AREA_AVERAGING.”
  • JAI Tutorial (Sun)
  • Resizing with JAI
  • Resizing with JAI (Subsample for best result)

Other Samples

Java: Sorting List with Comparator

Tuesday, August 18th, 2009
class EmpSortByName implements Comparator{

    public int compare(Employee o1, Employee o2) {
        return o1.getName().compareTo(o2.getName());
    }
}

....
List employees = ...;
Collections.sort(employees , new EmpSortByName());

java.lang.Comparable: int compareTo(Object o1)
This method compares this object with o1 object. Returned int value has the following meanings.

  1. positive – this object is greater than o1
  2. zero – this object equals to o1
  3. negative – this object is less than o1

java.lang.Comparator: int compare(Object o1, Objecto2)
This method compares o1 and o2 objects. Returned int value has the following meanings.

  1. positive – o1 is greater than o2
  2. zero – o1 equals to o2
  3. negative – o1 is less than o1

Source: Java Sorting: Comparator vs Comparable Tutorial

Java: BeanUtils Enum Support - generic Enum converter

Monday, July 6th, 2009

By default, apache commons BeanUtils does not support string value to their targeted Enum. You can write a converter for each enum, but this quickly become unmanageable.

Here is a quick fix to automatically convert the string value to the targeted enum.

BeanUtilsBean beanUtilsBean = new BeanUtilsBean(new ConvertUtilsBean(){
            @Override
            public Object convert(String value, Class clazz) {
                  if (clazz.isEnum()){
                       return Enum.valueOf(clazz, value);
                  }else{
                       return super.convert(value, clazz);
                  }
           }
        });

Now, you can call beanUtilsBean.populate(bean,map) even for enum values.

Hibernate: Supporting Spring DataSourceTransactionManager (and @Transactional) programmatically with SessionFactoryUtils

Sunday, July 5th, 2009

Here is the minimum code to support DataSourceTransactionManager thread bound session  (similar to OpenSessionInViewInterceptor).

For each thread:

public void beginThreadSession(SessionFactory sessionFactory){

  Session session = SessionFactoryUtils.getSession(sessionFactory, true);
  TransactionSynchronizationManager.bindResource(sessionFactory,
                                               new SessionHolder(session));

}
public void endThreadSession(SessionFactory sessionFactory){

  SessionHolder sessionHolder =
    (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
  SessionFactoryUtils.closeSession(sessionHolder.getSession());

}

DataSourceTransactionManager will pickup the thread bound session with SessionFactoryUtils. The trick is calling the “un/bindResource” methods. This set one session for all your requests and transactions for a given thread (and use the @transactional if you have configured it as follow).

<aop:config proxy-target-class="true"/>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
    <property name="configLocation" value="config/hibernate.cfg.xml"/>
    <property name="dataSource" ref="dataSource"/>
</bean>

<tx:annotation-driven transaction-manager="txManager"/>

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

Obviously, this is the strict minimum code (good of unit testing for example). For Web App, use the OpenSessionInViewInterceptor.

<bean id="openSessionInView"
class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
    <property name="sessionFactory" ref="sessionFactory"/>
    <!-- optional
    <property name="flushModeName" value="FLUSH_NEVER" />
    -->
</bean>

Hibernate: org.hibernate.WrongClassException … instanceAlreadyLoaded

Monday, May 4th, 2009

Hibernate inheritance and relationship could lead to the following exception:

Caused by: org.hibernate.WrongClassException: Object with id: 3 was not of the
specified subclass...
...
        at org.hibernate.loader.Loader.instanceAlreadyLoaded(Loader.java:1267)
        at org.hibernate.loader.Loader.getRow(Loader.java:1219)
        at org.hibernate.loader.Loader.getRowFromResultSet(Loader.java:603)
        at org.hibernate.loader.Loader.doQuery(Loader.java:724)
...

Putting @ForceDiscriminator near the @DiscriminatorValue(..) of your respective classes might solve the problem.
See Hibernate Annotation Doc

Java: c3p0.ComboPooledDataSource broken pipe Error With MySQL

Monday, April 13th, 2009

This usually happen when the client connection pool maintained connection longer than the database connection. Fix: set the maxIdleTime property:

 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
  <property name="driverClass" value="${db.driverClass}" />
  <property name="jdbcUrl" value="${db.jdbcUrl}" />
  <property name="user" value="${db.user}" />
  <property name="password" value="${db.password}" />
  <!-- 1/2 hr. MySQL server default connection timeout is 43200 (12hrs) -->
  <property name="maxIdleTime" value="1800" />
 </bean>

Information Source: Broken pipe

Java: JODConverter 3.x Getting Started

Thursday, April 9th, 2009

Requirements:

  • OpenOffice installed and OpenOffice started (e.g., OpenOffice in the system tray on Windows)
  • Java

Quick steps to test:

  1. Download the latest JODConverter 3.x from google code.
  2. Unzip the jar file
  3. Do a quick test:
    java -jar lib/jodconverter-${version}.jar test.odt test.pdf
  4. you should see something like
    C:\apps\jodconverter-3.0-beta-1>java -jar lib/jodconverter-3.0-beta-1.jar test.odt test.pdf
    
    Apr 9, 2009 12:56:42 PM net.sf.jodconverter.office.OfficeProcess start
    INFO: starting process with acceptString 'socket,host=127.0.0.1,port=8100' and
    profileDir 'C:\Users\JEREMY~1\AppData\Local\Temp\.jodconverter_socket_host-127.0.0.1_port-8100'
    Apr 9, 2009 12:56:42 PM net.sf.jodconverter.office.OfficeProcess start
    INFO: started process; pid -1
    Apr 9, 2009 12:56:47 PM net.sf.jodconverter.office.OfficeConnection connect
    INFO: connected: 'socket,host=127.0.0.1,port=8100'
    Apr 9, 2009 12:56:52 PM net.sf.jodconverter.office.OfficeConnection$1 disposing
    INFO: disconnected: 'socket,host=127.0.0.1,port=8100'
    Apr 9, 2009 12:56:53 PM net.sf.jodconverter.office.ManagedOfficeProcess doEnsureProcessExited
    INFO: process exited with code 0

Note: As you can see it works because it assumes that OpenOffice listen to the port 8100, which happen to be the case (how lucky!).

In a Java (Server) App:

  1. Copy the following .jar files in your webapp lib directory
    lib/jodconverter-3.0-beta-1.jar
    lib/juh-3.0.0.jar
    lib/jurt-3.0.0.jar
    lib/ridl-3.0.0.jar
    lib/unoil-3.0.0.jar
  2. Use the following code snippet:
    OfficeManager officeManager = new ManagedProcessOfficeManager();
    officeManager.start();
    
    OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
    converter.convert(sourceFile,targetFile);
    
    officeManager.stop();

Best Practice (from JODConverter group)

  1. OfficeManager instance can and should be shared across all
    threads
    . It should typically be started when your webapp starts, and
    stopped when the webapp stops. It can be e.g. a singleton, or a Spring
    bean, or other equivalent approach of your choice.
  2. The OfficeDocumentConverter instance can also be shared, or you can
    create a different instance per thread. It doesn’t really matter,
    since all conversions will be delegated to the OfficeManager anyway.

See Also

RegEx: Java Quick Start and Tips

Wednesday, April 8th, 2009

Java: Word, RTF, PDF convert, read, import, export, write

Tuesday, April 7th, 2009

Reading/Writing Word and PDF document could be quite tricky.

For Word (.doc), the best option seems to be using OpenOffice to convert the file to a text format (RTF or OpenOffice XML format), modify the text document, and use OpenOffice to convert back to .doc. JODConverter 3.x seems to be a great option for doing that in a Web Application.

For PDF, iText seems to be the solution.

There seems to be also a very complete and mature commercial product for Java which is Aspose. It supports direct access to Office documents such as .doc file allowing to preserve any meta data such as revision and such. Its a little pricey but manageable for a SaaS application, although, I am not sure how their definition of “location” applies to a SaaS application.

Here are some pointers:

Word:

RTF:

PDF:

  • IText (download): Java Lib to read/create PDF document.
  • FOP: reads a formatting object (FO) tree and renders the resulting pages to a specified output (The primary output target is PDF)

Java: Servlet Set Expires Header with Cache Control

Saturday, March 28th, 2009

When setting the expires date in Servlet, better to set the cache-control as well.

final int CACHE_DURATION_IN_SECOND = 60 * 60 * 24 * 2; // 2 days
final long   CACHE_DURATION_IN_MS = CACHE_DURATION_IN_SECOND  * 1000;
long now = System.currentTimeMillis();
//res being the HttpServletResponse of the request
res.addHeader("Cache-Control", "max-age=" + CACHE_DURATION_IN_SECOND);
res.addHeader("Cache-Control", "must-revalidate");//optional
res.setDateHeader("Last-Modified", now);
res.setDateHeader("Expires", now + CACHE_DURATION_IN_MS);

For no cache

res.setHeader("Pragma", "No-cache");
res.setHeader("Cache-Control", "no-cache,no-store,max-age=0");
res.setDateHeader("Expires", 1);