CglibKitchen
From SPA Wiki
So we all ended up working on the same problem - how to get the following test to pass.
@Test public void blockTest() throws IOException { final String output = "hello people"; openForWrite(new File("del.txt"), new Block<File Output Stream>() Template:Arg(0).write(output.getBytes());); }
Our successful JBoss AOP solution involved intercepting
< aop >
< bind pointcut="execution($instanceof{Block}->new(..))"> <interceptor class="ConstructorInterceptor"/> </bind>
< /aop >
Skipping the constructor by use of Objenisis
public class ConstructorInterceptor implements Interceptor { Objenesis objenesis = new ObjenesisStd(); // or ObjenesisSerializer
public String getName() { return "ConstructorInterceptor"; }
public Object invoke(Invocation invocation) throws Throwable { ConstructorInvocation mi = (ConstructorInvocation)invocation; Object[] args = mi.getArguments(); Object[] args2 = (Object[]) args[ 1];
if (args2.length != 0) return invocation.invokeNext(); else { ObjectInstantiator thingyInstantiator = objenesis.getInstantiatorOf(mi.getConstructor().getDeclaringClass()); Object result = thingyInstantiator.newInstance(); return result; } }
}
and then
public void openForWrite(File f, Block<FileOutputStream> b) throws IOException { FileOutputStream os = new FileOutputStream(f); try { invokeBlock(b.getClass(), os); } catch (IOException x) { throw x; } catch (Throwable e) { throw new RuntimeException(e); } finally { os.close(); } }
@SuppressWarnings("unchecked") private static void invokeBlock(Class c, Object...args) throws Throwable { try { Constructor[] constructors = c.getDeclaredConstructors(); constructors[0].newInstance(null, args); } catch (InvocationTargetException e) { throw e.getTargetException(); } catch (Exception e) { throw new RuntimeException(e); } }