Friday, December 16, 2011

Initialization block as a constructor for anonymous class

Although not broadly used, [static] initialization blocks are quite interesting features in Java. They may be used to initialize static and instance fields with own default values, before a constructor kicks in. In byte-code, such blocks are represented by two special methods: void <clinit>() for static initialization block and void <init>() for instance initialization block. There may be multiple declarations of initialization blocks in one class. In such case the code from each block is combined into one of the above methods. All instructions are invoked in the same order as they were declared in source code. Example:

package net.progsign.java6;

public class InitializationBlockTest {
 
 private static char charValue;
 private boolean boolValue;
 private int intValue;
 private String stringValue;
 
 static {
  charValue = '$';
  System.out.println("[clinit] " + charValue);
 }
 
 {
  System.out.println("[init-0] " + boolValue);
  System.out.println("[init-0] " + intValue);
  System.out.println("[init-0] " + stringValue);
  System.out.println();
 }
 
 {
  boolValue = true;
  intValue = 1024;
  stringValue = "default";
 }

 public InitializationBlockTest() {
  System.out.println("[constr] " + boolValue);
  System.out.println("[constr] " + intValue);
  System.out.println("[constr] " + stringValue);
 }
 
 public static final void main(String[] args) {
  new InitializationBlockTest();
 }
}

The output of the above code will be:
[clinit] $
[init-0] false
[init-0] 0
[init-0] null

[constr] true
[constr] 1024
[constr] default

Good code design expects from us to initialize class fields in a constructor. Also, because of the characteristics of initialization blocks, it may cause some confusion when trying to understand the order in which the object is created.
However, there is a case where initialization block may be successfuly used. Examine the following code:

package net.progsign.java6;

interface IFace {
 int method();
}

public class AnonymousConstructor {
 public static void main(String[] args) {
  // anonymous class implementing IFace interface
  IFace foo = new IFace() {
   private int value;
   
   {
    value = 1024;
    init();
   }
   
   public int method() {
    return value;
   }
   
   private void init() {
    System.out.println("<init> called init()");
   }
  };
  System.out.println("[main] foo.method() = " + foo.method());
 }
}

In the above code, I declared an interface IFace and, in the main() method, I created anonymous class that implements this interface. My anonymous class has one private attribute value of type int. Because anonymous classes have no name, thus it's not possible to define own constructor (default non-argument constructor will still be created for the class by the compiler). Without initialization blocks, we would be unable to init the class field with our own values.

When compiled and run, the code will produce the following output:

<init> called init()
[main] foo.method() = 1024

Things to know about [static] initialization blocks:
  • there may be multiple initialization blocks in one class (they run in the order they occur in code)
  • they are invoked before any constructor
  • you can't call constructors (neither super() nor this()) from inside initialization block
  • same as constructors, initialization blocks may throw runtime exceptions (in such case the object will not be created)
  • you can assign default value to fields declared as final, but only if they haven't been initialized at declaration time



PS: noticed quite an interesting behaviour of initialization blocks. See the following code:

package net.progsign.java6;

public class InitializationTest {

 static {
  sfield = 1;
  //System.out.println("<clinit> " + sfield);
  //System.out.println("<clinit> sfield=" + InitializationTest.sfield);
 }
 
 {
  ifield = 2;
  //System.out.println("<init> " + ifield);
  //System.out.println("<init>   ifield=" + this.ifield);
 }
 
 static int sfield = 10;
 int ifield = 20;
 
 public static void main(String[] args) {
  InitializationTest it = new InitializationTest();
  System.out.println("[main]   sfield=" + it.sfield);
  System.out.println("[main]   ifield=" + it.ifield);
 }
}

Will the code compile? What will be the output? What will happen if you uncomment the "System.out.println(...)" lines?

Tuesday, October 11, 2011

OT: Chatting with Windows shell (VBScript)

Just a short memo on how to use WMI (Windows Management Instrumentation) and VBScript to simplify some administration tasks.

Rebooting remote machine (have to have privileges to WMI on the remote host):
Sub Reboot(host)
On Error Resume Next
    Set wmi = GetObject("winmgmts:{(Shutdown)}\\" & host & "\root\cimv2")
    If Err.Number <> 0 Then
        Exit Sub
    End If
    Set osList = wmi.ExecQuery("SELECT * FROM Win32_OperatingSystem")
 
    For Each os In osList
        os.Reboot()
    Next
