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.
Thursday, September 29, 2011
Saturday, September 10, 2011
Using SBT 0.10.1, Eclipsify for a new Scala project
Run sbt(0.10.1) in a new folder:
The following folders will show up under the root folder:
Create the default source/test/resource structure:
Create a build configuration file build.sbt, and place it in the root of the project with the following content:
Add, one sample test in the file src\test\scala\gcdtests.scala, just to test out the sbt configuration:
Invoke sbt, and run test, if everything is configured correctly the following output will be displayed:
Now, to import this project into eclipse. Create a build.sbt file with the following contents and place in the project/plugins folder:
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:
Assuming that Scala IDE for Eclipse is installed, import this new project into Eclipse:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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:
1 2 3 4 5 6 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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:
1 2 3 | 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:
1 2 3 4 5 6 | > 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.
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:
Here the pointcut expression -
selects all methods annotated with @PerfLog annotation, and the aspect method logPerformanceStats logs the time taken by the method calls.
To test this:
When this test is invoked the output is the following:
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
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:
1 2 3 4 5 6 7 8 9 10 11 | 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | @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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | 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 -
1 | @Pointcut ( "execution(@org.bk.annotations.PerfLog * *.*(..))" ) |
To test this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 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:
1 2 3 4 5 6 7 | 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.
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:
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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | 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
Subscribe to:
Posts (Atom)