2010-01-14 18 views
5

Para utilizar las funciones de instrumentación introducidas en JDK 5, puede usar el indicador -javaagent que se pasa a la JVM. Esto inyectará una instancia de una clase Instrumentation en el método estático premain. Por ejemplo, en una clase como esta:¿Cómo puedo usar java.lang.instrument en una aplicación Eclipse RCP?

public class MyClass { 
    public static Instrumentation inst; 
    public static void premain(String options, Instrumentation inst) { 
     MyClass.inst = inst; 
    } 
} 

Con un archivo de manifiesto apropiada, puede ejecutar la siguiente manera:

java -javaagent:myfiles.jar SomeClass 

Esto llama al método premain continuación main de SomeClass. Este enfoque se usa en el Java.SizeOf Project para adivinar el tamaño aproximado de un objeto Java.

OK, ahora en Eclipse RCP each bundle has its own classloader. Esto significa que la Instrumentación estática que almacenamos en nuestra MyClass no es visible para una aplicación de Eclipse. Javaagent usa un cargador de clases, los paquetes de Eclipse se cargan con otro. Cuando accedemos al MyClass.inst desde un plugin, es null, como que la clase no es de la misma clase que la que javaagent cargó y llamó al premain.

Otras pistas sobre una posible solución son this thread en la lista de correo de rcp. Pero nada concluyente.

¿Hay alguna forma de solucionar este problema? El Eclipse-BuddyPolicy insinuado en el artículo eclipsezone suena bien. Intenté:

Eclipse-BuddyPolicy: app 

en mis complementos sin suerte. Necesito algo como Eclipse-BuddyPolicy: javaagent. ¿Algunas ideas?

+0

¿Recibe cualquier ¿Excepciones? Una trampa es tener la clase de agente sin un paquete. (es decir, MyClass puede no estar en el paquete predeterminado). ¿Funciona fuera del eclipse? – stacker

+0

Sí, funciona bien fuera de Eclipse con cosas POJO. De hecho, un "println" en el premain se muestra desde Eclipse, pero luego la instrumentación estática es nula cuando se llama desde cualquier complemento. – richq

Respuesta

4

Creo que la solución más simple es usar el objeto de propiedades globales. Tienen tienda de pre-principal objeto de instrumentación como propiedades globales y luego acceder a él desde todas partes (las propiedades del objeto es el mismo en todos los cargadores de clases):

[Editar: actualiza]

public class MyClass { 
    private static final String KEY = "my.instrumentation"; 
    public static void premain(String options, Instrumentation inst) { 
     Properties props = System.getProperties(); 
     if(props.get(KEY) == null) 
      props.put(KEY, inst); 
    } 

    public static Instrumentation getInstrumentation() { 
     return System.getProperties().get(KEY); 
    } 
} 
+0

Es una buena idea, pero lamentablemente es 'setProperty (String, String)' - no puedes poner ningún objeto viejo allí. – richq

+0

Esto se puede arreglar fácilmente (Ver la versión actualizada de mi respuesta): System.getProperties() devuelve un objeto Properties() que es una subclase de Hashtable cuya API ofrece set (String, Object) y get (String) que devuelve un Object. –

+0

Una solución tan simple, y funciona perfectamente. ¡Gracias! – richq

Cuestiones relacionadas