Es gibt eine weitere Option, für die keine Stream-Unterdrückung erforderlich ist und die nicht auf undokumentierten oder nicht unterstützten APIs basiert. Mit einem Java-Agenten können Module neu definiert werden, um die erforderlichen Pakete zu exportieren / zu öffnen. Der Code dafür würde ungefähr so aussehen:
void exportAndOpen(Instrumentation instrumentation) {
Set<Module> unnamed =
Collections.singleton(ClassLoader.getSystemClassLoader().getUnnamedModule());
ModuleLayer.boot().modules().forEach(module -> instrumentation.redefineModule(
module,
unnamed,
module.getPackages().stream().collect(Collectors.toMap(
Function.identity(),
pkg -> unnamed
)),
module.getPackages().stream().collect(Collectors.toMap(
Function.identity(),
pkg -> unnamed
)),
Collections.emptySet(),
Collections.emptyMap()
));
}
Sie können jetzt jeden illegalen Zugriff ohne Warnung ausführen, da Ihre Anwendung im unbenannten Modul enthalten ist, wie zum Beispiel:
Method method = ClassLoader.class.getDeclaredMethod("defineClass",
byte[].class, int.class, int.class);
method.setAccessible(true);
Um an die Instrumentation
Instanz zu gelangen, können Sie entweder einen recht einfachen Java-Agenten schreiben und ihn in der Befehlszeile (anstelle des Klassenpfads) angeben -javaagent:myjar.jar
. Der Agent würde nur eine premain
Methode wie folgt enthalten:
public class MyAgent {
public static void main(String arg, Instrumentation inst) {
exportAndOpen(inst);
}
}
Alternativ können Sie befestigen dynamisch die anhängen API , die bequem durch zugänglich gemacht wird die Byte-Buddy-Agent - Projekt (die ich verfasst):
exportAndOpen(ByteBuddyAgent.install());
die Sie vor dem illegalen Zugriff anrufen müssten. Beachten Sie, dass dies nur auf JDKs und auf Linux-VMs verfügbar ist, während Sie den Byte Buddy-Agenten in der Befehlszeile als Java-Agenten angeben müssten, wenn Sie ihn auf anderen VMs benötigen würden. Dies kann praktisch sein, wenn Sie die Selbstanbringung auf Test- und Entwicklungsmaschinen wünschen, auf denen normalerweise JDKs installiert sind.
Wie andere betonten, sollte dies nur als Zwischenlösung dienen, aber ich verstehe voll und ganz, dass das aktuelle Verhalten häufig die Protokollierung von Crawlern und Konsolen-Apps beeinträchtigt, weshalb ich dies selbst in Produktionsumgebungen als kurzfristige Lösung für die Verwendung von Java 9 und verwendet habe so lange hatte ich keine probleme.
Das Gute ist jedoch, dass diese Lösung gegenüber zukünftigen Updates robust ist, da jeder Vorgang, selbst der dynamische Anhang, legal ist. Mit einem Hilfsprozess umgeht Byte Buddy sogar die normalerweise verbotene Selbstanhaftung.