Invoke private Methode von Java ASM

user12801918:

Ich möchte eine private Methode aufzurufen, ohne Reflexion mit: ist es möglich, durch Verwendung von ASM und rufen Sie es eine private native Methode Haken?

Holger:

Die Herausforderung ist , eine Klasse nicht Aufrufen der generieren privateMethode über ASM oder ein ähnliches Bytecode Generierungswerkzeug. Die Herausforderung ist es, den Bytecode in die JVM zu erhalten , ohne durch den Gutachter abgelehnt.

Für OpenJDK / HotSpot, ist es , sun.misc.Unsafedie das Verfahren aufweist , defineAnonymousClass(Class<?>, byte[], Object[])die zur Erzeugung Accessor Klassen verwendet wird, wie die Laufzeitklassen funktionalen Schnittstellen der Implementierung und der aufrufende privatesynthetische Verfahren eine Lambda - Ausdruck des Körpers zu halten.

Sie könnten so Ihre Bytecode zu laden, die unter Verwendung von privateVerfahren der deklarierte Klasse als erstes Argument, um das Verfahren zugänglich zu machen. Auf der anderen Seite, der eigene Anwendungsfall JRE bedeutet , dass Sie nicht einmal so Bytecode selbst zu erzeugen , benötigen:

MethodHandles.Lookup l = MethodHandles.privateLookupIn(Class.class, MethodHandles.lookup());
MethodHandle target = l.findSpecial(Class.class, "getDeclaredFields0",
    MethodType.methodType(Field[].class, boolean.class), Class.class);
BiFunction<Class<?>,Boolean,Field[]> a = (BiFunction)LambdaMetafactory.metafactory(
    l, "apply", MethodType.methodType(BiFunction.class), target.type().generic(),
    target, target.type().changeParameterType(1, Boolean.class))
    .getTarget().invokeExact();

Dann können Sie anrufen, zum Beispiel , a.apply(Class.class, false)die berufen werden getDeclaredFields0ohne Reflexion.

privateLookupInist eine Java - 9 Methode , die in nicht-modularem Code oder die notwendige , wenn Sie arbeitet --add-opensOption bei JVM Start zu öffnen , java.baseum Ihr Modul. Es wird eine Warnung über die Reflexion Zugang und gut, es ist richtig , zu der Feststellung , dass ein solcher Zugang „wird in einer zukünftigen Version verweigert werden“. Wie auch immer, wie zu verbergen „Illegal reflektierenden Zugangs“ in Java 9 ohne JVM - Argument Warnung? interessant sein könnte.

Für Java 8, müssen Sie in die Hack - LookupKlasse eine entsprechende Lookup - Instanz zu erhalten. Diese Antwort zeigt eine Lösung, hier ist ein anderer Ansatz.

Ich denke du magst

Origin http://10.200.1.11:23101/article/api/json?id=478786&siteId=1
Empfohlen
Rangfolge