2011-09-01 9 views
8

मेरे पास एक ऐसा प्रोग्राम है जिसके लिए गतिशील रूप से (यानी रन टाइम पर) एक उपलब्ध सॉकेट खोलना और उस पर एक जेएमएक्स एजेंट शुरू करना आवश्यक है। यह जेएमएक्स पैरामीटर जावा कोड के अंदर सेट किया जा रहा है और कमांड लाइन के माध्यम से नहीं। यह ठीक काम करता है। इसके बाद यह (यानी मुद्दा JMX आदेशों आदि) पर नजर रखने की जरूरत है जावा दृश्य वीएम के माध्यम से दूर सेदूरस्थ निगरानी के लिए जावा कोड के माध्यम से जेएमएक्स रिमोट पोर्ट सिस्टम पर्यावरण पैरामीटर कैसे सेट करें?

कार्यक्रम में RMI सर्वर एजेंट बॉक्स प्रबंधन से बाहर की तर्ज पर दिए गए वर्णन पर है: http://download.oracle.com/javase/6/docs/technotes/guides/management/agent.html

सवाल मुझे संक्षेप में सारांशित किया जा सकता है: जावा कोड के माध्यम से इस तरह की कमांड लाइन गुण सिस्टम स्तर पर कैसे सेट किया जा सकता है, ताकि रिमोट प्रोफाइलिंग का उपयोग किया जा सके ??

-Dcom.sun.management.jmxremote.port=1234 

"jmxremote.port" और अन्य पैरामीटर कमांड लाइन के माध्यम से स्थापित कर रहे हैं, तो दूरस्थ निगरानी ठीक काम करता है। मैं जावा के माध्यम से ऐसा करने का तरीका खोजने की कोशिश कर रहा हूं और कमांड लाइन के माध्यम से नहीं।

प्रोग्राम कमांड लाइन के माध्यम से बंदरगाह निर्दिष्ट नहीं कर सकता क्योंकि नए उपलब्ध बंदरगाह को रन टाइम पर पता लगाना है।

प्रक्रिया को दूरस्थ निगरानी की आवश्यकता है और यह स्थानीय रूप से ठीक काम करता है। यदि निम्न पैरामीटर कमांड लाइन पर निर्दिष्ट नहीं हैं, तो जावा विजुअल वीएम प्रक्रिया से कनेक्ट नहीं होता है।

-Dcom.sun.management.jmxremote.port=1234 
-Dcom.sun.management.jmxremote.authenticate=false 
-Dcom.sun.management.jmxremote.ssl=false 
-Djava.rmi.server.hostname=10.0.0.128 

मैंने कोशिश की है।

System.setProperty("com.sun.management.jmxremote.port",Integer.toString(port)); 

यह JMXConnectorServer शुरू करने से पहले प्रोग्राम में किए गए पहले कामों में से एक है। दुर्भाग्य से यह पहचाना नहीं गया है। केवल रन टाइम गुण (यानी कमांड लाइन के माध्यम से निर्दिष्ट जावा विजुअल वीएम द्वारा जेएमएक्स कनेक्शन के लिए मान्यता प्राप्त है)।

इसके अलावा जिस तरह से गुण जावा संग्रह वर्गों से निकाला जा सकता है भर में आया था, लेकिन कैसे संपत्ति का पता लगाने में नहीं पहुंच सका "com.sun.management.jmxremote.port ="

public static void setEnv(Map<String, String> newenv) throws Exception { 
    Class[] classes = Collections.class.getDeclaredClasses(); 
    Map<String, String> env = System.getenv(); 

    for(Class cl : classes) { 

    if("java.util.Collections$UnmodifiableMap".equals(cl.getName())) { 

     Field field = cl.getDeclaredField("m"); 
     field.setAccessible(true); 

     Object obj = field.get(env); 
     Map<String, String> map = (Map<String, String>) obj; 

     //map.clear(); 
     map.putAll(newenv); 
    } 
    } 
} 

किसी भी मदद की सराहना की जाएगी !

+0

आप अपने मूल प्रश्न को संपादित और कोड नमूने है कि आप टिप्पणी में पोस्टिंग की है शामिल होना चाहिए। – Perception

उत्तर

0

System.setProperty()-D कमांड लाइन विकल्प के समान है। हालांकि जाहिर है कि आपको इसे जल्द से जल्द कॉल करना होगा कि आप इसे पढ़ने से पहले संपत्ति को सेट कर रहे हैं।

+0

