Search in sources :

Example 96 with ReloadableType

use of org.springsource.loaded.ReloadableType in project spring-loaded by spring-projects.

the class MethodInvokerRewriterTests method callingMethodChangedFromNonStaticToStatic.

@Test
public void callingMethodChangedFromNonStaticToStatic() 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, "callApple4", new Object[] { 3 });
    // Load a version of Apple that does define that method
    apple.loadNewVersion("002", retrieveRename("data.Apple", "data.Apple002"));
    Result result = runUnguarded(callerClazz, "callApple4", new Object[] { 4 });
    assertEquals(8, result.returnValue);
    // Load a version of Apple that doesn't define it
    apple.loadNewVersion("003", loadBytesForClass("data.Apple"));
    runExpectNoSuchMethodException(callerClazz, "callApple4", new Object[] { 5 });
}
Also used : ReloadableType(org.springsource.loaded.ReloadableType) TypeRegistry(org.springsource.loaded.TypeRegistry) Result(org.springsource.loaded.test.infra.Result) Test(org.junit.Test)

Example 97 with ReloadableType

use of org.springsource.loaded.ReloadableType in project spring-loaded by spring-projects.

the class MethodInvokerRewriterTests method rewriteCallArguments.

/**
	 * Target method here takes (string,integer,string,integer) and return a string
	 */
@Test
public void rewriteCallArguments() 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);
    try {
        runUnguarded(callerClazz, "callApple1", new Object[] { "a", 1, "b", 2 });
        Assert.fail("should not work, Apple doesn't have that method in it!");
    } catch (InvocationTargetException ite) {
        String cause = ite.getCause().toString();
        if (!cause.startsWith("java.lang.NoSuchMethodError")) {
            ite.printStackTrace();
            Assert.fail("Should be a NoSuchMethodError, but got " + ite.getCause());
        }
    }
    // Load a version of Apple that does define that method
    apple.loadNewVersion("002", retrieveRename("data.Apple", "data.Apple002"));
    Result result = runUnguarded(callerClazz, "callApple1", new Object[] { "a", 1, "b", 2 });
    assertEquals("a 1 b 2", result.returnValue);
    // Load a version of Apple that doesn't define it
    apple.loadNewVersion("003", loadBytesForClass("data.Apple"));
    try {
        result = runUnguarded(callerClazz, "callApple1", new Object[] { "a", 1, "b", 2 });
        Assert.fail("should not work, Apple doesn't have that method in it!");
    } catch (InvocationTargetException ite) {
        String cause = ite.getCause().toString();
        if (!cause.startsWith("java.lang.NoSuchMethodError")) {
            ite.printStackTrace();
            Assert.fail("Should be a NoSuchMethodError, but got " + ite);
        }
    }
}
Also used : ReloadableType(org.springsource.loaded.ReloadableType) TypeRegistry(org.springsource.loaded.TypeRegistry) InvocationTargetException(java.lang.reflect.InvocationTargetException) Result(org.springsource.loaded.test.infra.Result) Test(org.junit.Test)

Example 98 with ReloadableType

use of org.springsource.loaded.ReloadableType in project spring-loaded by spring-projects.

the class MethodInvokerRewriterTests method fieldOverloading.

//	@Test
//	public void accessingAnnotationTypeReflectively() throws Exception {
//		String t = "annos.Play";
//		TypeRegistry typeRegistry = getTypeRegistry(t);
//		ReloadableType target = typeRegistry.addType(t, loadBytesForClass(t));
//		//		Class<?> callerClazz = loadit(t, loadBytesForClass(t));
//		// Run the initial version which does not define toString()
//		Result result = runUnguarded(target.getClazz(), "run");
//		target.loadNewVersion("2", target.bytesInitial);
//		result = runUnguarded(target.getClazz(), "run");
//		System.out.println(result);
//		//		ClassPrinter.print(target.bytesLoaded);
//	}
@Test
public void fieldOverloading() throws Exception {
    TypeRegistry r = getTypeRegistry("fields..*");
    ReloadableType one = loadType(r, "fields.One");
    ReloadableType two = loadType(r, "fields.Two");
    Class<?> oneClazz = one.getClazz();
    Object oneInstance = oneClazz.newInstance();
    Class<?> twoClazz = two.getClazz();
    Object twoInstance = twoClazz.newInstance();
    // Field 'a' is only defined in One and 'inherited' by Two
    assertEquals("a from One", runOnInstance(oneClazz, oneInstance, "getOneA").returnValue);
    assertEquals("a from One", runOnInstance(twoClazz, twoInstance, "getTwoA").returnValue);
    runOnInstance(oneClazz, oneInstance, "setOneA", "abcde");
    assertEquals("abcde", runOnInstance(oneClazz, oneInstance, "getOneA").returnValue);
    runOnInstance(twoClazz, twoInstance, "setOneA", "abcde");
    assertEquals("abcde", runOnInstance(twoClazz, twoInstance, "getTwoA").returnValue);
    // Field 'b' is defined in One and Two
    assertEquals("b from One", runOnInstance(oneClazz, oneInstance, "getOneB").returnValue);
    assertEquals("b from Two", runOnInstance(twoClazz, twoInstance, "getTwoB").returnValue);
    // Field 'c' is private in One and public in Two
    assertEquals("c from One", runOnInstance(oneClazz, oneInstance, "getOneC").returnValue);
    assertEquals("c from Two", runOnInstance(twoClazz, twoInstance, "getTwoC").returnValue);
    // Now... set the private field 'c' in One then try to access the field c in both One and Two
    // Should be different if the FieldAccessor is preserving things correctly
    runOnInstance(twoClazz, twoInstance, "setOneC", "abcde");
    assertEquals("abcde", runOnInstance(twoClazz, twoInstance, "getOneC").returnValue);
    assertEquals("c from Two", runOnInstance(twoClazz, twoInstance, "getTwoC").returnValue);
}
Also used : ReloadableType(org.springsource.loaded.ReloadableType) TypeRegistry(org.springsource.loaded.TypeRegistry) Test(org.junit.Test)

