Thursday, September 29, 2011

Indianapolis Java User Group - Presentation on Clojure

I attended a session on Clojure at Indianapolis JUG yesterday. The session was conducted by Carin Meier.

I have wanted to look at Clojure for sometime now, but have been put off by the different looking LISP syntax. Instead I have been learning Scala as the functional JVM based language this year

The session was great, it was about the basics of Clojure but presented in a fun way - it has provided me sufficient amount of motivation to have a second look at Clojure.

The presentation slides are available at Carin Meier's Github account.


Saturday, September 10, 2011

Using SBT 0.10.1, Eclipsify for a new Scala project

Run sbt(0.10.1) in a new folder:

D:\samplescala>sbt

D:\samplescala>set SCRIPT_DIR=C:\util\sbt\

D:\samplescala>java -Dfile.encoding=UTF8 -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256m -jar "C:\util\sbt\sbt
-launch.jar"
Getting net.java.dev.jna jna 3.2.3 ...
:: retrieving :: org.scala-tools.sbt#boot-app
        confs: [default]
        1 artifacts copied, 0 already retrieved (838kB/46ms)
Getting Scala 2.8.1 (for sbt)...
:: retrieving :: org.scala-tools.sbt#boot-scala
        confs: [default]
        3 artifacts copied, 0 already retrieved (15178kB/235ms)
Getting org.scala-tools.sbt sbt_2.8.1 0.10.1 ...
:: retrieving :: org.scala-tools.sbt#boot-app
        confs: [default]
        36 artifacts copied, 0 already retrieved (6414kB/965ms)
[info] Set current project to default-097978 (in build file:/D:/samplescala/)

The following folders will show up under the root folder:

Create the default source/test/resource structure:
mkdir src\main\resources
mkdir src\main\scala
mkdir src\main\java
mkdir src\test\resources
mkdir src\test\scala
mkdir src\test\java

Create a build configuration file build.sbt, and place it in the root of the project with the following content:

name:="samplescala"

version:="1.0"

scalaVersion := "2.9.0-1"

libraryDependencies ++= Seq(
    "junit" % "junit" % "4.8" % "test",
    "org.scalatest" % "scalatest_2.9.0" % "1.6.1"
)

defaultExcludes ~= (filter => filter || "*~")

Add, one sample test in the file src\test\scala\gcdtests.scala, just to test out the sbt configuration:
package com.sample

object Gcd{
    def gcd(a:Int, b:Int):Int = if (b==0) a else gcd(b, a%b)
}


import org.scalatest.FlatSpec
import org.scalatest.matchers.ShouldMatchers


class GcdTests extends FlatSpec with ShouldMatchers{
    "GCD of 1440, 408" should  "be 24" in {
        Gcd.gcd(1440, 408) should equal (24)
    }
}


Invoke sbt, and run test, if everything is configured correctly the following output will be displayed:
D:\samplescala>sbt

D:\samplescala>set SCRIPT_DIR=C:\util\sbt\

D:\samplescala>java -Dfile.encoding=UTF8 -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256m -jar "C:\util\sbt\sbt
-launch.jar"
[info] Set current project to default-097978 (in build file:/D:/samplescala/)
> test
[info] Updating {file:/D:/samplescala/}default-097978...
[info] Done updating.
[info] GcdTests:
[info] GCD of 1440, 408
[info] - should be 24
[info] Passed: : Total 1, Failed 0, Errors 0, Passed 1, Skipped 0
[success] Total time: 1 s, completed Sep 10, 2011 7:00:28 PM

Now, to import this project into eclipse. Create a build.sbt file with the following contents and place in the project/plugins folder:
libraryDependencies <+= (libraryDependencies, sbtVersion) { (deps, version) => 
    "de.element34" %% "sbt-eclipsify" % "0.10.0-SNAPSHOT"
}

