Writing file system independent applications with commons-vfs

Lately I’ve been playing with commons virtual file system
(commons-vfs), which is a really cool way to make your application file
system independent. You can write the same code to access files in your
local file system, samba servers, sftp servers, http, webdav,… see the complete list.

        FileSystemManager fileSystemManager = VFS.getManager();
        FileObject from = fileSystemManager.resolveFile(getFrom());
        FileObject to = fileSystemManager.resolveFile(getTo(), getFileSystemOptions());
        to.copyFrom(from, new AllFileSelector());

The application context with Spring would be something like the
following. You can see that setting the file system options it’s a pita
because they don’t follow the beans convention and you need to call
different methods instead of setting bean properties. I hop they change
ths in next versions.

    <bean id="myBean" class="TestBean">
        <property name="from" value="http://www.myserver.com/filename"/>
        <property name="to" value="sftp://username:password@myserver.com/home/whatever"/>
        <property name="fileSystemOptions" ref="sftpFileSystemOptions"/>
    </bean>

    <bean id="sftpFileSystemConfigBuilder"
          class="org.apache.commons.vfs.provider.sftp.SftpFileSystemConfigBuilder"
          factory-method="getInstance"/>

    <bean id="sftpFileSystemOptions" class="org.apache.commons.vfs.FileSystemOptions"/>

    <bean id="sftpFileSystemOptions_disableStrictHostKeyChecking"
          class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetObject" ref="sftpFileSystemConfigBuilder"/>
        <property name="targetMethod" value="setStrictHostKeyChecking"/>
        <property name="arguments">
            <list>
                <ref local="sftpFileSystemOptions"/>
                <value>no</value>
            </list>
        </property>
    </bean>

    <!-- use private key instead of password -->
    <bean id="sftpFileSystemOptions_setIdentities"
          class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetObject" ref="sftpFileSystemConfigBuilder"/>
        <property name="targetMethod" value="setIdentities"/>
        <property name="arguments">
            <list>
               <ref local="sftpFileSystemOptions"/>
               <list><value>Path to the ssh identity file</value></list>
            </list>
        </property>
    </bean>

Another drawback is that you need to build from sources, no releases are available yet 😦

Managing your clustered application with jManage

One of the drawbacks of JMX is the lack of cluster support, you have
to invoke the operation in each one of the servers. The solution? use a
JMX client that does that for you, as jManage.
You setup the servers as in any other administration console and then
you can group them in clusters, allowing you to see the value of the
properties in each one of the servers in the cluster and invoke operations
in all of them getting the results of each server in a single page.

Using jManage with JBoss 4

Download jManage version 0.5.3.

Go to jmanage-0.5.3/modules/jboss and copy there the following jars from jboss installation.

  • jboss-4.0.2/client/jbossall-client.jar
  • jboss-4.0.2/lib/jboss-jmx.jar

Start JBoss servers with the java option  -Djava.rmi.server.hostname=hostname (you can set JAVA_OPTS environment variable)

Run jManage with jmanage-0.5.3/bin/startup.sh, you’ll be asked for a password (123456 by default). Then you can login at http://localhost:9090 with username/password admin/123456

Hibernate 3.0.5 statistics + TreeCache bugs

When working at a client site we decided to enable Hibernate
statistics, so we can access all this information about cache
hits/misses, transactions, entities,… and all kind of cool stuff
through a JMX interface at runtime, allowing runtime configuration
changes and monitoring.

But seems that not many people is using this feature, because we
got the frustrating NullPointerException. After debugging a bit through
the Hibernate sources (if you have ever tried you know that it’s a PITA) I found the errors, same exception in two places,
and told JBoss support (the client was paying for it). Anyway I fixed them
locally while they fixed them in CVS, see the cvs diff or the JIRA issue. This bugs are present in hibernate 3.0.5 when using TreeCache.

Now we can get a lot of useful information at runtime, through a JMX console, I really like jManage,
mostly due to it’s cluster support, but you’ll need some tricks to make
it run with JBoss 4, that I’ll post in a separate entry.

dbUnit, useful more than just for unit tests

I really like dbUnit for unit tests, but I like it more for other
tasks, as exporting data from the database in xml or Excel formats with
a few lines of code and without bothering about writing xml tags or
interacting with POI to write Excel cells.

For
instance the next code can be used to export the result of a query into
an Excel file.

public class Report {

    private DataSource dataSource;

    public void exportData() throws Exception {

        IDatabaseConnection connection = new DatabaseConnection(dataSource
                .getConnection());

        try {

            // partial database export
            QueryDataSet partialDataSet = new QueryDataSet(connection);

            String query =
                    "SELECT a, b FROM t WHERE a = 'whatever'");

            partialDataSet.addTable("Report", query);
            XlsDataSet.write(partialDataSet, new FileOutputStream(
                    "report.xls"));

        } finally {
            connection.close();
        }

    }

Inheriting annotations from implemented interfaces

In relation to Rick Hightower entry on annotations and inheritance I also checked if annotations on implemented interfaces are accesible
from the class implementing them. The answer is NO, neither using the
@Inherited annotation on the annotation class. The only way is getting
the implemented interfaces and iterate over them to see if they have
annotations.

