java - Resolving Dependencies in JNI DefineClass -
i writing application using jvmti. trying instrument bytecode: injecting method calls on every method entry.
i know how that, problem in instrument class, it's called proxy
, load using jni function defineclass. proxy
has few dependencies in java class library, java.lang.threadlocal<boolean>
.
now, have this, ininstrumentmethod
plain boolean
:
public static void onentry(int methodid) { if (ininstrumentmethod) { return; } else { ininstrumentmethod = true; } system.out.println("method id: " + methodid); ininstrumentmethod = false; }
the code compiles , works. however, if make ininstrumentmethod
java.lang.threadlocal<boolean>
, noclassdeffounderror. code:
private static threadlocal<boolean> ininstrumentmethod = new threadlocal<boolean>() { @override protected boolean initialvalue() { return boolean.false; } }; public static void onentry(int methodid) { if (ininstrumentmethod.get()) { return; } else { ininstrumentmethod.set(true); } system.out.println("method id: " + methodid); ininstrumentmethod.set(false); }
my guess dependencies have not been resolved correctly, , java.lang.threadlocal
not loaded (and not found). question is, then, how force java load java.lang.threadlocal
? don't think use defineclass
in case; there alternative?
i don’t think there problem resolving standard class java.lang.threadlocal
, rather inner class extending it, generated by
new threadlocal<boolean>() { @override protected boolean initialvalue() { return boolean.false; } };
solving via defineclass
might indeed impossible due circular dependency between inner , outer class, there’s no order allows define them, unless have full-fledged classloader
returns classes on demand.
the simplest solution avoid generation of inner class @ all, possible java 8:
private static threadlocal<boolean> ininstrumentmethod = threadlocal.withinitial(() -> boolean.false);
if use version prior java 8, can’t use way, best solution in case, rewrite code accept default value of null
initial value, eliminating need specify different initial value:
private static threadlocal<boolean> ininstrumentmethod = new threadlocal<>(); public static void onentry(int methodid) { if (ininstrumentmethod.get()!=null) { return; } else { ininstrumentmethod.set(true); } system.out.println("method id: " + methodid); ininstrumentmethod.set(null); }
you convert anonymous inner class top level class. since then, class has no dependency formerly outer class, defining subtype of threadlocal
first, before defining class using it, should solve issue.
Comments
Post a Comment