End Sub

Checking host availability:
Sub Ping(host)
    Set pingStatus = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery("SELECT * FROM Win32_PingStatus WHERE address = '" & host & "'")
    For Each pingReplay In pingStatus
       If pingReplay.StatusCode = 0 Then
            WScript.Echo "Response: OK [Time (ms)=" & pingReplay.ResponseTime & "/TTL (ms)=" & pingReplay.ResponseTimeToLive & "]"
       Else
            WScript.Echo "No response from host '" & host & "'"
       End If
    Next
End Sub

Mounting network resources:
Sub Mount(folder)
On Error Resume Next
    Set NetworkObj = CreateObject("WScript.Network")
    Set ShellObj   = CreateObject("WScript.Shell")
    NetworkObj.MapNetworkDrive "X:", folder, true', "user", "pass"
    If Err.Number = 0 Then
        ShellObj.LogEvent 0, "Network resource '" & folder & "' mounted"
    Else
        WScript.Echo "Failed (Status code: " & Err.Number & ")"
    End If
End Sub

Thursday, September 29, 2011

Getting power source info from OS X (Objective-C)

I trust any introduction is unnecessary here, so will go straight to the code.
First approach is to use power source support methods from the IOKit/ps package. Here's how to do it:
#import <Cocoa/Cocoa.h>
#import <IOKit/ps/IOPowerSources.h>
#import <IOKit/ps/IOPSKeys.h>
#import "PowerSourceInfo.h"

@interface IOKitPowerSourceInfo : NSObject {

}

- (PowerSourceInfo*) getPowerSourceInfoFor: (int) index;

@end
... and the implementation:
#import "IOKitPowerSourceInfo.h"


@implementation IOKitPowerSourceInfo

- (PowerSourceInfo*) getPowerSourceInfoFor: (int) index {
 CFTypeRef info = IOPSCopyPowerSourcesInfo();
 CFArrayRef sources = IOPSCopyPowerSourcesList(info);
 PowerSourceInfo* psi = nil;

 int numOfSources = CFArrayGetCount(sources);
 if(numOfSources == 0) {
  return nil;
 }
 CFDictionaryRef source = IOPSGetPowerSourceDescription(info, CFArrayGetValueAtIndex(sources, index));
 psi = [[PowerSourceInfo alloc] initWithDictionary:(NSDictionary*)source];

 CFRelease(sources);
 CFRelease(info);

 return psi;
}

@end

Two functions, IOPSCopyPowerSourcesInfo() and IOPSCopyPowerSourcesList() are used to get information from the system and create list of available power sources. Then, by invoking IOPSGetPowerSourceDescription() function with references to our info object and particular source passed as arguments, we get a reference to a dictionary with all information about selected power source provided by vendor.
The key values for the dictionary are stored in IOKit/ps/IOPSKeys.h file. Unfortunately the dictionary does not have to contain values for all the keys as some of them, according to documentation, are optional.

Another apprach is to read system IO registry related to particular power source. The code is as follows:

#import <Cocoa/Cocoa.h>
#import <IOKit/IOKitLib.h>
#import "PowerSourceInfo.h"

@interface IORegPowerSourceInfo : NSObject {

}

- (PowerSourceInfo*) getPowerSourceInfo;

@end
and...
#import "IORegPowerSourceInfo.h"


@implementation IORegPowerSourceInfo

- (PowerSourceInfo*) getPowerSourceInfo {
 io_object_t deviceHandle;
 kern_return_t kernReturn;
 CFMutableDictionaryRef serviceMatch, properties;
 PowerSourceInfo* psi = nil;

 serviceMatch = IOServiceMatching("IOPMPowerSource");
 deviceHandle = IOServiceGetMatchingService(kIOMasterPortDefault, serviceMatch);
 kernReturn = IORegistryEntryCreateCFProperties(deviceHandle, &properties, NULL, 0);
 if(kernReturn == kIOReturnSuccess) {
  psi = [[PowerSourceInfo alloc] initWithDictionary:(NSDictionary*)properties];
 }
 CFRelease(properties);
 IOObjectRelease(deviceHandle);
 return psi;
}

@end

