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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user