use of org.springsource.loaded.ReloadableType in project spring-loaded by spring-projects.
the class MethodInvokerRewriterTests method invokevirtualNonCatchers3.
/**
* Similar to previous test but now new method is in the middle of the hierarchy (and in the top, but the middle one
* should be answering the request)
*/
@Test
public void invokevirtualNonCatchers3() throws Exception {
String top = "virtual.FourTopC";
String mid = "virtual.FourMidC";
String bot = "virtual.FourBotC";
TypeRegistry typeRegistry = getTypeRegistry(top + "," + bot);
ReloadableType topR = typeRegistry.addType(top, loadBytesForClass(top));
ReloadableType midR = typeRegistry.addType(mid, loadBytesForClass(mid));
ReloadableType botR = typeRegistry.addType(bot, loadBytesForClass(bot));
result = runUnguarded(botR.getClazz(), "run");
assertEquals(42, result.returnValue);
topR.loadNewVersion(retrieveRename(top, top + "2"));
midR.loadNewVersion(retrieveRename(mid, mid + "2", top + "2:" + top));
botR.loadNewVersion(retrieveRename(bot, bot + "2", mid + "2:" + mid));
// now 'run()' should be invoking super.bar() where bar() is a new method
// introduced into FourTop
result = runUnguarded(botR.getClazz(), "run");
assertEquals(99, result.returnValue);
}
use of org.springsource.loaded.ReloadableType 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.ReloadableType 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.ReloadableType in project spring-loaded by spring-projects.
the class MethodInvokerRewriterTests method superCallsDynamicDispatcher.
/**
* This is similar to the first case except the hierarchy is split such that a middle type exists which does not
* initially implement the methods, they are added in a reload. This variant of the testcase is checking dispatch
* through the dynamic dispatch __execute method will work.
*/
@Test
public void superCallsDynamicDispatcher() throws Exception {
TypeRegistry tr = getTypeRegistry("invokespecial..*");
loadType(tr, "invokespecial.Top");
ReloadableType rt = loadType(tr, "invokespecial.Able2");
ReloadableType st = loadType(tr, "invokespecial.Simple2");
rt.loadNewVersion("002", this.retrieveRename("invokespecial.Able2", "invokespecial.Able2002"));
Object object = st.getClazz().newInstance();
Method method = null;
String string = null;
// ClassPrinter.print(rt.bytesLoaded);
method = st.getClazz().getMethod("withParamSuperCaller");
string = (String) method.invoke(object);
assertEquals("2323", string);
method = st.getClazz().getMethod("withDoubleSlotParamSuperCaller");
string = (String) method.invoke(object);
assertEquals("3030", string);
// this call is checking the private field access in the reloaded method has been
// changed to use the accessors into the type that can access the field from outside
method = st.getClazz().getMethod("withParamSuperCallerPrivateVariable");
string = (String) method.invoke(object);
assertEquals("44", string);
}
use of org.springsource.loaded.ReloadableType in project spring-loaded by spring-projects.
the class MethodInvokerRewriterTests method superCallsRemovingMethods.
/**
* This is similar to the first case except the hierarchy is split such that a middle type exists where the methods
* initially exist but then they are removed in a reload. We should end up at the top level methods.
*/
@Test
public void superCallsRemovingMethods() throws Exception {
TypeRegistry tr = getTypeRegistry("invokespecial..*");
ReloadableType a = loadType(tr, "invokespecial.A");
ReloadableType b = loadType(tr, "invokespecial.B");
ReloadableType c = loadType(tr, "invokespecial.C");
Object object = c.getClazz().newInstance();
Method method = null;
String string = null;
// class B implements it right now
method = c.getClazz().getMethod("run1");
string = (String) method.invoke(object);
assertEquals("66", string);
method = c.getClazz().getMethod("run2");
string = (String) method.invoke(object);
assertEquals("66falseabc", string);
// Load new version of B where the methods are no longer there...
b.loadNewVersion("002", retrieveRename("invokespecial.B", "invokespecial.B002"));
// these calls should drop through to the super class A
method = c.getClazz().getMethod("run1");
string = (String) method.invoke(object);
assertEquals("65", string);
method = c.getClazz().getMethod("run2");
string = (String) method.invoke(object);
assertEquals("65falseabc", string);
// Load new version of A where they aren't there either - how do we fail?
a.loadNewVersion("002", retrieveRename("invokespecial.A", "invokespecial.A002"));
// these calls should drop through to the super class A
method = c.getClazz().getMethod("run1");
try {
string = (String) method.invoke(object);
fail();
} catch (InvocationTargetException ite) {
assertEquals("java.lang.NoSuchMethodError", ite.getCause().getClass().getName());
assertEquals("invokespecial.A.getInt()I", ite.getCause().getMessage());
}
}
Aggregations