First, we get a dictionary matching IOService class called "IOPMPowerSource". Then we ask the system to return first IOService related to this class. Next step is to invoke IORegistryEntryCreateCFProperties, passing the device handle we just got, address of a pointer which will refer to a dictionary with all registry values of a particular power source. The function returns status code of type kern_return_t to inform whether it succeeded or failed. Finally, we have to release the memory.

In both examples, the PowerSourceInfo class is just a custom wrapper for the returned dictionary that exposes all keys as class methods.

OS X allows us to be notified about any changes that occur in different parts of the system (including power source chanage). To listen for those changes we have to create a RunLoopSource and attach it to current RunLoop. See the code below:

#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>
#import <IOKit/ps/IOPowerSources.h>

@interface PowerSourceInfoWorker : NSObject {
 WebView* webView;
 CFRunLoopSourceRef runLoopSource;
}

@property (readonly, nonatomic) WebView* webView;

-(void) startThread;
-(void) stopThread;

void powerSourceChange(void* context);

@end

PowerSourceInfoWorker is just a simple Cocoa class that exposes two messages: "startThread" and "stopThread" which will be used to add and remove our "listener" from system loop. The most important is the void powerSourceChange(void* context). It's a regular C function, which will be the callback from the loop.

NOTE: The WebView* webView attribute in the above code will be used later on to call JavaScript functions from the callback function.

Implementation of the PowerSourceInfoWorker:

#import "PowerSourceInfoWorker.h"


@implementation PowerSourceInfoWorker
@synthesize webView;

-(id) initWithWebView:(WebView*) aWebView {
 self = [super init];
 
 if(self) {
  webView = [aWebView retain];
 }
 return self;
}

-(void) dealloc {
 [self stopThread];
 [webView release];
 [super dealloc];
}

-(void) startThread {
 runLoopSource = (CFRunLoopSourceRef)IOPSNotificationCreateRunLoopSource(powerSourceChange, self);
 if(runLoopSource) {
  CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode);
 }
}

-(void) stopThread {
 if(runLoopSource) {
  CFRunLoopSourceInvalidate(runLoopSource);
  CFRelease(runLoopSource);
 } 
}

void powerSourceChange(void* context) {
 NSArray* args = [NSArray arrayWithObjects: @"Power Source has changed!", nil];
 id win = [[(PowerSourceInfoWorker*)context webView] windowScriptObject];
 [win callWebScriptMethod:@"jsCallback" withArguments:args];
}

@end

In startThread new IOPS RunLoopSource is being created. The two params are our callback function and context (which in this case is "self"). Then, this newly created source is attached to currenct RunLoop in default mode (see documentation for details about available RunLoop modes).
stopThread is responsible for removing our RunLoopSource from the system loop, by invoking CFRunLoopSourceInvalidate function, and releasing resources.
The callback function simply gets WebView* from the context, which in my case is the PowerSourceInfoWorker class itself (see: startThread), and calls some WebScript method with arguments passed as an array.

And here comes the JavaScript callback function (with one argument):

function jsCallback(msg) {
    document.getElementById('status').innerHTML = msg + ' (' + new Date().toUTCString() + ')';
    //refresh view
}

The code is quite obvious, and I believe does not need any explanation.

There's one big advantage of the latter method. It returns much more information about power sources available in system than the IOPSCopyPowerSourcesInfo. I wrote a simple Cocoa application to present the differences between those two methods. For source code see the following Mercurial repository:
hg clone https://code.google.com/p/osx-battery-info-app/

Saturday, July 9, 2011

The longest class name in Java

The first thing, that I noticed while working with Spring framework (right after its simplicity, purity, good performance, etc.) is that the designers of the framework didn't bother of creating short and simple names which resulted in a set of VeryLongSelfDescriptiveClassNames.

Curious enough, went throught the core Spring API and found two candidates for the title of "the longest class name in Java", and by the longes class name I mean a class name with no package prefix.

Those two candidates are:

AbstractInterruptibleBatchPreparedStatementSetter
AbstractTransactionalDataSourceSpringContextTests
both containing impressing 50 characters.

However, with Google's help found they're not the winners. The longes class name tends to be:
PreAuthenticatedGrantedAuthoritiesWebAuthenticationDetails
from Spring Security package, which is amazing 59 characters long.