Restart sbt, if the plugin is configured correctly, eclipse will be a valid task in sbt, running this will create the .project and .classpath files for Eclipse:
> eclipse
[info] Starting eclipse
[info] written .project for samplescala
[info] written .classpath for samplescala
[info] * Don't forget to install the Scala IDE Plugin from http://www.scalaide.org/
[info] You may now import your projects in Eclipse

Assuming that Scala IDE for Eclipse is installed, import this new project into Eclipse:

Thursday, September 8, 2011

Simple Introduction to AOP - Session 5

This will be a wrap up of the AOP intro, with an example that will comprehensively exercise the concepts introduced in the previous sessions.

The use case is simple, I am going to define a custom annotation, PerfLog, I expect the calls to methods annotated with this annotation to be timed and logged.
Let me start by defining the annotation:

package org.bk.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface PerfLog {
    
}
Now to annotate some service methods with this annotation:

@Service
public class DefaultInventoryService implements InventoryService{
    
    private static Logger logger = LoggerFactory.getLogger(InventoryService.class);

    
    @Override
    public Inventory create(Inventory inventory) {
        logger.info("Create Inventory called");
        inventory.setId(1L);
        return inventory; 
    }

    @Override
    public List<Inventory> list() {
        return new ArrayList<Inventory>();
    }

    @Override
    @PerfLog
    public Inventory update(Inventory inventory) {
        return inventory;
    }

    @Override
    public boolean delete(Long id) {
        logger.info("Delete Inventory called");
        return true;
    }

    @Override
    @PerfLog
    public Inventory findByVin(String vin) {
        logger.info("find by vin called");
        return new Inventory("testmake", "testmodel","testtrim","testvin" );
    }

    @Override
    @PerfLog
    public Inventory compositeUpdateService(String vin, String newMake) {
        logger.info("composite Update Service called");
        Inventory inventory = findByVin(vin);
        inventory.setMake(newMake);
        update(inventory);
        return inventory;
    }
}

Here three methods of DefaultInventoryService have been annotated with @PerfLog annotation - update, findByVin, compositeUpdateService which internally invokes the methods findByVin and update.

Now for the Aspect which will intercept all calls to methods annotated with @PerfLog and log the time taken for the method call:

package org.bk.inventory.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@Aspect
public class AuditAspect {

    private static Logger logger = LoggerFactory.getLogger(AuditAspect.class);

    @Pointcut("execution(@org.bk.annotations.PerfLog * *.*(..))")
    public void performanceTargets(){}
   

    @Around("performanceTargets()")
    public Object logPerformanceStats(ProceedingJoinPoint joinpoint) {
        try {
            long start = System.nanoTime();
            Object result = joinpoint.proceed();
            long end = System.nanoTime();
            logger.info(String.format("%s took %d ns", joinpoint.getSignature(), (end - start)));
            return result;
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }
}

Here the pointcut expression -
@Pointcut("execution(@org.bk.annotations.PerfLog * *.*(..))")
selects all methods annotated with @PerfLog annotation, and the aspect method logPerformanceStats logs the time taken by the method calls.

To test this:
package org.bk.inventory;

import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;

import org.bk.inventory.service.InventoryService;
import org.bk.inventory.types.Inventory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:/testApplicationContextAOP.xml")
public class AuditAspectTest {

    @Autowired 
    InventoryService inventoryService;
        