Example 99 with ReloadableType

use of org.springsource.loaded.ReloadableType in project spring-loaded by spring-projects.

the class MethodInvokerRewriterTests method virtualDispatchCallingSubMethodIntroducedLater2.

/**
	 * Calling a method on a target that is initially satisfied by the subtype but is then added to the subtype with a
	 * different implementation. This is a 3 level hierarchy unlike the previous one, and the new method is added to the
	 * 'middle' type.
	 */
@Test
public void virtualDispatchCallingSubMethodIntroducedLater2() throws Exception {
    TypeRegistry tr = getTypeRegistry("invokevirtual..*");
    ReloadableType x = loadType(tr, "invokevirtual.XX");
    ReloadableType y = loadType(tr, "invokevirtual.YY");
    //		ReloadableType z = 
    loadType(tr, "invokevirtual.ZZ");
    Method method1 = null;
    Method method2 = null;
    Method method3 = null;
    String string = null;
    Object object = x.getClazz().newInstance();
    method1 = x.getClazz().getMethod("run1");
    method2 = x.getClazz().getMethod("run2");
    method3 = x.getClazz().getMethod("run3");
    // First call to run() will dispatch on 'ZZ' but as ZZ doesn't implement foo, and neither does YY, then XX.foo will be used
    string = method1.invoke(object).toString();
    assertEquals("1111", string);
    string = method2.invoke(object).toString();
    assertEquals("1111", string);
    string = method3.invoke(object).toString();
    assertEquals("1111", string);
    // Load a new version of Y that now implements foo
    y.loadNewVersion("002", this.retrieveRename("invokevirtual.YY", "invokevirtual.YY002"));
    string = method1.invoke(object).toString();
    assertEquals("3333", string);
    string = method2.invoke(object).toString();
    assertEquals("3333", string);
    string = method3.invoke(object).toString();
    assertEquals("3333", string);
}
Also used : ReloadableType(org.springsource.loaded.ReloadableType) Method(java.lang.reflect.Method) TypeRegistry(org.springsource.loaded.TypeRegistry) Test(org.junit.Test)

Example 100 with ReloadableType

use of org.springsource.loaded.ReloadableType in project spring-loaded by spring-projects.

the class MethodInvokerRewriterTests method rewriteInvokeStatic6.

/**
	 * If the static method is made non-static, here is what happens in the java case:
	 * 
	 * <pre>
	 * Exception in thread "main" java.lang.IncompatibleClassChangeError: Expected static method B.foo()V
	 *         at A.main(A.java:3)
	 * </pre>
	 */
@Test
public void rewriteInvokeStatic6() 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);
    // new version of SimpleClass where target static method has been made non-static
    callee.loadNewVersion("6", retrieveRename("tgt.SimpleClass", "tgt.SimpleClass006"));
    try {
        result = runUnguarded(callerClazz, "run");
        Assert.fail();
    } catch (InvocationTargetException ite) {
        Throwable t = ite.getCause();
        IncompatibleClassChangeError icce = (IncompatibleClassChangeError) t;
        assertEquals("SpringLoaded: Target of static call is no longer static 'SimpleClass.toInt(Ljava/lang/String;)I'", icce.getMessage());
    }
}
Also used : ReloadableType(org.springsource.loaded.ReloadableType) TypeRegistry(org.springsource.loaded.TypeRegistry) InvocationTargetException(java.lang.reflect.InvocationTargetException) Result(org.springsource.loaded.test.infra.Result) Test(org.junit.Test)

Aggregations

ReloadableType (org.springsource.loaded.ReloadableType)375 Test (org.junit.Test)320 TypeRegistry (org.springsource.loaded.TypeRegistry)287 Result (org.springsource.loaded.test.infra.Result)106 Method (java.lang.reflect.Method)37 InvocationTargetException (java.lang.reflect.InvocationTargetException)26 TestClassloaderWithRewriting (org.springsource.loaded.test.infra.TestClassloaderWithRewriting)22 Ignore (org.junit.Ignore)17 CurrentLiveVersion (org.springsource.loaded.CurrentLiveVersion)10 AccessibleObject (java.lang.reflect.AccessibleObject)9 ResultException (org.springsource.loaded.test.infra.ResultException)9 MethodMember (org.springsource.loaded.MethodMember)8 Field (java.lang.reflect.Field)6 TypeDescriptor (org.springsource.loaded.TypeDescriptor)6 IOException (java.io.IOException)5 Annotation (java.lang.annotation.Annotation)4 ZipEntry (java.util.zip.ZipEntry)4 ZipFile (java.util.zip.ZipFile)4 LoadtimeInstrumentationPlugin (org.springsource.loaded.LoadtimeInstrumentationPlugin)4 File (java.io.File)3