Well self-described code or just a good sense of humor? Both, I guess.

Uninstalling devices and hardware reenumeration in Windows - C# in action

Recently I came across the following problem: how to re-install some device in MS Windows in the easiest possible way (assuming a target user has no knowledge of the system, whatsoever, maybe with exception of an Internet browser). The solution is to write a simple app, which does everything automatically. The idea was quite simple: uninstall the device and then rescan all hardware for changes, letting the PnP mechanism do the rest. Language: C# and SetupAPI (Windows Driver Kit) hidden behind fancy Windows Forms GUI. Here's the code.

Declarations:
using System.Runtime.InteropServices;
// ...
public const int CR_SUCCESS = 0x00000000;
public const int CM_LOCATE_DEVNODE_NORMAL = 0x00000000;
public const int DIGCF_PRESENT = 0x00000002;
public const int DIF_REMOVE = 0x00000005;

// devnode info struct
[StructLayout(LayoutKind.Sequential)]
public class SP_DEVINFO_DATA
{
    public int cbSize;
    public Guid ClassGuid;
    public int DevInst;

    public ulong Reserved;
}

// importing external SetupAPI methods
[DllImport("cfgmgr32.dll")]
public static extern UInt32 CM_Locate_DevNode(ref UInt32 DevInst, string pDeviceID, UInt32 Flags);

[DllImport("cfgmgr32.dll", SetLastError = true)]
public static extern UInt32 CM_Reenumerate_DevNode(UInt32 DevInst, UInt32 Flags);

[DllImport("setupapi.dll")]
public static extern Boolean SetupDiClassGuidsFromNameA(string ClassName, ref Guid Guids, UInt32 ClassNameSize, ref UInt32 RequiredSize);

[DllImport("setupapi.dll")]
public static extern IntPtr SetupDiGetClassDevsA(ref Guid ClassGuid, UInt32 Enumerator, IntPtr hwndPtr, UInt32 Flags);

[DllImport("setupapi.dll")]
public static extern Boolean SetupDiEnumDeviceInfo(IntPtr DeviceInfoSet, UInt32 DeviceIndex, SP_DEVINFO_DATA DeviceInfoData);

[DllImport("setupapi.dll", SetLastError = true)]
public static extern Boolean SetupDiCallClassInstaller(UInt32 InstallFunction, IntPtr DeviceInfoSet, SP_DEVINFO_DATA DeviceInfoData);

[DllImport("setupapi.dll")]
public static extern Boolean SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
Uninstalling all devices in class:
private Int32 RemoveAllDevicesInClassName(string ClassName)
    {
        IntPtr NewDeviceInfoSet;
        UInt32 RequiredSize = 0;
        SP_DEVINFO_DATA DeviceInfoData = new SP_DEVINFO_DATA();
        Guid[] Guids = new Guid[1];

  // getting required size to store Guids for given class name
        Boolean result = SetupDiClassGuidsFromNameA(
                                ClassName, ref Guids[0], RequiredSize, ref RequiredSize);
        if (RequiredSize == 0)
        {
            // incorrect class name
            return -4;
        }
        if (!result)
        {
            Guids = new Guid[RequiredSize];
   // getting the actual Guids
            result = SetupDiClassGuidsFromNameA(
                                ClassName, ref Guids[0], RequiredSize, ref RequiredSize);
        }
        if (!result)
        {
            // incorrect class name
            return -4;
        }
  // getting all present devnodes for given Guid
        NewDeviceInfoSet = SetupDiGetClassDevsA(ref Guids[0], 0, IntPtr.Zero, DIGCF_PRESENT);

        if (NewDeviceInfoSet.ToInt32() == -1)
        {
            // unavailable
            return -8;
        }

  // preparing device info struct
        DeviceInfoData.cbSize = 28;
        DeviceInfoData.ClassGuid = Guid.Empty;
        DeviceInfoData.DevInst = 0;
        DeviceInfoData.Reserved = 0;

        UInt32 i;
  // for each device in class (set of devnodes pointed by NewDeviceInfoSet)
        for (i = 0; SetupDiEnumDeviceInfo(NewDeviceInfoSet, i, DeviceInfoData); i++)
        {
   // invoke class installer method with DIF_REMOVE flag
            if (!SetupDiCallClassInstaller(DIF_REMOVE, NewDeviceInfoSet, DeviceInfoData))
            {
                // failed to uninstall device
    SetupDiDestroyDeviceInfoList(NewDeviceInfoSet);
                return -16;
            }
        }
  // perform cleanup
        SetupDiDestroyDeviceInfoList(NewDeviceInfoSet);
        return CR_SUCCESS;
    }