रिमोट प्रोफाइलिंग के लिए प्रोफाइलर द्वारा पढ़ी जाने वाली संपत्ति JVM प्रारंभ होने पर सेट की गई डिफ़ॉल्ट गुण हैं। इस मामले में जब जावा कोड शुरू होता है। मैं जावा दृश्य वीएम प्रोफाइलर को बहुत बाद में शुरू कर रहा हूं और JMXConnectorServer शुरू होने से पहले संपत्ति को सेट कर रहा हूं। संपत्ति की सवारी करने के तरीके को समझने की कोशिश कर रहा है ताकि यह एक जेएमएक्स सिस्टम स्तर के रूप में दिखाई दे और जावा दृश्य वीएम द्वारा पता लगाया जा सके ?? इसे "जल्दी पर्याप्त" कहने के तरीके के बारे में किसी भी सुझाव की सराहना करेंगे। – Devesh

+0

किसी भी '-Dcom.sun.management.jmxremote' के बिना ऐप चलाना और बाद में रनटाइम में इस एनवी को सेट करना बुरा विचार है क्योंकि जेएमएक्स एजेंट लोड नहीं किया गया था, इसलिए इसका उपयोग नहीं किया जा सकता है। – kbec

2

यदि आप रन पैरा के रूप में jmxremote env निर्दिष्ट नहीं करते हैं तो जेएमएक्स प्रबंधन एजेंट लोड नहीं किया गया था। आप गतिशील लोड करने के लिए यह कोशिश कर सकते हैं:

public static String loadJMXAgent(int port) throws IOException, AttachNotSupportedException, AgentLoadException, AgentInitializationException { 
    System.setProperty("com.sun.management.jmxremote.port", Integer.toString(port)); 
    String name = ManagementFactory.getRuntimeMXBean().getName(); 
    VirtualMachine vm = VirtualMachine.attach(name.substring(0, name.indexOf('@'))); 

    String lca = vm.getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress"); 
    if (lca == null) { 
     Path p = Paths.get(System.getProperty("java.home")).normalize(); 
     if (!"jre".equals(p.getName(p.getNameCount()-1).toString().toLowerCase())) p = p.resolve("jre"); 
     File f = p.resolve("lib").resolve("management-agent.jar").toFile(); 
     if (!f.exists()) throw new IOException("Management agent not found"); 

     vm.loadAgent(f.getCanonicalPath(), "com.sun.management.jmxremote"); 
     lca = vm.getAgentProperties().getProperty("com.sun.management.jmxremote.localConnectorAddress"); 
    } 
    vm.detach(); 
    return lca; 
} 

आप में शामिल करना चाहिए jdk/lib/tools.jar

9

kbec के जवाब रास्ता दिखाया लेकिन मेरे लिए काम नहीं किया - लेकिन this post को देखकर मैं इसे संशोधित करने और एक काम कर प्राप्त करने में सक्षम था द्वारा उपाय।

public static String loadJMXAgent(int port) throws IOException, 
     AttachNotSupportedException, AgentLoadException, 
     AgentInitializationException { 
    String name = ManagementFactory.getRuntimeMXBean().getName(); 
    VirtualMachine vm = VirtualMachine.attach(name.substring(0, 
      name.indexOf('@'))); 

    String lca = vm.getAgentProperties().getProperty(
      "com.sun.management.jmxremote.localConnectorAddress"); 
    if (lca == null) { 
     Path p = Paths.get(System.getProperty("java.home")).normalize(); 
     if (!"jre".equals(p.getName(p.getNameCount() - 1).toString() 
       .toLowerCase())) { 
      p = p.resolve("jre"); 
     } 
     File f = p.resolve("lib").resolve("management-agent.jar").toFile(); 
     if (!f.exists()) { 
      throw new IOException("Management agent not found"); 
     } 
     String options = String.format("com.sun.management.jmxremote.port=%d, " + 
       "com.sun.management.jmxremote.authenticate=false, " + 
       "com.sun.management.jmxremote.ssl=false", port); 
     vm.loadAgent(f.getCanonicalPath(), options); 
     lca = vm.getAgentProperties().getProperty(
       "com.sun.management.jmxremote.localConnectorAddress"); 
    } 
    vm.detach(); 
    return lca; 
} 

यह ग्रहण में काम करता है, लेकिन यह आदेश पंक्ति पर काम करने के लिए हो रही है अलग बात है - वहाँ के बारे में इस यहाँ Why does using the Java Attach API fail on linux? (even though maven build completes) कुछ चर्चा है, लेकिन मैं $ JAVA_HOME/lib/उपकरण जोड़ने पाया।मेरी कक्षा के लिए जार समस्या हल हो गई।

1

मैं एक विशिष्ट पोर्ट पर एक कनेक्शन है करने के लिए जावा कोड से jmxremote पोर्ट निर्दिष्ट करने के कुछ तरीके की कोशिश की और पता लगा है निम्नलिखित:

