use of org.springsource.loaded.test.infra.Result in project spring-loaded by spring-projects.
the class MethodInvokerRewriterTests method callingMethodIntroducedLaterReturningPrimitiveShort.
@Test
public void callingMethodIntroducedLaterReturningPrimitiveShort() throws Exception {
TypeRegistry typeRegistry = TypeRegistry.getTypeRegistryFor(binLoader);
// Configure it directly such that data.Apple is considered reloadable
configureForTesting(typeRegistry, "data.Apple");
ReloadableType apple = typeRegistry.addType("data.Apple", loadBytesForClass("data.Apple"));
byte[] callerbytes = loadBytesForClass("data.Orange002");
callerbytes = ClassRenamer.rename("data.Orange", callerbytes, "data.Apple002:data.Apple");
byte[] rewrittenBytes = MethodInvokerRewriter.rewrite(typeRegistry, callerbytes);
Class<?> callerClazz = loadit("data.Orange", rewrittenBytes);
runExpectNoSuchMethodException(callerClazz, "callAppleRetShort", new Object[] { (short) 3 });
// Load a version of Apple that does define that method
apple.loadNewVersion("002", retrieveRename("data.Apple", "data.Apple002"));
Result result = runUnguarded(callerClazz, "callAppleRetShort", new Object[] { (short) 5 });
assertEquals((short) 10, result.returnValue);
}
use of org.springsource.loaded.test.infra.Result in project spring-loaded by spring-projects.
the class MethodInvokerRewriterTests method invokevirtual3.
/**
* Variant of the above test that this time uses a 3 class hierarchy, checks we can get to the top.toString() that
* is added when toString() is invoked on bottom.
*/
@Test
public void invokevirtual3() throws Exception {
String caller = "virtual.CallerThree";
String top = "virtual.CalleeThreeTop";
String middle = "virtual.CalleeThreeMiddle";
String bottom = "virtual.CalleeThreeBottom";
TypeRegistry typeRegistry = getTypeRegistry(top + "," + bottom + "," + middle);
// The first target does not define toString()
ReloadableType reloadableTop = typeRegistry.addType(top, loadBytesForClass(top));
typeRegistry.addType(middle, loadBytesForClass(middle));
typeRegistry.addType(bottom, loadBytesForClass(bottom));
Class<?> callerClazz = loadit(caller, loadBytesForClass(caller));
Result result = null;
result = runUnguarded(callerClazz, "runTopToString");
assertTrue(((String) result.returnValue).startsWith("virtual.CalleeThreeTop@"));
result = runUnguarded(callerClazz, "runBottomToString");
assertTrue(((String) result.returnValue).startsWith("virtual.CalleeThreeBottom@"));
// adds toString() to top class
reloadableTop.loadNewVersion("002", retrieveRename(top, top + "002"));
result = runUnguarded(callerClazz, "runTopToString");
assertTrue(((String) result.returnValue).startsWith("topToString"));
result = runUnguarded(callerClazz, "runBottomToString");
assertTrue(((String) result.returnValue).startsWith("topToString"));
// remove it again
reloadableTop.loadNewVersion("003", retrieveRename(top, top + "003"));
result = runUnguarded(callerClazz, "runBottomToString");
assertTrue(((String) result.returnValue).startsWith("virtual.CalleeThreeBottom@"));
}
use of org.springsource.loaded.test.infra.Result in project spring-loaded by spring-projects.
the class ProxyTests method basicCaseSimpleInterface.
/*
* Some notes on proxies and reloading. A proxy is created that implements some interface - the proxy
* generator will ask those interfaces what methods they have and for each one: create a field to
* hold the method object in the proxy, create an entry in the static initializer to initialize
* the method object, create a method in the proxy that will call the invocation handler to run it.
*
* If the interfaces are modified to add new methods or delete existing ones, the proxy will
* be out of date (it will be missing the method field, the method itself that forwards to the
* invocation handler and the initialization logic). If we attempt to regenerate the proxy, the proxy creation
* code will give us back the old one because it cached the one it had created!
*/
/*
* Some snippets from a proxy:
* CLASS: $Proxy61 v49 0x0031(public final synchronized) super java/lang/reflect/Proxy interfacescom/test/jaxb/HomeController org/springframework/aop/SpringProxy org/springframework/aop/framework/Advised
FIELD 0x000a(private static) m17 Ljava/lang/reflect/Method;
FIELD 0x000a(private static) m12 Ljava/lang/reflect/Method;
FIELD 0x000a(private static) m6 Ljava/lang/reflect/Method;
METHOD: 0x0008(static) <clinit>()V
CODE
L0
LDC org.springframework.aop.framework.Advised
INVOKESTATIC java/lang/Class.forName(Ljava/lang/String;)Ljava/lang/Class;
LDC isPreFiltered
ICONST_0
ANEWARRAY java/lang/Class
INVOKEVIRTUAL java/lang/Class.getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
PUTSTATIC $Proxy61.m17 Ljava/lang/reflect/Method;
LDC org.springframework.aop.framework.Advised
INVOKESTATIC java/lang/Class.forName(Ljava/lang/String;)Ljava/lang/Class;
LDC isProxyTargetClass
ICONST_0
ANEWARRAY java/lang/Class
INVOKEVIRTUAL java/lang/Class.getMethod(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;
PUTSTATIC $Proxy61.m12 Ljava/lang/reflect/Method;
METHOD: 0x0011(public final) hashCode()I
CODE
L0
ALOAD 0
GETFIELD java/lang/reflect/Proxy.h Ljava/lang/reflect/InvocationHandler;
ALOAD 0
GETSTATIC $Proxy61.m0 Ljava/lang/reflect/Method;
ACONST_NULL
INVOKEINTERFACE java/lang/reflect/InvocationHandler.invoke(Ljava/lang/Object;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;
CHECKCAST java/lang/Integer
INVOKEVIRTUAL java/lang/Integer.intValue()I
IRETURN
L1
ATHROW
L2
ASTORE 1
NEW java/lang/reflect/UndeclaredThrowableException
DUP
ALOAD 1
INVOKESPECIAL java/lang/reflect/UndeclaredThrowableException.<init>(Ljava/lang/Throwable;)V
ATHROW
*/
// To run these tests you need to have -javaagent specified
@Ignore
@Test
public void basicCaseSimpleInterface() throws Exception {
// Set so that the Proxy generator can see the interface class
Thread.currentThread().setContextClassLoader(binLoader);
Class<?> clazz = Class.forName("proxy.TestA1", false, binLoader);
Result r = runUnguarded(clazz, "createProxy");
Class<?> clazzForInterface = Class.forName("proxy.TestIntfaceA1", false, binLoader);
// Call a method through the proxy
r = runUnguarded(clazz, "runM");
assertContains("TestInvocationHandler1.invoke() for m", r.stdout);
TypeRegistry tr = TypeRegistry.getTypeRegistryFor(binLoader);
assertNotNull(tr);
ReloadableType rt = tr.getReloadableType(clazzForInterface);
assertNotNull(rt);
// new version adds a method called n
byte[] newVersionOfTestInterfaceA1 = retrieveRename("proxy.TestIntfaceA1", "proxy.TestIntfaceA2");
rt.loadNewVersion(newVersionOfTestInterfaceA1);
// running m() should still work
r = runUnguarded(clazz, "runM");
assertContains("TestInvocationHandler1.invoke() for m", r.stdout);
// Now load new version of proxy.TestA1 that will enable us to call n on the new interface
byte[] newVersionOfTestA2 = retrieveRename("proxy.TestA1", "proxy.TestA2", "proxy.TestIntfaceA2:proxy.TestIntfaceA1");
tr.getReloadableType(clazz).loadNewVersion(newVersionOfTestA2);
// running m() should still work
r = runUnguarded(clazz, "runM");
assertContains("TestInvocationHandler1.invoke() for m", r.stdout);
// running n() should now work! (if the proxy was auto regen/reloaded)
r = runUnguarded(clazz, "runN");
assertContains("TestInvocationHandler1.invoke() for n", r.stdout);
}
use of org.springsource.loaded.test.infra.Result in project spring-loaded by spring-projects.
the class MethodInvokerRewriterTests method rewriteInvokeVirtual2.
/**
* The simplest thing - method now returns a string
*/
@Test
public void rewriteInvokeVirtual2() throws Exception {
TypeRegistry typeRegistry = getTypeRegistry("invokevirtual.BB");
ReloadableType b = typeRegistry.addType("invokevirtual.BB", loadBytesForClass("invokevirtual.BB"));
byte[] callerbytes = loadBytesForClass("invokevirtual.AA");
byte[] rewrittenBytes = MethodInvokerRewriter.rewrite(typeRegistry, callerbytes);
Class<?> callerClazz = loadit("invokevirtual.AA", rewrittenBytes);
Result result = runUnguarded(callerClazz, "callfoo");
assertEquals("hi from BB.foo", result.returnValue);
callerbytes = loadBytesForClass("invokevirtual.AA2");
callerbytes = ClassRenamer.rename("invokevirtual.AA2", callerbytes, "invokevirtual.BB2:invokevirtual.BB");
rewrittenBytes = MethodInvokerRewriter.rewrite(typeRegistry, callerbytes);
Class<?> callerClazz002 = loadit("invokevirtual.AA2", rewrittenBytes);
// ClassPrinter.print(rewrittenBytes);
b.loadNewVersion("2", retrieveRename("invokevirtual.BB", "invokevirtual.BB2"));
// result = runUnguarded(callerClazz002, "callfoo");
// assertEquals("hi from BB2.foo", result.returnValue);
//
// result = runUnguarded(callerClazz002, "callbar");
// assertEquals("hi from BB2.bar", result.returnValue);
// Now BB3 is loaded, it doesn't implement foo(), instead foo() from the supertype CC should run
b.loadNewVersion("3", retrieveRename("invokevirtual.BB", "invokevirtual.BB3"));
result = runUnguarded(callerClazz002, "callfoo");
assertEquals("hi from CC.foo", result.returnValue);
}
use of org.springsource.loaded.test.infra.Result in project spring-loaded by spring-projects.
the class MethodInvokerRewriterTests method callingMethodIntroducedLaterReturningPrimitiveArray.
@Test
public void callingMethodIntroducedLaterReturningPrimitiveArray() throws Exception {
TypeRegistry typeRegistry = TypeRegistry.getTypeRegistryFor(binLoader);
// Configure it directly such that data.Apple is considered reloadable
configureForTesting(typeRegistry, "data.Apple");
ReloadableType apple = typeRegistry.addType("data.Apple", loadBytesForClass("data.Apple"));
byte[] callerbytes = loadBytesForClass("data.Orange002");
callerbytes = ClassRenamer.rename("data.Orange", callerbytes, "data.Apple002:data.Apple");
byte[] rewrittenBytes = MethodInvokerRewriter.rewrite(typeRegistry, callerbytes);
Class<?> callerClazz = loadit("data.Orange", rewrittenBytes);
runExpectNoSuchMethodException(callerClazz, "callAppleRetArrayInt", new Object[] { new int[] { 3 } });
// Load a version of Apple that does define that method
apple.loadNewVersion("002", retrieveRename("data.Apple", "data.Apple002"));
Result result = runUnguarded(callerClazz, "callAppleRetArrayInt", new Object[] { new int[] { 3 } });
assertEquals(3, ((int[]) result.returnValue)[0]);
}
Aggregations