diff --git a/jdk/src/share/classes/sun/management/jdp/JdpController.java b/jdk/src/share/classes/sun/management/jdp/JdpController.java index 3083c972cac..9b90b594271 100644 --- a/jdk/src/share/classes/sun/management/jdp/JdpController.java +++ b/jdk/src/share/classes/sun/management/jdp/JdpController.java @@ -29,6 +29,12 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.util.UUID; +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import sun.management.VMManagement; + /** * JdpController is responsible to create and manage a broadcast loop * @@ -126,6 +132,25 @@ public final class JdpController { } } + // Get the process id of the current running Java process + private static Integer getProcessId() { + try { + // Get the current process id using a reflection hack + RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean(); + Field jvm = runtime.getClass().getDeclaredField("jvm"); + jvm.setAccessible(true); + + VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime); + Method pid_method = mgmt.getClass().getDeclaredMethod("getProcessId"); + pid_method.setAccessible(true); + Integer pid = (Integer) pid_method.invoke(mgmt); + return pid; + } catch(Exception ex) { + return null; + } + } + + /** * Starts discovery service * @@ -173,6 +198,20 @@ public final class JdpController { // it the key is skipped. PacketWriter is responsible to skip keys having null value. packet.setInstanceName(instanceName); + // Set rmi server hostname if it explicitly specified by user with + // java.rmi.server.hostname + String rmiHostname = System.getProperty("java.rmi.server.hostname"); + packet.setRmiHostname(rmiHostname); + + // Set broadcast interval + packet.setBroadcastInterval(new Integer(pause).toString()); + + // Set process id + Integer pid = getProcessId(); + if (pid != null) { + packet.setProcessId(pid.toString()); + } + JdpBroadcaster bcast = new JdpBroadcaster(address, sourceAddress, port, ttl); // Stop discovery service if it's already running diff --git a/jdk/src/share/classes/sun/management/jdp/JdpJmxPacket.java b/jdk/src/share/classes/sun/management/jdp/JdpJmxPacket.java index 60aea2bd40f..2ff2d18af08 100644 --- a/jdk/src/share/classes/sun/management/jdp/JdpJmxPacket.java +++ b/jdk/src/share/classes/sun/management/jdp/JdpJmxPacket.java @@ -64,11 +64,27 @@ public final class JdpJmxPacket * Name of Java instance */ public final static String INSTANCE_NAME_KEY = "INSTANCE_NAME"; + /** + * PID of java process, optional presented if it could be obtained + */ + public final static String PROCESS_ID_KEY = "PROCESS_ID"; + /** + * Hostname of rmi server, optional presented if user overrides rmi server + * hostname by java.rmi.server.hostname property + */ + public final static String RMI_HOSTNAME_KEY = "RMI_HOSTNAME"; + /** + * Configured broadcast interval, optional + */ + public final static String BROADCAST_INTERVAL_KEY = "BROADCAST_INTERVAL"; private UUID id; private String mainClass; private String jmxServiceUrl; private String instanceName; + private String processId; + private String rmiHostname; + private String broadcastInterval; /** * Create new instance from user provided data. Set mandatory fields @@ -99,6 +115,9 @@ public final class JdpJmxPacket this.jmxServiceUrl = p.get(JMX_SERVICE_URL_KEY); this.mainClass = p.get(MAIN_CLASS_KEY); this.instanceName = p.get(INSTANCE_NAME_KEY); + this.processId = p.get(PROCESS_ID_KEY); + this.rmiHostname = p.get(RMI_HOSTNAME_KEY); + this.broadcastInterval = p.get(BROADCAST_INTERVAL_KEY); } /** @@ -150,6 +169,30 @@ public final class JdpJmxPacket return instanceName; } + public String getProcessId() { + return processId; + } + + public void setProcessId(String processId) { + this.processId = processId; + } + + public String getRmiHostname() { + return rmiHostname; + } + + public void setRmiHostname(String rmiHostname) { + this.rmiHostname = rmiHostname; + } + + public String getBroadcastInterval() { + return broadcastInterval; + } + + public void setBroadcastInterval(String broadcastInterval) { + this.broadcastInterval = broadcastInterval; + } + /** * * @return assembled packet ready to be sent across a Net @@ -164,6 +207,10 @@ public final class JdpJmxPacket writer.addEntry(MAIN_CLASS_KEY, mainClass); writer.addEntry(JMX_SERVICE_URL_KEY, jmxServiceUrl); writer.addEntry(INSTANCE_NAME_KEY, instanceName); + writer.addEntry(PROCESS_ID_KEY, processId); + writer.addEntry(RMI_HOSTNAME_KEY, rmiHostname); + writer.addEntry(BROADCAST_INTERVAL_KEY, broadcastInterval); + return writer.getPacketBytes(); } diff --git a/jdk/test/sun/management/jdp/JdpClient.java b/jdk/test/sun/management/jdp/JdpClient.java index 4a2348468b2..992c45e1af5 100644 --- a/jdk/test/sun/management/jdp/JdpClient.java +++ b/jdk/test/sun/management/jdp/JdpClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,8 +35,10 @@ import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.util.Collections; import java.util.Enumeration; +import java.util.Map; import sun.management.jdp.JdpException; import sun.management.jdp.JdpJmxPacket; +import sun.management.jdp.JdpPacketReader; public class JdpClient { @@ -47,6 +49,31 @@ public class JdpClient { private static int maxPacketCount = 1; private static int maxEmptyPacketCount = 10; + private void get(Map map, String key) + throws JdpException { + + if (map.get(key) == null) { + throw new JdpException("Test failed, packet field " + key + " missed"); + } + } + + private void checkFieldPresence(JdpJmxPacket p) + throws IOException, JdpException { + + byte[] b = p.getPacketData(); + + JdpPacketReader reader = new JdpPacketReader(b); + Map pMap = reader.getDiscoveryDataAsMap(); + + get(pMap, JdpJmxPacket.UUID_KEY); + get(pMap, JdpJmxPacket.MAIN_CLASS_KEY); + get(pMap, JdpJmxPacket.JMX_SERVICE_URL_KEY); + // get(pMap, JdpJmxPacket.INSTANCE_NAME_KEY); + get(pMap, JdpJmxPacket.PROCESS_ID_KEY); + get(pMap, JdpJmxPacket.BROADCAST_INTERVAL_KEY); + get(pMap, JdpJmxPacket.RMI_HOSTNAME_KEY); + } + PacketListener(DatagramChannel channel) { this.channel = channel; @@ -67,6 +94,8 @@ public class JdpClient { try { while (true) { + // Use tcpdump -U -w - -s 1400 -c 2 -vv port 7095 + // to verify that correct packet being sent sel.selectedKeys().clear(); buf.rewind(); @@ -87,10 +116,10 @@ public class JdpClient { buf.flip(); byte[] dgramData = new byte[buf.remaining()]; buf.get(dgramData); - try { JdpJmxPacket packet = new JdpJmxPacket(dgramData); JdpDoSomething.printJdpPacket(packet); + checkFieldPresence(packet); if(++count > maxPacketCount){ break; } diff --git a/jdk/test/sun/management/jdp/JdpDoSomething.java b/jdk/test/sun/management/jdp/JdpDoSomething.java index ad9366cbaa4..56032df8329 100644 --- a/jdk/test/sun/management/jdp/JdpDoSomething.java +++ b/jdk/test/sun/management/jdp/JdpDoSomething.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,7 @@ import sun.management.jdp.JdpException; public class JdpDoSomething { private static final String lockFileName = "JdpDoSomething.lck"; - private static final boolean verbose=false; + private static final boolean verbose = false; public static boolean getVerbose(){ return verbose; @@ -52,6 +52,9 @@ public class JdpDoSomething { System.out.println("Jmx: " + p.getJmxServiceUrl()); System.out.println("Main: " + p.getMainClass()); System.out.println("InstanceName: " + p.getInstanceName()); + System.out.println("ProccessId: " + p.getProcessId()); + System.out.println("BroadcastInterval: " + p.getBroadcastInterval()); + System.out.println("Rmi Hostname: " + p.getRmiHostname()); System.out.flush(); } diff --git a/jdk/test/sun/management/jdp/JdpTest.sh b/jdk/test/sun/management/jdp/JdpTest.sh index 12698e4a570..18f88a5430c 100644 --- a/jdk/test/sun/management/jdp/JdpTest.sh +++ b/jdk/test/sun/management/jdp/JdpTest.sh @@ -1,6 +1,6 @@ #!/bin/sh -x -# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ _do_compile(){ if [ ! -d ${_testclasses} ] then - mkdir -p ${_testclasses} + mkdir -p ${_testclasses} fi rm -f ${_testclasses}/*.class @@ -64,7 +64,7 @@ _do_compile(){ # Compile testcase ${COMPILEJAVA}/bin/javac -XDignore.symbol.file -d ${_testclasses} \ JdpUnitTest.java \ - JdpDoSomething.java \ + JdpDoSomething.java \ JdpClient.java @@ -84,10 +84,10 @@ _app_start(){ ${TESTJAVA}/bin/java -server $* -cp ${_testclasses} ${testappname} >> ${_logname} 2>&1 & _last_pid=$! -# wait until VM is actually starts. +# wait until VM is actually starts. # please note, if vm doesn't start for some reason # jtreg kills the test by timeout. Don't file a bug. - cnt=1 + cnt=1 while true do npid=`_get_pid` @@ -135,7 +135,6 @@ _testme(){ -Dcom.sun.management.jdp.port=${_port} \ -Dcom.sun.management.jdp.address=${_ip} \ JdpClient - } @@ -156,18 +155,20 @@ test_01(){ _echo "**** Test one ****" _app_start JdpUnitTest \ - -Dcom.sun.management.jdp.port=${_port} \ - -Dcom.sun.management.jdp.address=${_ip} \ - -Dcom.sun.management.jdp.pause=5 + -Dcom.sun.management.jdp.port=${_port} \ + -Dcom.sun.management.jdp.address=${_ip} \ + -Dcom.sun.management.jdp.name=testme \ + -Djava.rmi.server.hostname=localhost \ + -Dcom.sun.management.jdp.pause=5 res=`_testme` case "${res}" in OK*) - _echo "Passed" + _echo "Passed" ;; *) - _echo "Failed!" + _echo "Failed!" ;; esac @@ -179,21 +180,23 @@ test_02(){ _echo "**** Test two ****" _app_start JdpDoSomething \ - -Dcom.sun.management.jdp.port=${_port} \ - -Dcom.sun.management.jdp.address=${_ip} \ - -Dcom.sun.management.jdp.pause=5 \ - -Dcom.sun.management.jmxremote.port=${_jmxport} \ - -Dcom.sun.management.jmxremote.authenticate=false \ - -Dcom.sun.management.jmxremote.ssl=false + -Dcom.sun.management.jdp.port=${_port} \ + -Dcom.sun.management.jdp.address=${_ip} \ + -Dcom.sun.management.jdp.pause=5 \ + -Dcom.sun.management.jdp.name=testme \ + -Djava.rmi.server.hostname=localhost \ + -Dcom.sun.management.jmxremote.port=${_jmxport} \ + -Dcom.sun.management.jmxremote.authenticate=false \ + -Dcom.sun.management.jmxremote.ssl=false res=`_testme` case "${res}" in OK*) - _echo "Passed" + _echo "Passed" ;; *) - _echo "Failed!" + _echo "Failed!" ;; esac @@ -218,10 +221,10 @@ test_03(){ case "${res}" in OK*) - _echo "Passed" + _echo "Passed" ;; *) - _echo "Failed!" + _echo "Failed!" ;; esac @@ -233,19 +236,21 @@ test_04(){ _echo "**** Test four ****" _app_start JdpDoSomething \ - -Dcom.sun.management.jmxremote.autodiscovery=true \ - -Dcom.sun.management.jmxremote.port=${_jmxport} \ - -Dcom.sun.management.jmxremote.authenticate=false \ - -Dcom.sun.management.jmxremote.ssl=false + -Dcom.sun.management.jmxremote.autodiscovery=true \ + -Dcom.sun.management.jdp.name=testme \ + -Djava.rmi.server.hostname=localhost \ + -Dcom.sun.management.jmxremote.port=${_jmxport} \ + -Dcom.sun.management.jmxremote.authenticate=false \ + -Dcom.sun.management.jmxremote.ssl=false res=`_testme` case "${res}" in OK*) - _echo "Passed" + _echo "Passed" ;; *) - _echo "Failed!" + _echo "Failed!" ;; esac @@ -269,10 +274,10 @@ test_05(){ case "${res}" in OK*) - _echo "Passed" + _echo "Passed" ;; *) - _echo "Failed!" + _echo "Failed!" ;; esac @@ -300,28 +305,28 @@ fi for parm in "$@" do - case $parm in - --verbose) _verbose=yes ;; - --jtreg) _jtreg=yes ;; - --no-compile) _compile=no ;; - --testsuite=*) _testsuite=`_echo $parm | sed "s,^--.*=\(.*\),\1,"` ;; - *) - echo "Undefined parameter $parm. Try --help for help" - exit - ;; - esac + case $parm in + --verbose) _verbose=yes ;; + --jtreg) _jtreg=yes ;; + --no-compile) _compile=no ;; + --testsuite=*) _testsuite=`_echo $parm | sed "s,^--.*=\(.*\),\1,"` ;; + *) + echo "Undefined parameter $parm. Try --help for help" + exit + ;; + esac done if [ "${_compile}" = "yes" ] then - _do_compile + _do_compile fi if [ "${_jtreg}" = "yes" ] then - _testclasses=${TESTCLASSES} - _testsrc=${TESTSRC} - _logname="output.txt" + _testclasses=${TESTCLASSES} + _testsrc=${TESTSRC} + _logname="output.txt" fi # Make sure _tesclasses is absolute path