public class AnnotationTest extends TestCase {

    @Retention(RetentionPolicy.RUNTIME) // This makes the annotation available at runtime
    @Inherited
    public static @interface Developer {
        String name();

        String email() default “somebody@somewhere.com”;

        int rank() default 1;
    }

    // Using the annotation to decorate a class and a method
    @Developer(name = “RickHightower”)
    interface MyInterface {
        @Developer(name = “ScottFauerbach”, email = “foobar@foo.com”)
        void myMethod();
    }

    class MyClassSub implements MyInterface {
        
        public void myMethod() {
            // …
        }
    }

    // Testing the annotation
    public void testAnnotation() throws Exception {
        assertFalse (MyClassSub.class.isAnnotationPresent(Developer.class));
        Method method2 = MyClassSub.class.getMethod(“myMethod”, (Class[]) null);
        assertFalse (method2.isAnnotationPresent(Developer.class));
        
        Class[] interfaces = MyClassSub.class.getInterfaces();
        boolean annotationPresent = false;
        for (Class iClass : interfaces) {
            if (iClass.isAnnotationPresent(Developer.class)) {
                   
annotationPresent = true;
                    break;
            }
        }
        assertTrue(annotationPresent);
    }
}

Spring Framework 1.2.2 released

Juergen has annonced the release of Spring 1.2.2, which I’ll make
available for maven users in a few hours through the central repository
at ibiblio. This has came out before having time to finish the Maven 2
POMs for 1.2.1, so I’ll try to update them to 1.2.2 asap.

Dear Spring community,

I’m pleased to announce that Spring 1.2.2 has just been released. This is a
bugfix and minor enhancement release. It also provides a unified basis for
the upcoming Spring WebFlow release candidate.

Besides refinements in the JTA transaction synchronization and SQLException
translation, this release introduces a variety of internal refactorings and
new helper classes. Furthermore, support for JDK 1.5’s XML-based properties
format has been added to all relevant Spring classes.

We have also extended our reference documentation in various areas. Most
importantly, it covers JDO, TopLink, OJB, and JCA CCI now.

Cheers,

Juergen

Spring: creating a bean of type java.util.Properties

I don’t know if there’s a simple way to crate a Spring bean of type java.util.Properties . This is what I needed to do.

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" depends-on="hibernateProperties.load">
  <property name="dataSource"><ref local="dataSource"/></property>
  <property name="configLocation"><value>classpath:net/lmb/resources/hibernate.cfg.xml</value></property>
  <property name="configurationClass"><value>org.hibernate.cfg.AnnotationConfiguration</value></property>
  <property name="hibernateProperties"><ref local="hibernateProperties"/></property>
</bean>

<bean id="hibernateProperties" class="java.util.Properties"/>
<bean id="hibernateProperties.load" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
  <property name="targetObject"><ref local="hibernateProperties"/></property>
  <property name="targetMethod"><value>putAll</value></property>
  <property name="arguments">
    <props>
      <prop key="hibernate.dialect">${hibernate.dialect}</prop>
      <prop key="hibernate.query.substitutions">${hibernate.query.substitutions}</prop>
      <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
      <prop key="hibernate.cglib.use_reflection_optimizer">${hibernate.cglib.use_reflection_optimizer}</prop>
      <prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>
      <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
      <prop key="hibernate.connection.username">${hibernate.connection.username}</prop>
      <prop key="hibernate.connection.password">${hibernate.connection.password}</prop>
    </props>
  </property>
</bean>

Basically you need to create an empty bean of type java.util.Properties, and after you add the properties using Spring <props> syntax calling the method putAll. One of the tricky parts is that you need to explicitly state the depends-on attribute in the LocalSessionFactoryBean so properties get loaded before the hibernate session is created.

Update:

Marc Logemann has posted a much more elegant solution using Spring’s PropertiesFactoryBean

<bean id="hibernateProperties"
     class="org.springframework.beans.factory.config.PropertiesFactoryBean">
  <property name="properties">
    <props>
      <prop key="hibernate.dialect">${hibernate.dialect}</prop>
      <prop key="hibernate.query.substitutions">${hibernate.query.substitutions}</prop>
      <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
      <prop key="hibernate.cglib.use_reflection_optimizer">${hibernate.cglib.use_refl}</prop>
      <prop key="hibernate.cache.provider_class">${hibernate.cache.provider_class}</prop>
      <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
      <prop key="hibernate.connection.username">${hibernate.connection.username}</prop>
      <prop key="hibernate.connection.password">${hibernate.connection.password}</prop>
    </props>
  </property>
</bean>

Spring JMX support

Spring provides a nice way to expose plain java objects and its
methods and properties as JMX managed objects. Maybe the best way to do
so is using annotations.

@ManagedResource(
        objectName = "domain:name=testBean",
        description = "A test Spring-JMX bean")
public class JmxTestBean {

    private int age;

    private String name;

    @ManagedAttribute(description = "age attribute")
    public void setAge(int age) {
        logger.info("setAge");
        this.age = age;
    }