मामले में jmxremote आर्ग निर्दिष्ट किया जाता है: मंच MBean सर्वर है जेवीएम द्वारा शुरू किया गया, इससे पहले कि मेरा कोड आवश्यक jmxremote System.properties को संशोधित करता है। प्रत्येक मेबीन सर्वर में सेम की अपनी रजिस्ट्री होती है। Plaform और JVM Mbeans एक अन्य तरीके से अपने स्वयं के सेम पंजीकृत नहीं कर सका।

आप जेएमएक्स बंदरगाह गुणों को स्थापित करने के बाद वैकल्पिक एमबीएन सर्वर बना सकते हैं। यह आपके द्वारा निर्दिष्ट सही जेएमएक्स पोर्ट पर सुनेंगे।

इस तरह से आप मंच सर्वर चुनें:

MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 

इस तरह अपनी खुद की:

System.setProperty("com.sun.management.jmxremote.port","9991"); 
//... 
MBeanServer mbsCustom=MBeanServerFactory.createMBeanServer(); 

भी विचार है कि linux यह लूपबैक इंटरफ़ेस है ताकि आप सही होस्ट नाम निर्दिष्ट करना चाहिए है स्पष्ट रूप से सुनने के लिए।

यह की सिफारिश की है नहीं मंच की तुलना में एक अन्य MBeanServer उपयोग करने के लिए, मैनुअल के अनुसार, लेकिन मैं कुछ स्थितियों कल्पना कर सकते हैं जहां कमांड लाइन विकल्पों जिस तरह से आप एक सर्वर शुरू कर सकते हैं नहीं कर रहे हैं।

0

यह मेरे लिए काम करता है। संदर्भ Oracle JMX Tutorial। मुझे लगता है कि आप पहले से ही सरल एमएक्सबीन को सही उदाहरण के लिए उपयोग करने के बारे में जानते हैं।

package sample; 

import java.io.IOException; 
import java.lang.management.ManagementFactory; 
import java.rmi.registry.LocateRegistry; 
import java.util.HashMap; 
import java.util.Map; 

import javax.management.MBeanServer; 
import javax.management.ObjectName; 
import javax.management.remote.JMXConnectorServer; 
import javax.management.remote.JMXConnectorServerFactory; 
import javax.management.remote.JMXServiceURL; 

public class MBServerTest { 
    public static void loadJMXAgent(int port, MBeanServer mbs) throws IOException { 
     LocateRegistry.createRegistry(port); 
     System.out.println("Initialize the environment map"); 
     Map<String,Object> env = new HashMap<String,Object>(); 
     env.put("com.sun.management.jmxremote.authenticate", "false"); 
     env.put("com.sun.management.jmxremote.ssl", "false"); 
     System.out.println("Create an RMI connector server"); 
     JMXServiceURL url = 
      new JMXServiceURL("service:jmx:rmi:///jndi/rmi://:"+port+"/jmxrmi"); 
     JMXConnectorServer cs = 
      JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs); 

     // Start the RMI connector server. 
     // 
     System.out.println("Start the RMI connector server"); 
     cs.start(); 

    } 

    public static void main(String[] args) throws Exception { 
     MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 
     loadJMXAgent(1199,mbs); 

     SimpleStandard cache = new SimpleStandard(); 

     ObjectName name = new ObjectName(
       "org.javalobby.tnt.jmx:type=ApplicationCacheMBean"); 
     mbs.registerMBean(cache, name); 
     imitateActivity(cache); 
    } 

    private static void imitateActivity(SimpleStandard cache) { 
     while (true) { 
      try { 
       cache.cacheObject("hello"); 
       Thread.sleep(1000); 
      } catch (InterruptedException e) { 
      } 
     } 
    } 
} 
+0

नकारात्मक वोट की व्याख्या करने के लिए देखभाल? –

4

आप इस बारे में गलत तरीके से जा रहे हैं। जब तक आपका कोड कहलाता है तब तक आप इन गुणों का कोई प्रभाव नहीं ले पाएंगे।

आप MBeanServer इस तरह एक JMXConnectorServer मंच से जुड़ा हुआ एक RmiRegistry बनाने और उसके बाद बनाने की जरूरत:

private void createJmxConnectorServer() throws IOException { 
    LocateRegistry.createRegistry(1234); 
    MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); 
    JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://localhost/jndi/rmi://localhost:1234/jmxrmi"); 
    JMXConnectorServer svr = JMXConnectorServerFactory.newJMXConnectorServer(url, null, mbs); 
    svr.start(); 
} 
संबंधित मुद्दे