Workaround for issue #69

Made rewriting all system classes optional, to enable easy testing
of whether a given problem is simply that some system classes
are currently being ignored.
This commit is contained in:
Andy Clement
2014-06-03 23:43:24 -07:00
parent 9baf7b5514
commit e33dad83c7
3 changed files with 34 additions and 15 deletions

View File

@@ -86,6 +86,9 @@ public class GlobalConfiguration {
* Determine whether on disk caching will be used.
*/
public static boolean isCaching = false;
public static boolean investigateSystemClassReflection = false;
public static boolean rewriteAllSystemClasses = false;
/**
* A well known profile (e.g. grails) can tweak a lot of the default options in a particular way.
@@ -286,6 +289,12 @@ public class GlobalConfiguration {
verboseMode = true;
reloadMessages = true;
}
else if (kv.equals("investigateSystemClassReflection")) {
investigateSystemClassReflection = true;
}
else if (kv.equals("rewriteAllSystemClasses")) {
rewriteAllSystemClasses = true;
}
else if (kv.equals("asserts")) {
Log.log("[asserts mode on] Will verify system coherence");
assertsMode = true;

View File

@@ -31,9 +31,10 @@ import org.objectweb.asm.Opcodes;
*/
public class SystemClassReflectionInvestigator {
public static int investigate(String slashedClassName, byte[] bytes) {
public static int investigate(String slashedClassName, byte[] bytes, boolean print) {
ClassReader fileReader = new ClassReader(bytes);
RewriteClassAdaptor classAdaptor = new RewriteClassAdaptor();
RewriteClassAdaptor classAdaptor = new RewriteClassAdaptor(print);
fileReader.accept(classAdaptor, ClassReader.SKIP_FRAMES);
return classAdaptor.hitCount;
}
@@ -43,15 +44,17 @@ public class SystemClassReflectionInvestigator {
int hitCount = 0;
private ClassWriter cw;
int bits = 0x0000;
private boolean print;
private String classname;
private static boolean isInterceptable(String owner, String methodName) {
return MethodInvokerRewriter.RewriteClassAdaptor.intercepted.contains(owner + "." + methodName);
}
public RewriteClassAdaptor() {
public RewriteClassAdaptor(boolean print) {
// TODO should it also compute frames?
super(ASM5,new ClassWriter(ClassWriter.COMPUTE_MAXS));
this.print = print;
cw = (ClassWriter) cv;
}
@@ -85,7 +88,9 @@ public class SystemClassReflectionInvestigator {
private boolean interceptReflection(String owner, String name, String desc) {
if (isInterceptable(owner, name)) {
hitCount++;
System.out.println("SystemClassReflectionInvestigator: " + classname + " uses " + owner + "." + name + desc);
if (print) {
System.out.println("SystemClassReflectionInvestigator: " + classname + " uses " + owner + "." + name + desc);
}
}
return false;
}

View File

@@ -36,6 +36,7 @@ import org.springsource.loaded.LoadtimeInstrumentationPlugin;
import org.springsource.loaded.Log;
import org.springsource.loaded.Plugin;
import org.springsource.loaded.ReloadableType;
import org.springsource.loaded.SystemClassReflectionInvestigator;
import org.springsource.loaded.SystemClassReflectionRewriter;
import org.springsource.loaded.TypeRegistry;
import org.springsource.loaded.Utils;
@@ -147,21 +148,25 @@ public class SpringLoadedPreProcessor implements Constants {
} catch (Exception re) {
re.printStackTrace();
}
// This block can help when you suspect there is a system class using reflection and that
// class isn't on the 'shortlist' (in systemClassesContainingReflection). Currently we skip
// this for performance, we could make it optional baed on a configuration option
// } else {
// // We should really track whether this type is using reflection...
// if (SystemClassReflectionInvestigator.investigate(slashedClassName, bytes) > 0) {
// RewriteResult rr = SystemClassReflectionRewriter.rewrite(slashedClassName, bytes);
// System.err.println("Type " + slashedClassName + " rewrite summary: " + rr.summarize());
// systemClassesRequiringInitialization.put(slashedClassName, rr.bits);
// return rr.bytes;
// }
}
else if (slashedClassName.equals("java/lang/invoke/InnerClassLambdaMetafactory")) {
bytes = Java8.enhanceInnerClassLambdaMetaFactory(bytes);
return bytes;
} else if ((GlobalConfiguration.investigateSystemClassReflection || GlobalConfiguration.rewriteAllSystemClasses) &&
SystemClassReflectionInvestigator.investigate(slashedClassName, bytes, GlobalConfiguration.investigateSystemClassReflection) > 0) {
// This block can help when you suspect there is a system class using reflection and that
// class isn't on the 'shortlist' (in systemClassesContainingReflection). Basically turn on the
// options to trigger this investigation then add them to the shortlist if it looks like they need rewriting.
RewriteResult rr = SystemClassReflectionRewriter.rewrite(slashedClassName, bytes);
if (GlobalConfiguration.rewriteAllSystemClasses) {
systemClassesRequiringInitialization.put(slashedClassName, rr.bits);
return rr.bytes;
}
else {
System.err.println("Type " + slashedClassName + " rewrite summary: " + rr.summarize());
return bytes;
}
}
}
return bytes;