use of org.springsource.loaded.test.infra.Result in project spring-loaded by spring-projects.
the class MethodInvokerRewriterTests method rewriteInvokeInterface5_paramsChanged.
/**
* A method is changed on an interface - parameter type change.
*/
@Test
public void rewriteInvokeInterface5_paramsChanged() throws Exception {
TypeRegistry typeRegistry = getTypeRegistry("tgt.SimpleIClass,tgt.SimpleI");
ReloadableType intface = typeRegistry.addType("tgt.SimpleI", loadBytesForClass("tgt.SimpleI"));
ReloadableType impl = typeRegistry.addType("tgt.SimpleIClass", loadBytesForClass("tgt.SimpleIClass"));
byte[] callerbytes = loadBytesForClass("tgt.StaticICaller");
byte[] rewrittenBytes = MethodInvokerRewriter.rewrite(typeRegistry, callerbytes);
Class<?> callerClazz = loadit("tgt.StaticICaller", rewrittenBytes);
Result result = runUnguarded(callerClazz, "run");
assertEquals(123, result.returnValue);
// new interface version has method removed
intface.loadNewVersion("2", retrieveRename("tgt.SimpleI", "tgt.SimpleI005"));
impl.loadNewVersion("2", retrieveRename("tgt.SimpleIClass", "tgt.SimpleIClass005", "tgt.SimpleI005:tgt.SimpleI"));
callerbytes = loadBytesForClass("tgt.StaticICaller005");
callerbytes = ClassRenamer.rename("tgt.StaticICaller005", callerbytes, "tgt.SimpleI005:tgt.SimpleI", "tgt.SimpleIClass005:tgt.SimpleIClass", "tgt.SimpleIClass005:tgt.SimpleIClass");
rewrittenBytes = MethodInvokerRewriter.rewrite(typeRegistry, callerbytes);
callerClazz = loadit("tgt.StaticICaller005", rewrittenBytes);
result = runUnguarded(callerClazz, "run");
assertEquals(72, result.returnValue);
}
use of org.springsource.loaded.test.infra.Result in project spring-loaded by spring-projects.
the class MethodInvokerRewriterTests method rewriteInvokeStatic.
/**
* Rewrite of a simple INVOKESTATIC call.
*/
@Test
public void rewriteInvokeStatic() throws Exception {
TypeRegistry typeRegistry = getTypeRegistry("tgt.SimpleClass");
ReloadableType r = typeRegistry.addType("tgt.SimpleClass", loadBytesForClass("tgt.SimpleClass"));
byte[] callerbytes = loadBytesForClass("tgt.StaticCaller");
// @formatter:off
checkMethod(callerbytes, "run", " L0\n" + " LDC 123\n" + " INVOKESTATIC tgt/SimpleClass.toInt(Ljava/lang/String;)I\n" + " IRETURN\n" + " L1\n");
// @formatter:on
byte[] rewrittenBytes = MethodInvokerRewriter.rewrite(typeRegistry, callerbytes);
// @formatter:off
checkMethod(rewrittenBytes, "run", " L0\n" + " LDC 123\n" + " LDC " + r.getId() + "\n" + " LDC toInt(Ljava/lang/String;)I\n" + " INVOKESTATIC org/springsource/loaded/TypeRegistry.istcheck(ILjava/lang/String;)Ljava/lang/Object;\n" + " DUP\n" + " IFNULL L1\n" + " CHECKCAST tgt/SimpleClass__I\n" + " ASTORE 1\n" + // it would remove from here:
" LDC 1\n" + // load 1
" ANEWARRAY java/lang/Object\n" + // new array of size 1
" DUP_X1\n" + // put it under the argument (it'll be under and on top)
" SWAP\n" + // put it under and under, arg on top
" LDC 0\n" + // load 0
" SWAP\n" + // swap
" AASTORE\n" + // to here
" ALOAD 1\n" + // load the target
" SWAP\n" + // put the target at the bottom
" ACONST_NULL\n" + // load the instance (static call so null)
" LDC toInt(Ljava/lang/String;)I\n" + // load the name+descriptor
" INVOKEINTERFACE tgt/SimpleClass__I.__execute([Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;\n" + " CHECKCAST java/lang/Integer\n" + " INVOKEVIRTUAL java/lang/Integer.intValue()I\n" + " GOTO L2\n" + " L1\n" + " POP\n" + " INVOKESTATIC tgt/SimpleClass.toInt(Ljava/lang/String;)I\n" + " L2\n" + " IRETURN\n" + " L3\n");
// @formatter:on
Class<?> callerClazz = loadit("tgt.StaticCaller", rewrittenBytes);
// ClassPrinter.print(r.bytesLoaded);
Result result = runUnguarded(callerClazz, "run");
assertEquals(123, result.returnValue);
}
use of org.springsource.loaded.test.infra.Result in project spring-loaded by spring-projects.
the class MethodInvokerRewriterTests method rewriteInvokeVirtual1.
// TODO review visibility runtime checking. In this next test a static method is changed from public to private. It does
// not currently trigger an error - whether we need to check kind of depends on if we support deployment of broken code. A
// compiler could not create code like this, it can only happen when one end of a call has been deployed but the other end hasnt
// /**
// * If the static method is made non-visible (private), here is what happens in the java case:
// *
// * <pre>
// * Exception in thread "main" java.lang.IllegalAccessError: tried to access method B.foo()V from class A
// * at A.main(A.java:3)
// * </pre>
// */
// @Test
// public void rewriteInvokeStatic7() throws Exception {
// TypeRegistry typeRegistry = getTypeRegistry("tgt.SimpleClass");
// ReloadableType callee = typeRegistry.addType("tgt.SimpleClass", loadBytesForClass("tgt.SimpleClass"));
//
// byte[] callerbytes = loadBytesForClass("tgt.StaticCaller");
// byte[] rewrittenBytes = MethodInvokerRewriter.rewrite(typeRegistry, callerbytes);
// Class<?> callerClazz = loadit("tgt.StaticCaller", rewrittenBytes);
//
// Result result = runUnguarded(callerClazz, "run");
// assertEquals(123, result.returnValue);
//
// // new version of SimpleClass where target static method has been made private
// callee.loadNewVersion("7", retrieveRename("tgt.SimpleClass", "tgt.SimpleClass007"));
//
// try {
// ClassPrinter.print(rewrittenBytes);
// result = runUnguarded(callerClazz, "run");
// System.out.println(result.returnValue);
// fail here because the visibility of the changed static method has not been policed
// Assert.fail();
// } catch (RuntimeException rt) {
// rt.printStackTrace();
// InvocationTargetException ite = (InvocationTargetException) rt.getCause();
// Throwable t = ite.getCause();
// IncompatibleClassChangeError icce = (IncompatibleClassChangeError) t;
// assertEquals("Expected static method SimpleClass.toInt(Ljava/lang/String;)I", icce.getMessage());
// }
// }
/**
* The simplest thing - calling a method with no params and no return (keeps generated code short!)
*/
@Test
public void rewriteInvokeVirtual1() throws Exception {
TypeRegistry typeRegistry = getTypeRegistry("invokevirtual.B");
ReloadableType b = loadType(typeRegistry, "invokevirtual.B");
byte[] callerbytes = loadBytesForClass("invokevirtual.A");
byte[] rewrittenBytes = MethodInvokerRewriter.rewrite(typeRegistry, callerbytes);
Class<?> callerClazz = loadit("invokevirtual.A", rewrittenBytes);
Result result = runUnguarded(callerClazz, "run");
Assert.assertNull(result.returnValue);
callerbytes = loadBytesForClass("invokevirtual.A2");
callerbytes = ClassRenamer.rename("invokevirtual.A2", callerbytes, "invokevirtual.B2:invokevirtual.B");
rewrittenBytes = MethodInvokerRewriter.rewrite(typeRegistry, callerbytes);
Class<?> callerClazz002 = loadit("invokevirtual.A2", rewrittenBytes);
b.loadNewVersion("2", retrieveRename("invokevirtual.B", "invokevirtual.B2"));
result = runUnguarded(callerClazz002, "run");
Assert.assertNull(result.returnValue);
}
use of org.springsource.loaded.test.infra.Result in project spring-loaded by spring-projects.
the class MethodInvokerRewriterTests method rewriteInvokeStatic3.
/**
* Reloading target with a new static method that takes no parameters.
*/
@Test
public void rewriteInvokeStatic3() throws Exception {
TypeRegistry typeRegistry = getTypeRegistry("tgt.SimpleClass");
ReloadableType callee = typeRegistry.addType("tgt.SimpleClass", loadBytesForClass("tgt.SimpleClass"));
byte[] callerbytes = loadBytesForClass("tgt.StaticCaller");
byte[] rewrittenBytes = MethodInvokerRewriter.rewrite(typeRegistry, callerbytes);
Class<?> callerClazz = loadit("tgt.StaticCaller", rewrittenBytes);
// run the original
Result result = runUnguarded(callerClazz, "run");
assertEquals(123, result.returnValue);
callerbytes = loadBytesForClass("tgt.StaticCaller003");
callerbytes = ClassRenamer.rename("tgt.StaticCaller003", callerbytes, "tgt.SimpleClass003:tgt.SimpleClass");
rewrittenBytes = MethodInvokerRewriter.rewrite(typeRegistry, callerbytes);
Class<?> callerClazz002 = loadit("tgt.StaticCaller003", rewrittenBytes);
callee.loadNewVersion("3", retrieveRename("tgt.SimpleClass", "tgt.SimpleClass003"));
result = runUnguarded(callerClazz002, "run3");
assertEquals("42", result.returnValue);
}
use of org.springsource.loaded.test.infra.Result in project spring-loaded by spring-projects.
the class MethodInvokerRewriterTests method callingMethodIntroducedLaterReturningPrimitiveBoolean.
@Test
public void callingMethodIntroducedLaterReturningPrimitiveBoolean() 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, "callAppleRetBoolean", new Object[] { true });
// Load a version of Apple that does define that method
apple.loadNewVersion("002", retrieveRename("data.Apple", "data.Apple002"));
Result result = runUnguarded(callerClazz, "callAppleRetBoolean", new Object[] { true });
assertEquals(false, result.returnValue);
}
Aggregations