📄 scandiragent.java
字号:
/* * ScanDirAgent.java * * Created on July 10, 2006, 2:11 PM * * @(#)ScanDirAgent.java 1.2 06/08/02 * * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * -Redistribution of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * -Redistribution in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of Sun Microsystems, Inc. or the names of contributors may * be used to endorse or promote products derived from this software without * specific prior written permission. * * This software is provided "AS IS," without a warranty of any kind. ALL * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed, licensed or intended * for use in the design, construction, operation or maintenance of any * nuclear facility. */package com.sun.jmx.examples.scandir;import com.sun.jmx.examples.scandir.ScanManagerMXBean.ScanState;import java.io.IOException;import java.lang.management.ManagementFactory;import java.util.concurrent.BlockingQueue;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.TimeUnit;import java.util.logging.Logger;import javax.management.JMException;import javax.management.Notification;import javax.management.NotificationEmitter;import javax.management.NotificationListener;/** * <p> * The <code>ScanDirAgent</code> is the Agent class for the <i>scandir</i> * application. * This class contains the {@link #main} method to start a standalone * <i>scandir</i> application. * </p> * <p> * The {@link #main main()} method simply registers a {@link * ScanManagerMXBean} in the platform MBeanServer - see {@link #init init}, * and then waits for someone to call {@link ScanManagerMXBean#close close} * on that MBean. * </p> * <p> * When the {@link ScanManagerMXBean} state is switched to {@link * ScanManagerMXBean.ScanState#CLOSED CLOSED}, {@link #cleanup cleanup} is * called, the {@link ScanManagerMXBean} is unregistered, and the application * terminates (i.e. the main thread completes). * </p> * @author Sun Microsystems, 2006 - All rights reserved. **/public class ScanDirAgent { /** * A logger for this class. **/ private static final Logger LOG = Logger.getLogger(ScanDirAgent.class.getName()); // Proxy to the ScanManagerMXBean - created by init(); // private volatile ScanManagerMXBean proxy = null; // A queue to put received Notifications. // private final BlockingQueue<Notification> queue; // A listener that will put notifications into the queue. // private final NotificationListener listener; /** * Creates a new instance of ScanDirAgent * You will need to call {@link #init()} later on in order to initialize * the application. * @see #main **/ public ScanDirAgent() { // Initialize the notification queue queue = new LinkedBlockingQueue<Notification>(); // Creates the listener. listener = new NotificationListener() { public void handleNotification(Notification notification, Object handback) { try { // Just put the received notification in the queue. // It will be consumed later on by 'waitForClose()' // LOG.finer("Queuing received notification "+notification); queue.put(notification); } catch (InterruptedException ex) { // OK } } }; } /** * Initialize the application by registering a ScanManagerMXBean in * the platform MBeanServer * @throws java.io.IOException Registration failed for communication-related reasons. * @throws javax.management.JMException Registration failed for JMX-related reasons. */ public void init() throws IOException, JMException { // Registers the ScanManagerMXBean singleton in the // platform MBeanServer // proxy = ScanManager.register(); // Registers a NotificationListener with the ScanManagerMXBean in // order to receive state changed notifications. // ((NotificationEmitter)proxy).addNotificationListener(listener,null,null); } /** * Cleanup after close: unregister the ScanManagerMXBean singleton. * @throws java.io.IOException Cleanup failed for communication-related reasons. * @throws javax.management.JMException Cleanup failed for JMX-related reasons. */ public void cleanup() throws IOException, JMException { try { ((NotificationEmitter)proxy). removeNotificationListener(listener,null,null); } finally { ManagementFactory.getPlatformMBeanServer(). unregisterMBean(ScanManager.SCAN_MANAGER_NAME); } } /** * Wait for someone to call 'close()' on the ScanManagerMXBean singleton. * Every time its state changes, the ScanManagerMXBean emits a notification. * We don't rely on the notification content (if we were using a remote * connection, we could miss some notifications) - we simply use the * state change notifications to react more quickly to state changes. * We do so simply by polling the {@link BlockingQueue} in which our * listener is pushing notifications, and checking the ScanManagerMXBean * state every time that a notification is received. * <p> * We can do so because we know that once the ScanManagerMXBean state is * switched to 'CLOSED', it will remain 'CLOSED' whatsoever. <br> * Therefore we don't need to concern ourselves with the possibility of * missing the window in which the ScanManagerMXBean state's will be * CLOSED, because that particular window stays opened forever. * <p> * Had we wanted to wait for 'RUNNING', we would have needed to apply * a different strategy - e.g. by taking into account the actual content * of the state changed notifications we received. * @throws java.io.IOException wait failed - a communication problem occurred. * @throws javax.management.JMException wait failed - the MBeanServer threw an exception. */ public void waitForClose() throws IOException, JMException { // Wait until state is closed while(proxy.getState() != ScanState.CLOSED ) { try { // Wake up at least every 30 seconds - if we missed a // notification - we will at least get a chance to // call getState(). 30 seconds is obviously quite // arbitrary - if this were a real daemon - id'be tempted // to wait 30 minutes - knowing that any incoming // notification will wake me up anyway. // Note: we simply use the state change notifications to // react more quickly to state changes: see javadoc above. // queue.poll(30,TimeUnit.SECONDS); } catch (InterruptedException ex) { // OK } } } /** * The agent's main: {@link #init registers} a {@link ScanManagerMXBean}, * {@link #waitForClose waits} until its state is {@link * ScanManagerMXBean.ScanState#CLOSED CLOSED}, {@link #cleanup cleanup} * and exits. * @param args the command line arguments - ignored * @throws java.io.IOException A communication problem occurred. * @throws javax.management.JMException A JMX problem occurred. */ public static void main(String[] args) throws IOException, JMException { System.out.println("Initializing ScanManager..."); final ScanDirAgent agent = new ScanDirAgent(); agent.init(); try { System.out.println("Waiting for ScanManager to close..."); agent.waitForClose(); } finally { System.out.println("Cleaning up..."); agent.cleanup(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -