1. Introduction This demo shows how to interact with JMX MBean Server running on Oracle JVM in Oracle database. The demo contains shell scripts and sql scripts activating RMI listener and JMX MBean Server in a database session running java and then interacts with the server using RMI and JMX protocols. The client part for JMX connectivity is a command-line (non-GUI) JMX console. This command-line console gathers attributes and invokes operations of MBeans shipped with the current release of OJVM. 2. Installation and Requirements The demo is provided fully in the directory where this README file resides. To run this demo you need to have 'make', 'java', 'javac' and 'jar' tools available. Before you run the demo, verify that the directory where the demo runs is writeable. Also, verify that commands 'javac' and 'java' resolve to java 1.5 versions. 3. Running the demo To run the demo from a command shell do the following: % make This compiles java code, generates auxiliary files in the demo/jmx directory when necessary, and uploads necessary server-side java code in the database. After the setup, the demo initiates several RMI and JMX client-server sessions, each demonstrating a particular aspect of RMI and JMX connectivity, monitoring and management. Currently, the set includes the following sessions: * RMI session over plain socket connection (make target run_cs_rmissl_noauth) * JMX session over plan socket (target run_cs_jmx_no_ssl) * RMI session over SSL socket (target run_cs_rmissl_auth_dflt) * JMX session over SSL socket with JKS keys (target run_cs_jmx_ssl_dflt_k) * RMI session over SSL socket and programmatic SSL setup (make target run_cs_rmissl_auth_prog) Consecutive invocations of 'make' reuse the setup step. To clean all auxiliary files, do the following: % make clean 4. client/server make targets The demo executes several client/server sessions in a sequence. For each session, the server is conceptually instructed to launch the listener and wait for a client to connect. Because it is not clear how much time it takes for the server to become available, at the beginning of each sequence the client starts first in a background shell process and attempts to connect to the server. The client/server sessions are implemented with the following make targets: run_cs_rmissl_noauth run_cs_jmx_no_ssl run_cs_rmissl_auth_dflt run_cs_jmx_ssl_dflt_k run_cs_rmissl_auth_prog The target run_cs_all_modes is a sequence of all of them. All run_cs_* targets work in the following manner: first the client starts in a particular configuration, waiting to obtain connection with the server. The server is not running at this moment. The client will attempt to obtain JMX connection for 10 secs before reporting a failure. For that, each client invocation contains '-ht 10000'. The client process is forked with '&' as child process. Next line starts the server in compatible mode. This usually takes less than 10 secs and the client is able to communicate. Each client invocation contains -invoke jmxserv:type=Load stop which tells the Load bean (class jmxserv.Load) to stop the workload. This way, both the client and the server gracefully close connections and workload. run_cs_all_modes can execute several modes in a row. For further details regarding these targets read the comments in ./Makefile. 5. Make targets for getting MBean info and attribute 5.1. make ping Ping an MBean. This retrieves the bean which name descriptor is passed as BEAN variable or java.lang:type=Runtime by default. Examples: make ping this prints out info for singleton bean java.lang:type=Runtime make ping BEAN=oracle.jvm:type=OracleRuntime this prints out info for bean OracleRuntime make ping BEAN=java.lang:type=MemoryPool,name='New Generation' this prints out info for memory pool 'New Generation' 5.2 make get Get an attribute of an MBean. This retrieves an attribute of a bean Examples: make get this retrieves attribute InputArguments of singleton bean java.lang:type=Runtime make get ATTR=VmName this retrieves attribute VmName of the Runtime MBean make get BEAN=oracle.jvm:type=OracleRuntime ATTR=NewspaceSize this retrieves attribute NewspaceSize of singleton bean OracleRuntime make get BEAN=java.lang:type=MemoryPool,name='New Generation' \ ATTR=UsageThreshold this retrieves attribute UsageThreshold of memory pool 'New Generation' For further details regarding running specific JMX sessions or regards the steps comprising individual make targets, read the comments in ./Makefile. 6. Debugging flags Using make with DEBUG=1 causes lots tracing/debugging output, both on the client side and on the server. This is especially useful when debugging SSL handshaking issues. Examples: % make DEBUG=1 % make DEBUG=1 run_cs_jmx_ssl_dflt_k % make clobber; make DEBUG=1 > & out.txt # verbose, saved into file Note: tracing details on the server are dumped into the *.trc files by default. Appendix 1. Below is the output the JMX command-line console typically generates. Note: some of these lines are over 80col in wdth. . Connection Proxy : :9999 PASS Beans . RuntimeMXBean : class $Proxy0 PASS . . Name : (PID=;SID=) PASS . . PID : PASS . . SID : PASS . . MODE : DEDICATED_MODE . OperatingSystemMXBean : class $Proxy1 PASS . com.sun.management.OperatingSystemMXBean : class $Proxy2 PASS . . Uptime, ms : 11,719 PASS Process CPU time : 0 PASS . . Total physical memory : 0 kbytes PASS Free physical memory : 0 kbytes PASS . . Committed virtual memory : 0 kbytes PASS . CompilationMXBean : class $Proxy3 PASS . ThreadMXBean : class $Proxy4 PASS . . Live Threads : 8 PASS Peak : 8 PASS . . Daemon threads : 7 PASS . . Total started : 8 PASS . . . ThreadInfo : Thread Root Thread (Id = 1) TIMED_WAITING null PASS . . . . Name : Root Thread State : TIMED_WAITING . . . . BlockedCount : 0 WaitedCount : 0 . . . . Stack trace size : 3 PASS . . . . . 1 : java.lang.Thread.sleep(Native Method) PASS . . . . . 2 : jmxserv.Load.doLoad(Load.java:140) PASS . . . . . 3 : jmxserv.Load.medium(Load.java:66) PASS . . . ThreadInfo : Thread Timer-0 (Id = 3) TIMED_WAITING null PASS . . . . Name : Timer-0 State : TIMED_WAITING . . . . BlockedCount : 1 WaitedCount : 2 . . . . Stack trace size : 3 PASS . . . . . 1 : java.lang.Object.wait(Native Method) PASS . . . . . 2 : java.util.TimerThread.mainLoop(Timer.java:509) PASS . . . . . 3 : java.util.TimerThread.run(Timer.java:462) PASS . . . ThreadInfo : Thread RMI TCP Accept-0 (Id = 4) WAITING null PASS . . . . Name : RMI TCP Accept-0 State : WAITING . . . . BlockedCount : 0 WaitedCount : 0 . . . . Stack trace size : 5 PASS . . . . . 1 : java.net.PlainSocketImpl.socketAccept(Native Method) PASS . . . . . 2 : java.net.PlainSocketImpl.accept(PlainSocketImpl.java:384) PASS . . . . . 3 : java.net.ServerSocket.implAccept(ServerSocket.java:450) PASS . . . . . 4 : java.net.ServerSocket.accept(ServerSocket.java:421) PASS . . . . . 5 : sun.rmi.transport.tcp.TCPTransport.run(TCPTransport.java:340) PASS . . . ThreadInfo : Thread RMI TCP Accept-9999 (Id = 5) WAITING null PASS . . . . Name : RMI TCP Accept-9999 State : WAITING . . . . BlockedCount : 0 WaitedCount : 0 . . . . Stack trace size : 5 PASS . . . . . 1 : java.net.PlainSocketImpl.socketAccept(Native Method) PASS . . . . . 2 : java.net.PlainSocketImpl.accept(PlainSocketImpl.java:384) PASS . . . . . 3 : java.net.ServerSocket.implAccept(ServerSocket.java:450) PASS . . . . . 4 : java.net.ServerSocket.accept(ServerSocket.java:421) PASS . . . . . 5 : sun.rmi.transport.tcp.TCPTransport.run(TCPTransport.java:340) PASS . . . ThreadInfo : Thread RMI TCP Connection(1)-140.87.4.38 (Id = 6) TIMED_WAITING null PASS . . . . Name : RMI TCP Connection(1)-140.87.4.38 State : TIMED_WAITING . . . . BlockedCount : 0 WaitedCount : 0 . . . . Stack trace size : 7 PASS . . . . . 1 : java.net.SocketInputStream.socketRead0(Native Method) PASS . . . . . 2 : java.net.SocketInputStream.read(SocketInputStream.java) PASS . . . . . 3 : java.io.BufferedInputStream.fill(BufferedInputStream.java) PASS . . . . . 4 : java.io.BufferedInputStream.read(BufferedInputStream.java) PASS . . . . . 5 : java.io.FilterInputStream.read(FilterInputStream.java:66) PASS . . . . . 6 : sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:448) PASS . . . . . 7 : sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:707) PASS . . . ThreadInfo : Thread RMI TCP Connection(2)-140.87.4.38 (Id = 7) RUNNABLE null PASS . . . . Name : RMI TCP Connection(2)-140.87.4.38 State : RUNNABLE . . . . BlockedCount : 1 WaitedCount : 0 . . . . Stack trace size : 28 PASS . . . . . 1 : sun.management.ThreadImpl.getThreadInfo0(Native Method) PASS . . . . . 2 : sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:142) PASS . . . . . 3 : sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:120) PASS . . . . . 4 : sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) PASS . . . . . 5 : sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) PASS . . . . . 6 : sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) PASS . . . . . 7 : java.lang.reflect.Method.invoke(Method.java) PASS . . . . . 8 : sun.management.MXBeanSupport.invoke(MXBeanSupport.java:632) PASS . . . . . 9 : sun.management.MXBeanSupport.invoke(MXBeanSupport.java:94) PASS . . . . . 10 : com.sun.jmx.mbeanserver.DynamicMetaDataImpl.invoke(DynamicMetaDataImpl.java:213) PASS . . . . . 11 : com.sun.jmx.mbeanserver.MetaDataImpl.invoke(MetaDataImpl.java:220) PASS . . . . . 12 : com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.invoke(DefaultMBeanServerInterceptor.java:815) PASS . . . . . 13 : com.sun.jmx.mbeanserver.JmxMBeanServer.invoke(JmxMBeanServer.java:784) PASS . . . . . 14 : javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1408) PASS . . . . . 15 : javax.management.remote.rmi.RMIConnectionImpl.access$100(RMIConnectionImpl.java:81) PASS . . . . . 16 : javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1245) PASS . . . . . 17 : javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1341) PASS . . . . . 18 : javax.management.remote.rmi.RMIConnectionImpl.invoke(RMIConnectionImpl.java:782) PASS . . . . . 19 : sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) PASS . . . . . 20 : sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) PASS . . . . . 21 : sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) PASS . . . . . 22 : java.lang.reflect.Method.invoke(Method.java) PASS . . . . . 23 : sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:294) PASS . . . . . 24 : sun.rmi.transport.Transport$1.run(Transport.java:153) PASS . . . . . 25 : java.security.AccessController.doPrivileged(Native Method) PASS . . . . . 26 : sun.rmi.transport.Transport.serviceCall(Transport.java:149) PASS . . . . . 27 : sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:466) PASS . . . . . 28 : sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:707) PASS . . . ThreadInfo : Thread RMI LeaseChecker (Id = 8) TIMED_WAITING null PASS . . . . Name : RMI LeaseChecker State : TIMED_WAITING . . . . BlockedCount : 0 WaitedCount : 0 . . . . Stack trace size : 2 PASS . . . . . 1 : java.lang.Thread.sleep(Native Method) PASS . . . . . 2 : sun.rmi.transport.DGCImpl$LeaseChecker.run(DGCImpl.java:310) PASS . . . ThreadInfo : Thread JMX server connection timeout 9 (Id = 9) TIMED_WAITING null PASS . . . . Name : JMX server connection timeout 9 State : TIMED_WAITING . . . . BlockedCount : 32 WaitedCount : 22 . . . . Stack trace size : 2 PASS . . . . . 1 : java.lang.Object.wait(Native Method) PASS . . . . . 2 : com.sun.jmx.remote.internal.ServerCommunicatorAdmin$Timeout.run(ServerCommunicatorAdmin.java:150) PASS . MemoryMXBean : class $Proxy5 PASS . . Current heap size : 3,806 kbytes PASS . . Committed memory : 31,027 kbytes PASS . . Maximum heap size : 13,107,455 kbytes PASS . . Objects pending for finalization : 0 PASS . . flip verbose flag : PASS . GarbageCollectorMXBean : class $Proxy6 . Name = 'GCManager', Collections = 909, Total time spent = 6.610 seconds . Perform gc... . Total collection count : 941 PASS . Memory Pools . Pool Proxy Collection : PASS . . Number of Proxies : 8 PASS . . . Name : Malloc/Free Space PASS . . . Current size : 20 kbytes PASS Committed memory : 20 kbytes PASS . . . Maximum heap size : 4,194,303 kbytes PASS . . . Name : Stack Space PASS . . . Current size : 15 kbytes PASS Committed memory : 23 kbytes PASS . . . Maximum heap size : 262,144 kbytes PASS . . . Name : Dedicated Session Space PASS . . . Current size : 660 kbytes PASS Committed memory : 660 kbytes PASS . . . Maximum heap size : 4,194,303 kbytes PASS . . . Name : Paged Session Space PASS . . . Current size : 0 kbytes PASS Committed memory : 0 kbytes PASS . . . Maximum heap size : -1 kbytes . . . Name : Run Space PASS . . . Current size : 158 kbytes PASS Committed memory : 158 kbytes PASS . . . Maximum heap size : 4,194,175 kbytes PASS . . . Name : End Of Migration Space PASS . . . Current size : 0 kbytes PASS Committed memory : 0 kbytes PASS . . . Maximum heap size : -1 kbytes . . . Name : New Generation PASS . . . Current size : 99 kbytes PASS Committed memory : 256 kbytes PASS . . . Maximum heap size : 512 kbytes PASS . . . Name : Old Generation PASS . . . Current size : 4,174 kbytes PASS Committed memory : 29,956 kbytes PASS . . . Maximum heap size : 262,016 kbytes PASS . ClassLoadingMXBean : class $Proxy9 PASS . . Current classes loaded : 1,269 PASS Total classes unloaded : 0 PASS . . Total classes loaded : 1,269 PASS . Bean name : oracle.jvm:type=OracleRuntime PASS . OracleRuntimeMXBean : javax.management.MBeanInfo@f68f892 PASS . . OracleRuntimeMXBean : Platform = Linux Port PASS . . OracleRuntimeMXBean : WholeJVM_ExecutionElapsedTime = 47979902 PASS . . OracleRuntimeMXBean : WholeJVM_CallHeapCollectedCount = 6197791 PASS . Roundtrip time, average, ms: 43083.0 . Roundtrip time, single, diff beans ms: 210.66666666666666 . Bean name : jmxserv:type=Load PASS . Bean operation jmxserv:type=Load:stop : PASS . Result of jmxserv:type=Load:stop() : : null