Forcing hardware reenumeration:
private Int32 ScanForHardwareChanges()
    {
        UInt32 DevInst = 0;
        UInt32 result = CM_Locate_DevNode(ref DevInst, null, CM_LOCATE_DEVNODE_NORMAL);
        if (result != CR_SUCCESS)
        {
            // failed to get devnode
            return -1;
        }
        result = CM_Reenumerate_DevNode(DevInst, 0);

        if (result != CR_SUCCESS)
        {
            // reenumeration failed
            return -2;
        }
        return CR_SUCCESS;
    }

Method invocation:
private void btnFixme_Click(object sender, EventArgs e)
    {
        // remove all devices of class "Image" (image capturing devices)
        Int32 status = RemoveAllDevicesInClassName("Image");
        if (status == CR_SUCCESS)
        {
            status = ScanForHardwareChanges();
        }
        lblStatus.Text = status==CR_SUCCESS ? "Done!" : "Error: " + status.ToString();
    }
I hope the code is commented well enough, and doesn't require further explanation.

Thursday, February 10, 2011

#{...} is not allowed in template text

Shortly after starting my adventure with JSP 2.0 I came across the following runtime exception:

org.apache.jasper.JasperException: /index.jsp(13,27) #{...} is not allowed in template text
 org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:40)
 org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:407)
 org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:102)
 ...
 javax.faces.webapp.FacesServlet.service(FacesServlet.java:313)

My first question was: WTF? All my libs are where they should be, no compilation time errs/warnings, syntax seems to be OK as well. OK, I don't have the jsf/core & jsf/html taglibs imported, but I'm using JSF 2.0, so I don't need the <@ taglib uri="..." prefix="..."/> any more, right? Not exactly.
Quick introduction: as of JSF 2.0 Oracle introduces new technology called Facelets. It's a page declaration language used to build views & templates for JSF-based web applications. Facelets are usually created with conformance to XHTML Transitional DTD, thus the default file extension is *.xhtml. Now, how does this apply to the aforementioned error? One of the advantages of Facelets is that they use XML namespace declaration to import tag libraries. Similar mechanism is used in JSP pages with XML syntax. Example:

Facelets (XHTML) - index.xhtml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
 xmlns="http://www.w3.org/1999/xhtml"
 xmlns:f="http://java.sun.com/jsf/core"
 xmlns:h="http://java.sun.com/jsf/html">
 <h:head>
  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
  <title>Facelet (JSF 2.0)</title>
 </h:head>
 <h:body>
  Name: <h:outputText value="#{personDetails.name}"/>
 </h:body>
</html>

In the above example, both namespace declarations in <html> tag instruct the container that the page is using standard JSF tag libraries http://java.sun.com/jsf/core & http://java.sun.com/jsf/html, and so they should be automatically imported. Another advantage of the Facelets is that they define their own component tree, so there's no more need to wrap your JSF code into <f:view></f:view> tags, which was mandatory in previous versions of the framework.
So, why did I get the error? Because my file was a *.jsp file (i.e. JSP page) and not an *.xhtml file (default for Facelets), and the container kindly ignored my xmlns declarations.

What about the old JSP pages? We need to import manually all required taglibs. Some examples below (note the *.jsp file extension):

JSP (XHTML, JSP syntax) - index.jsp
<?xml version="1.0" encoding="ISO-8859-1" ?>
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
 xmlns="http://www.w3.org/1999/xhtml"
 xmlns:f="http://java.sun.com/jsf/core"
 xmlns:h="http://java.sun.com/jsf/html">
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
  <title>Insert title here</title>
 </head>
 <body>
  <f:view>
   Name: <h:outputText value="#{personDetails.name}"/>
  </f:view>
 </body>
</html>
JSP (XHTML, XML syntax) - index.jsp
<?xml version="1.0" encoding="ISO-8859-1" ?>
<jsp:root
 xmlns:jsp="http://java.sun.com/JSP/Page"
 xmlns:f="http://java.sun.com/jsf/core"
 xmlns:h="http://java.sun.com/jsf/html" version="2.0">