    @ManagedAttribute(description = "age attribute")
    public int getAge() {
        logger.info("getAge");
        return age;
    }

    @ManagedAttribute(description = "name attribute")
    public void setName(String name) {
        logger.info("setNamee");
        this.name = name;
    }

    @ManagedAttribute(description = "name attribute")
    public String getName() {
        logger.info("getName");
        return name;
    }

    public String dontExposeThisMethod() {
        return "dontExposeThisMethod return";
    }

    @ManagedOperation(description = "method exposed")
    public String exposeThisMethod() {
        return "exposeThisMethod return";
    }

}

In the application context you need

    <bean id="jmxAdapter.parent" class="org.springframework.jmx.export.MBeanExporter" abstract="true">
        <property name="autodetect">
            <value>true</value>
        </property>
        <property name="assembler">
            <ref local="metadataMBeanInfoAssembler"/>
        </property>
        <property name="namingStrategy">
            <ref local="namingStrategy"/>
        </property>
    </bean>

    <!-- Use metadata to filter the exposed operations and attributes -->
    <bean id="metadataMBeanInfoAssembler" class="org.springframework.jmx.export.assembler.MetadataMBeanInfoAssembler">
        <property name="attributeSource">
            <ref local="annotationJmxAttributeSource"/>
        </property>
    </bean>
    <bean id="annotationJmxAttributeSource" class="org.springframework.jmx.export.annotation.AnnotationJmxAttributeSource"/>
    <bean id="namingStrategy" class="org.springframework.jmx.export.naming.MetadataNamingStrategy">
        <property name="attributeSource">
            <ref local="annotationJmxAttributeSource"/>
        </property>
    </bean>

    <bean id="testBean" class="com.arcmind.springjmx.JmxTestBean">
        <property name="name">
            <value>TEST</value>
        </property>
        <property name="age">
            <value>100</value>
        </property>
    </bean>

For testing you’d need to explicitly set the mbean server

    <bean id="jmxAdapter" parent="jmxAdapter.parent">
        <property name="server">
            <ref local="mbeanServer"/>
        </property>
    </bean>

    <bean id="mbeanServer" class="org.springframework.jmx.support.MBeanServerFactoryBean"/>

For deploying it gets autodetected

    <bean id="jmxAdapter" parent="jmxAdapter.parent"/>

Other options for the assembler property are

    <!-- Expose everything through reflection -->
    <bean id="simpleReflectiveMBeanInfoAssembler" class="org.springframework.jmx.export.assembler.SimpleReflectiveMBeanInfoAssembler"/>

    <!-- Use method names to filter the exposed operations and attributes -->
    <bean id="methodNameBasedMBeanInfoAssembler" class="org.springframework.jmx.export.assembler.MethodNameBasedMBeanInfoAssembler">
        <property name="managedMethods">
            <list>
                <value>exposeThisMethod</value>
                <value>getAge</value>
                <value>setAge</value>
                <value>getName</value>
                <value>setName</value>
            </list>
        </property>
    </bean>

    <!-- Expose only those methods in the interfaces implemented by the bean -->
    <bean id="interfaceBasedMBeanInfoAssembler" class="org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler"/>

But then you may need to explicitly say what beans you want to
expose instead of autodetecting them in the jmxAdapter.parent bean.

        <property name="beans">
            <map>
                <entry key="bean:name=testBean1">
                    <ref local="testBean"/>
                </entry>
            </map>
        </property>


					

Spring framework 1.2 RC1 released

Some more jars that I’m adding to the 7000 already at iBiblio (see
my previous entry 😉 ) are the ones from Spring framework 1.2 RC1, just
released by Juergen

Dear Spring community,

It's Spring time :-)

I'm pleased to announce that Spring 1.2 RC1 has just been released.
This release introduces a number of major new features:

* finer-grained distribution jar files, alongside the full spring.jar
* AOP Alliance interfaces are now contained in spring-aop.jar and spring.jar
* XML bean definition improvements ("ref" and "value" shortcut attributes etc)
* improved AOP TargetSourceCreator mechanism (supporting LazyInitTargetSource too)
* transaction annotation support for JDK 1.5+ (annotation called "Transactional")
* improved WebLogicJtaTransactionManager (transaction names, isolation levels)
* SqlRowSet support for JDBC (in conjunction with JdbcTemplate's "queryForRowSet")
* Hibernate3 support (in orm.hibernate3; Hibernate 2.1 support is still available)
* JMX support for export of Spring beans as managed resources and for MBean access
* Commons Attributes and JDK 1.5+ annotations for JMX MBean export

This release also contains many minor enhancements, for example:

* factored out BindingErrorProcessor strategy for ServletRequestDataBinder
* improved ParameterMethodNameResolver for Web MVC MultiActionController

For a detailed list of enhancements and bug fixes, see the changelog.

This release candidate is already considered stable and recommended for development use.
We expect Spring 1.2 final to be released in late April.

Watch out for the Spring Web Flow preview release to follow later this week
(for use with Spring 1.2)!
Web Flow will also become part of the nightly build at that time.

Cheers,

Juergen

Just let me know if any spring dependency is missing and I’ll add it.