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:
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.
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 -
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:
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.
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
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)