<html xmlns="http://www.w3.org/1999/xhtml">
 <head>
  <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
  <title>JSP (XHTML, XML syntax)</title>
 </head>
 <body>
  <f:view>
   Name: <h:outputText value="#{personDetails.name}"/>
  </f:view>
 </body>
</html>

A little explanation to the last snippet. As mentioned before, JSP pages with an XML syntax use the xmlns namespace declarations of the <jsp:root> tag while importing required tag libraries. What differs from Facelets, is that we still need to specify scope of our JSF code by declaring <f:view></f:view> tags in our JSP file.

Friday, November 12, 2010

Dynamic proxy vs. AOP - simple cache

I'm not going to explain what dynamic proxy (introduced in Java 1.3) and Aspect Oriented Programming (AspectJ implementation) are, as there's a lot of places on the Internet where you can find information about both. I'll rather focus on how to use these two technologies to apply some basic cache mechanism to our project - which will be a simple calculator. Dynamic Proxy
As Dynamic Proxy requires proxied class to implement at least one interface, we will start from creating one:

package net.progsign.proxy;

public interface Calculator {
 public long factorial(int n);
}
and the implementation:
package net.progsign.proxy;

public class CalculatorImpl implements Calculator {
 
 @Override
 public long factorial(int n) {
  return n==0 ? 1 : n * factorial(n-1);
 }
}

Nothing special in the above code snippets. Next, the main part, our InvocationHandler, which will be passed as a parameter to the Proxy.newProxyInstance(InvocationHandler) method. It may look like this:

package net.progsign.proxy.dynamic;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class CalculatorCacheHandler implements InvocationHandler {
 private static final Log log = LogFactory.getLog(CalculatorCacheHandler.class);
 private Map<Integer, Long> cache;
 private Object target;
 
 public CalculatorCacheHandler(Object target) {
  cache = new HashMap<Integer, Long>();
  this.target = target;
 }
 
 @Override
 public Object invoke(Object proxy, Method method, Object[] args)
   throws Throwable {
  int value = (Integer)args[0];
  long computed = 0;
  if(cache.containsKey(value)) {
   log.debug(String.format("[proxy] - hit against cache (%d)", value));
   computed = cache.get(value);
  } else {
   computed = (Long) method.invoke(target, args);
   cache.put(value, computed);
   log.debug(String.format(
    "[proxy] - cached new result (%d/%d)", value, computed));
  }
  return computed;
 }
}

Code explanation: our cache is implemented as a simple map which matches a value to a computed result. If the cache has already got a result for the value that was passed to our method, we simply return that result. Otherwise, if the result hasn't been computed yet, we do it now by invoking calculator's method, then cache the result and finally return it to user. Test application:

package net.progsign.proxy.sample;

import java.lang.reflect.Proxy;

import net.progsign.proxy.Calculator;
import net.progsign.proxy.dynamic.CalculatorCacheHandler;
import net.progsign.proxy.dynamic.CalculatorProxy;

public class ProxyTest {
 public static final void main(String[] args) {
  CalculatorProxy calculatorProxy = new CalculatorProxy();
  Calculator proxy = (Calculator)Proxy.newProxyInstance(
    calculatorProxy.getClass().getClassLoader(),
    calculatorProxy.getClass().getInterfaces(),
    new CalculatorCacheHandler(calculatorProxy));
  calculatorProxy.setProxy(proxy);
  
  System.out.println(proxy.factorial(4));
  System.out.println(proxy.factorial(7));
 }
}
Aspect Oriented Programming (AspectJ)

If Eclipse is your IDE, there are two methods you can incorporate AOP to your project. You can either install AspectJ plug-in for Eclipse (i.e. "Eclipse AspectJ Development Tools") or you can simply add required libraries to your project, configure AspectJ through XML configuration file and finally instruct JVM to use java agent, provided with AspectJ, to weave in your aspects. I'll use the second approach in this example. We start from the Calculator class (notice it doesn't implement any interface):

package net.progsign.proxy;

public class Calculator {
 
 public long factorial(int n) {
  return n==0 ? 1 : n * factorial(n-1);
 }
}
And here's the AOP part:
package net.progsign.proxy.aop;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

