Cómo inyectar una clase en el paquete java.lang

Félix:

Cuando se trata de inyectar una clase que está en el java.langespacio de nombres a través java.lang.instrument.Instrumentation#appendToBootstrapClassLoaderSearch de un OpenJDK 11, no pasa nada y se lanza ningún error. Al colocar la clase de inyectar en un paquete diferente, funciona como se esperaba.

JarFile jar = new JarFile(new File("file/to/bootstrap.jar));
instrumentation.appendToBootstrapClassLoaderSearch(jar);
// throws ClassNotFoundException java/lang/Dispatcher
Class.forName("java.lang.Dispatcher", false, null);
bootstrap.jar
 └─ java/lang/Dispatcher.class

La razón por la que quiero hacer esto es para superar los problemas con algunos contenedores OSGi. Por lo general restringen la delegación en el cargador de clases de arranque a solamente ciertos paquetes. Por defecto siempre que, obviamente, incluye java.*que es por eso que quiero poner mi Dispatcherclase hay. Soy consciente de org.osgi.framework.bootdelegationque esa propiedad solamente se lee durante la inicialización. Eso significa que cuando se conecta un agente en tiempo de ejecución, ya es demasiado tarde para reemplazar este valor.

Una alternativa sería la de todos los conocidos instrumentos cargadores de clases OSGi y para la lista blanca las clases de agentes. Pero hacer que para cada marco y la prueba de que para cada versión parece menos factible.

¿Cómo puedo inyectar una clase personalizada como java.lang.Dispatcheren el cargador de clases de arranque? ¿Hay otros patrones o las mejores prácticas para evitar problemas bootdelegation OSGi?

Para proporcionar un poco más de contexto:

Mi idea es inyectar sólo ésta Dispatcherclase en el cargador de clases de arranque. El despachador básicamente sólo tiene un mapa estático. El resto de clases del agente sería cargado por un URLClassLoader dedicado que es un hijo del cargador de clases de arranque. El agente sería luego registrar MethodHandles en el Mapa del despachador para que el código de bytes inyectado puede ponerme en contacto con los MethodHandles que permiten el acceso del agente clases cargadas en el cargador de clases de agente.

Rafael Winterhalter:

Es posible mediante el uso de la API inseguro. Desde Java 9, la implementación del cargador de clases de arranque ha cambiado sólo a comprobar un jmod designado para un paquete conocido, pero la ruta de búsqueda de arranque ya no está marcada.

Java 11 también eliminó el sun.misc.Unsafe#defineClassmétodo, pero el mismo método todavía está disponible en jdk.internal.misc.Unsafe.

Usted tiene que abrir el módulo de la clase que es interno. Usted puede hacer ya sea por lo que mediante el uso de sun.misc.Unsafelo que le permite escribir un valor de campo ( accessible) sin controles de accesibilidad o mediante el uso de la API oficial de Instrumentación.

Si está utilizando Byte de amigos, echar un vistazo a las ClassInjectorimplementaciones que ofrecen implementaciones para todos los enfoques.

Hay un billete abierto para adressing la necesidad de agentes de Java para inyectar ayudante clases , sino hasta que se resuelva, esto es una solución común.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=278777&siteId=1
Recomendado
Clasificación