use of org.springsource.loaded.ReloadableType in project spring-loaded by spring-projects.
the class FieldReloadingTests method defaultFields.
// The problem with default visibility fields is that the executors cannot see them. So we create accessors for
// these fields in the target types. If two types in a hierarchy declare the same field, then these accessor methods will be in an
// override relationship. The overriding accessors will be subject to virtual dispatch - but the runtime type should be
// correct so that the right one is called.
@Test
public void defaultFields() throws Exception {
TypeRegistry tr = getTypeRegistry("accessors..*");
ReloadableType top = tr.addType("accessors.DefaultFields", loadBytesForClass("accessors.DefaultFields"));
ReloadableType bottom = tr.addType("accessors.DefaultFieldsSub", loadBytesForClass("accessors.DefaultFieldsSub"));
ClassPrinter.print(top.bytesLoaded);
Object topInstance = top.getClazz().newInstance();
Result result = runOnInstance(top.getClazz(), topInstance, "a");
assertEquals(1, result.returnValue);
Object botInstance = bottom.getClazz().newInstance();
result = runOnInstance(bottom.getClazz(), botInstance, "a");
assertEquals(1, result.returnValue);
result = runOnInstance(bottom.getClazz(), botInstance, "b");
assertEquals(2, result.returnValue);
}
use of org.springsource.loaded.ReloadableType in project spring-loaded by spring-projects.
the class FieldReloadingTests method accessingFieldsThroughReloadableType.
/**
* Both 'normal' reloadable field access and reflective field access will use the same set methods on
* ReloadableType. In the reflection case the right FieldAccessor must be discovered, in the normal case it is
* passed in. This test checks that using either route behaves - exercising the method directly and not through
* reflection.
*/
@Test
public void accessingFieldsThroughReloadableType() throws Exception {
String p = "fields.P";
String q = "fields.Q";
String r = "fields.R";
TypeRegistry tr = getTypeRegistry(p + "," + q + "," + r);
ReloadableType ptype = tr.addType(p, loadBytesForClass(p));
ReloadableType qtype = tr.addType(q, loadBytesForClass(q));
ReloadableType rtype = tr.addType(r, loadBytesForClass(r));
Class<?> rClazz = rtype.getClazz();
Object rInstance = rClazz.newInstance();
// Before reloading, check both routes get to the same field:
assertEquals(2, runOnInstance(rClazz, rInstance, "getI").returnValue);
assertEquals(2, rtype.getField(rInstance, "i", false));
// Now mess with it via one route and check result via the other:
rtype.setField(rInstance, "i", false, 44);
assertEquals(44, runOnInstance(rClazz, rInstance, "getI").returnValue);
qtype.loadNewVersion("2", retrieveRename(q, q + "2"));
// After reloading, check both routes get to the same field:
assertEquals(1, runOnInstance(rClazz, rInstance, "getI").returnValue);
assertEquals(1, ptype.getField(rInstance, "i", false));
// Now mess with it via one route and check result via the other:
rtype.setField(rInstance, "i", false, 357);
assertEquals(357, runOnInstance(rClazz, rInstance, "getI").returnValue);
}
use of org.springsource.loaded.ReloadableType in project spring-loaded by spring-projects.
the class GroovyTests method basic.
// Changing the return value within a method
@Test
public void basic() throws Exception {
binLoader = new TestClassloaderWithRewriting();
String t = "simple.Basic";
TypeRegistry r = getTypeRegistry(t);
ReloadableType rtype = r.addType(t, loadBytesForClass(t));
result = runUnguarded(rtype.getClazz(), "run");
assertEquals("hello", result.returnValue);
rtype.loadNewVersion("2", retrieveRename(t, t + "2"));
result = runUnguarded(rtype.getClazz(), "run");
assertEquals("goodbye", result.returnValue);
}
use of org.springsource.loaded.ReloadableType in project spring-loaded by spring-projects.
the class GroovyTests method basic5.
// Calling from one type to another, now the methods are non-static
@Test
public void basic5() throws Exception {
binLoader = new TestClassloaderWithRewriting();
String t = "simple.BasicE";
String target = "simple.BasicETarget";
TypeRegistry r = getTypeRegistry(t + "," + target);
ReloadableType rtype = r.addType(t, loadBytesForClass(t));
ReloadableType rtypeTarget = r.addType(target, loadBytesForClass(target));
result = runUnguarded(rtype.getClazz(), "run");
assertEquals("hello", result.returnValue);
rtype.loadNewVersion("2", retrieveRename(t, t + "2"));
rtypeTarget.loadNewVersion("2", retrieveRename(target, target + "2"));
result = runUnguarded(rtype.getClazz(), "run");
assertEquals("foobar", result.returnValue);
}
use of org.springsource.loaded.ReloadableType in project spring-loaded by spring-projects.
the class EnumTests method testLargeEnum.
// TODO for this to work properly need support for very large enums (static method splitting)
// currently this will pass because we don't make enum values reloadable (changeable) if there are more than 1000 in an enum type
// it should be possible to reload if the values don't change, but a NSFE will be thrown if the values do change.
@Test
public void testLargeEnum() throws Exception {
String t = "enumtests.ColoursE";
String runner = "enumtests.RunnerE";
binLoader.loadClass(t);
Class<?> runnerClazz = binLoader.loadClass(runner);
assertNotNull(runnerClazz);
String output = runMethodAndCollectOutput(runnerClazz, "run1");
assertContains("[Red 1111 0 Green 2222 1 Blue 3333 2]", output);
// Check we loaded it as reloadable
ReloadableType rtype = TypeRegistry.getTypeRegistryFor(binLoader).getReloadableType(toSlash(t), false);
// Utils.dump(rtype.getSlashedName(), rtype.bytesLoaded);
assertNotNull(rtype);
ReloadableType rtypeRunner = TypeRegistry.getTypeRegistryFor(binLoader).getReloadableType(toSlash(runner), false);
assertNotNull(rtypeRunner);
assertTrue(rtype.loadNewVersion("1", rtype.bytesInitial));
output = runMethodAndCollectOutput(runnerClazz, "run1");
assertContains("[Red 1111 0 Green 2222 1 Blue 3333 2]", output);
// Changes from ints to chars
rtype.loadNewVersion(retrieveRename(t, t + "2"));
// expect this in the console:
// Caused by: java.lang.NoSuchFieldError: JOE1
// at enumtests.ColoursE$$E2. enum constant initialization$2(ColoursE2.java:1)
// at enumtests.ColoursE$$E2.___clinit___(ColoursE2.java:3)
}
Aggregations