    @Test
    public void testInventoryService() {
        Inventory inventory = this.inventoryService.create(new Inventory("testmake", "testmodel","testtrim","testvin" ));
        assertThat(inventory.getId(), is(1L));
        
        assertThat(this.inventoryService.delete(1L), is(true));
        assertThat(this.inventoryService.compositeUpdateService("vin","newmake").getMake(),is("newmake"));
    }

}

When this test is invoked the output is the following:
2011-09-08 20:54:03,521 org.bk.inventory.service.InventoryService - Create Inventory called
2011-09-08 20:54:03,536 org.bk.inventory.service.InventoryService - Delete Inventory called
2011-09-08 20:54:03,536 org.bk.inventory.service.InventoryService - composite Update Service called
2011-09-08 20:54:03,536 org.bk.inventory.service.InventoryService - find by vin called
2011-09-08 20:54:03,536 org.bk.inventory.aspect.AuditAspect - Inventory org.bk.inventory.service.DefaultInventoryService.findByVin(String) took 64893 ns
2011-09-08 20:54:03,536 org.bk.inventory.aspect.AuditAspect - Inventory org.bk.inventory.service.DefaultInventoryService.update(Inventory) took 1833 ns
2011-09-08 20:54:03,536 org.bk.inventory.aspect.AuditAspect - Inventory org.bk.inventory.service.DefaultInventoryService.compositeUpdateService(String, String) took 1371171 ns

the advice is correctly invoked for findByVin, update and compositeUpdateService.

This sample is available at : git://github.com/bijukunjummen/AOP-Samples.git


Links to all sessions on AOP:
AOP Session 1 - Decorator Pattern using Java Dynamic Proxies
AOP Session 2 - Using Spring AOP - xml based configuration
AOP Session 3 - Using Spring AOP - @AspectJ based configuration - with/without compile time weaving
AOP Session 4 - Native AspectJ with compile time weaving
AOP Session 5 - Comprehensive Example

Friday, September 2, 2011

Simple Introduction to AOP - Session 4

Yet another way to define an aspect - this time using native aspectj notation.
package org.bk.inventory.aspect;

import org.bk.inventory.types.Inventory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public aspect AuditAspect {
    private static Logger logger = LoggerFactory.getLogger(AuditAspect.class);

    pointcut serviceMethods() : execution(* org.bk.inventory.service.*.*(..));

    pointcut serviceMethodsWithInventoryAsParam(Inventory inventory) : execution(* org.bk.inventory.service.*.*(Inventory)) && args(inventory);

    before() : serviceMethods() {
        logger.info("before method");
    }

    Object around() : serviceMethods() {
        long start = System.nanoTime();
        Object result = proceed();
        long end = System.nanoTime();
        logger.info(String.format("%s took %d ns", thisJoinPointStaticPart.getSignature(),
                (end - start)));
        return result;
    }

    Object around(Inventory inventory) : serviceMethodsWithInventoryAsParam(inventory) {
        Object result = proceed(inventory);
        logger.info(String.format("WITH PARAM: %s", inventory.toString()));
        return result;
    }
    after() : serviceMethods() {
        logger.info("after method");
    }
}


This maps to the previously defined @AspectJ notation

Since this is a DSL specifically for defining Aspects, it is not understood by the java compiler. AspectJ provides a tool(ajc) to compile these native aspectj files and to weave the aspects into the targeted pointcuts. Maven provides a plugin which seamlessly invokes ajc at the point of compilation:

   <plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>aspectj-maven-plugin</artifactId>
    <version>1.0</version>
    <dependencies>
     <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>${aspectj.version}</version>
     </dependency>
     <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjtools</artifactId>
      <version>${aspectj.version}</version>
     </dependency>
    </dependencies>
    <executions>
     <execution>
      <goals>
       <goal>compile</goal>
       <goal>test-compile</goal>
      </goals>
     </execution>
    </executions>
    <configuration>
     <outxml>true</outxml>
     <aspectLibraries>
      <aspectLibrary>
       <groupId>org.springframework</groupId>
       <artifactId>spring-aspects</artifactId>
      </aspectLibrary>
     </aspectLibraries>
     <source>1.6</source>
     <target>1.6</target>
    </configuration>
   </plugin>



Links to all sessions on AOP:
AOP Session 1 - Decorator Pattern using Java Dynamic Proxies
AOP Session 2 - Using Spring AOP - xml based configuration
AOP Session 3 - Using Spring AOP - @AspectJ based configuration - with/without compile time weaving
AOP Session 4 - Native AspectJ with compile time weaving
AOP Session 5 - Comprehensive Example