@Aspect
public class CalculatorCacheAspect {
 private static final Log log = LogFactory.getLog(CalculatorCacheAspect.class);
 private Map<Integer, Long> cache;
 
 public CalculatorCacheAspect() {
  cache = new HashMap<Integer, Long>();
 }

 @Pointcut("call(public * net.progsign.proxy.Calculator.factorial(int)) && args(value)")
 public void cacheCheckPointcut(int value) {}
 
 @Around("cacheCheckPointcut(value)")
 public Object wrapCalculation(ProceedingJoinPoint pjp, int value) throws Throwable {
  if(cache.containsKey(value)) {
   log.debug(String.format("[aspect] - hit against cache (%d)", value));
   return cache.get(value);
  }
  return pjp.proceed();
 }
 
 @AfterReturning(value="cacheCheckPointcut(value)", returning="result")
 public void updateCache(int value, long result) {
  cache.put(value, result);
  log.debug(String.format("[aspect] - cached new result (%d/%d)", value, result));
 }
}

In the above code we have one pointcut which translates to every call to public method Calculator.factorial(int) which accepts one parameter of type int. We will use value of this parameter later on in our example. Next, we define two advices:

  • public Object wrapCalculation(ProceedingJoinPoint pjp, int value) - this advice is executed around the method invocation. We first check if value that was passed as an argument to our woven method already exists in the cache. If it does, we simply return pre-calculated result from the cache. Otherwise we let the calculator's method to execute and return whatever that method returns.
    Here, the ProceedingJoinPoint is a reference to our join point. By invoking the proceed() method we say, that the actual method that was advised, which in this case is Calculator.factorial(int value), should be executed. The second parameter is the parameter defined in the pointcut and it refers to the argument of the Calculator.factorial(int value) method.
  • public void updateCache(int value, long result) - this advice method is invoked after successfully returning from our pointcut. We take both, value passed as an argument to the advised method and the result it returns (no matter whether it was computed or taken directly from the cache) and put this pair in to our cache.

The last thing is the configuration XML for the application (META-INF/aop.xml):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE aspectj PUBLIC
"-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
 <aspects>
  <aspect name="net.progsign.proxy.aop.CalculatorCacheAspect"/>
 </aspects>
 <weaver option="-verbose">
  <include within="net.progsign.proxy..*"/>
 </weaver>
</aspectj>

I only defined one aspect, by specifying its fully qualified name, net.progsign.proxy.aop.CalculatorcacheAspect and joint points in the application where the aspect will be woven in, which in this case is all classes within package net.progsign.proxy and all its sub-packages. The test application is as simple as:

package net.progsign.proxy.sample;

import net.progsign.proxy.Calculator;

public class ProxyTest {
 public static final void main(String[] args) {
  Calculator impl = new Calculator();
  System.out.println(impl.factorial(4));
  System.out.println(impl.factorial(7));
 }
}

There's one last thing to do. To weave in the aspect to our project we also have to instruct JVM to use AspectJ agent:

-javaagent:${project_loc}/lib/aspectjweaver.jar
Conclusions

As you probably already know both Dynamic Proxy and AOP are widely used in many frameworks, e.g. IoC in Spring Framework or logging purposes in business applications. Dynamic Proxy is not very hard to implement in simple applications, but may be cumbersome in more complex systems. Sometimes even impossible. For example, there's no simple way to create dynamic proxy for recursive methods. Such method has to call its proxied version, thus be proxy aware and this may lead to design issues.
Another disadvantage is the way we implement it in our project. All methods must be called through proxy instance in order to being intercepted by the InvocationHandler and this means we have to modify our code. This, of course, may be time consuming and error prone. AOP lets us avoid these problems, because it doesn't affect the source code directly. It weaves in the new functionality into byte code and switching it on and off can be as easy as:

<aspectj>
 <weaver option="-verbose">
  <include within="net.progsign.proxy..*"/>
  <exclude within="*" />
 </weaver>
</aspectj>

Another advantage of AOP is that our classes don't have to implement any interfaces. We just choose which joint points we want to advise. It can be method calls, method executions, class attribute access, constructors, etc. Both Dynamic Proxy and AOP may be a good solution in real projects, although the latter one is really worth giving a try.