2016-03-22 34 views
2

için Java Enstrümanları açılamıyor Bir Java uygulamasını çalıştırmak için bir tomcat7 örneğini kullanıyorum. Uygulamamın maruz kalan Java enstrümantasyonuna ihtiyacı var. Bu bir javaagent ile yapılır ve ajanı başlangıçta setenv.bat komut dosyasındaki JVM'ye iletirim. Gerekli olan bölüme sahip bildirim dosyasında Tomcat jvm

set JAVA_OPTS=%JAVA_OPTS% -javaagent:"C:\path\to\agent.jar" 

: statik bir yöntem ile bir statik değişken erişilebilir JVM sağladığı aletleri atamak madde sınıfının premain yönteminde

Premain-Class: package.name.agent.ExposeInstrumentation 

public final class ExposeInstrumentation { 
private static Instrumentation s_instrumentation; 
public static void premain(String arguments, Instrumentation instrumentation) { 
    s_instrumentation = instrumentation; 
} 

public static Instrumentation getInstrumentation() { 
    return s_instrumentation; 
} 
} 

Ama kodunda böyle yaptığımda:

Instrumentation instrumentation = ExposeInstrumentation.getInstrumentation(); 

getInstrumentation() null değerini döndürür;

Sorun nedir?

GÜNCELLEME bazı ileri hata ayıklama yaptım ve premain çalıştırılmaktadır ve s_instrumentation enstrümantasyon alır, ama benim kod s_instumentation ilerleyen bölümlerinde getInstrumentation çağırdığınızda null olarak ayarlanır. Bu, değerin geçerli düşünce olduğunu düşündüğüm tuhaf bir şey.

+0

'Premain 'yönteminiz gerçekten aranıyor mu? – Berger

+0

premain yürütülür ama – dragosb

cevap

1

ExposeInstrumentation sınıfını iki kez yüklediğinizi varsayalım. Bir kez uygulama sınıfı yükleyici olan child-first (reverse-order) ve bir kez sınıfın otomatik olarak sistem sınıf yükleyicisi tarafından yüklendiği Java aracısı aracılığıyla. Sonuç olarak, ExposeInstrumentation sınıfı, alanın ayarlanmadığı uygulamadan birine eriştiğiniz iki kez yüklenir.

Açıkça sistem sınıfı yükleyicisi tarafından yüklenen sınıfını erişerek bu çözebilir:

class ExposeInstrumentation { 

    // public to assure accessability 
    public static Instrumentation s_instrumentation; 

    public static void premain(String arguments, Instrumentation inst) { 
    s_instrumentation = inst; 
    } 

    public static Instrumentation getInstrumentation() { 
    try { 
     return (Instrumentation) ClassLoader.getSystemClassLoader() 
      .loadClass(ExposeInstrumentation.class.getName()) 
      .getDeclaredField("s_instrumentation") 
      .get(null); 
    } catch(Exception e) { 
     return null; 
    } 
    } 
} 

Ayrıca bir ajanın bu işlevselliği ve daha fazla (çalışma zamanı kurulum) sunmaktadır Byte Buddy Agent project kontrol edebilirsiniz. Byte Buddy ile ByteBuddyAgent.getInstrumentation()'u arayabilirsiniz.

+0

herhangi bir enstrümantasyon almıyorum da ... ExposeInstrumentation yüklemeden ClassLoader uygulamasını durdurmanın bir yolu var mı? – dragosb

+0

"findClass" yerine "loadClass" olmalıdır. 'ExposeInstrumentation' sınıfını kendi modülüne ekleyerek ve web uygulaması için ona * verilen * kapsam bağımlılığını bildirerek çift yüklemeyi engelleyebilirsiniz. Ajan eklendiği sürece, bu işe yarayacaktır. –