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:
Comments (Atom)