feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
52
jdkSrc/jdk8/javax/management/remote/JMXAddressable.java
Normal file
52
jdkSrc/jdk8/javax/management/remote/JMXAddressable.java
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
/**
|
||||
* <p>Implemented by objects that can have a {@code JMXServiceURL} address.
|
||||
* All {@link JMXConnectorServer} objects implement this interface.
|
||||
* Depending on the connector implementation, a {@link JMXConnector}
|
||||
* object may implement this interface too. {@code JMXConnector}
|
||||
* objects for the RMI Connector are instances of
|
||||
* {@link javax.management.remote.rmi.RMIConnector RMIConnector} which
|
||||
* implements this interface.</p>
|
||||
*
|
||||
* <p>An object implementing this interface might not have an address
|
||||
* at a given moment. This is indicated by a null return value from
|
||||
* {@link #getAddress()}.</p>
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public interface JMXAddressable {
|
||||
/**
|
||||
* <p>The address of this object.</p>
|
||||
*
|
||||
* @return the address of this object, or null if it
|
||||
* does not have one.
|
||||
*/
|
||||
public JMXServiceURL getAddress();
|
||||
}
|
||||
70
jdkSrc/jdk8/javax/management/remote/JMXAuthenticator.java
Normal file
70
jdkSrc/jdk8/javax/management/remote/JMXAuthenticator.java
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2007, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
import java.security.Principal;
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
/**
|
||||
* <p>Interface to define how remote credentials are converted into a
|
||||
* JAAS Subject. This interface is used by the RMI Connector Server,
|
||||
* and can be used by other connector servers.</p>
|
||||
*
|
||||
* <p>The user-defined authenticator instance is passed to the
|
||||
* connector server in the environment map as the value of the
|
||||
* attribute {@link JMXConnectorServer#AUTHENTICATOR}. For connector
|
||||
* servers that use only this authentication system, if this attribute
|
||||
* is not present or its value is <code>null</code> then no user
|
||||
* authentication will be performed and full access to the methods
|
||||
* exported by the <code>MBeanServerConnection</code> object will be
|
||||
* allowed.</p>
|
||||
*
|
||||
* <p>If authentication is successful then an authenticated
|
||||
* {@link Subject subject} filled in with its associated
|
||||
* {@link Principal principals} is returned. Authorization checks
|
||||
* will be then performed based on the given set of principals.</p>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface JMXAuthenticator {
|
||||
|
||||
/**
|
||||
* <p>Authenticates the <code>MBeanServerConnection</code> client
|
||||
* with the given client credentials.</p>
|
||||
*
|
||||
* @param credentials the user-defined credentials to be passed
|
||||
* into the server in order to authenticate the user before
|
||||
* creating the <code>MBeanServerConnection</code>. The actual
|
||||
* type of this parameter, and whether it can be null, depends on
|
||||
* the connector.
|
||||
*
|
||||
* @return the authenticated subject containing its associated principals.
|
||||
*
|
||||
* @exception SecurityException if the server cannot authenticate the user
|
||||
* with the provided credentials.
|
||||
*/
|
||||
public Subject authenticate(Object credentials);
|
||||
}
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
import javax.management.Notification;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
/**
|
||||
* <p>Notification emitted when a client connection is opened or
|
||||
* closed or when notifications are lost. These notifications are
|
||||
* sent by connector servers (instances of {@link JMXConnectorServer})
|
||||
* and by connector clients (instances of {@link JMXConnector}). For
|
||||
* certain connectors, a session can consist of a sequence of
|
||||
* connections. Connection-opened and connection-closed notifications
|
||||
* will be sent for each one.</p>
|
||||
*
|
||||
* <p>The notification type is one of the following:</p>
|
||||
*
|
||||
* <table summary="JMXConnectionNotification Types">
|
||||
*
|
||||
* <tr>
|
||||
* <th align=left>Type</th>
|
||||
* <th align=left>Meaning</th>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td><code>jmx.remote.connection.opened</code></td>
|
||||
* <td>A new client connection has been opened.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td><code>jmx.remote.connection.closed</code></td>
|
||||
* <td>A client connection has been closed.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td><code>jmx.remote.connection.failed</code></td>
|
||||
* <td>A client connection has failed unexpectedly.</td>
|
||||
* </tr>
|
||||
*
|
||||
* <tr>
|
||||
* <td><code>jmx.remote.connection.notifs.lost</code></td>
|
||||
* <td>A client connection has potentially lost notifications. This
|
||||
* notification only appears on the client side.</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
* <p>The <code>timeStamp</code> of the notification is a time value
|
||||
* (consistent with {@link System#currentTimeMillis()}) indicating
|
||||
* when the notification was constructed.</p>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class JMXConnectionNotification extends Notification {
|
||||
|
||||
private static final long serialVersionUID = -2331308725952627538L;
|
||||
|
||||
/**
|
||||
* <p>Notification type string for a connection-opened notification.
|
||||
*/
|
||||
public static final String OPENED = "jmx.remote.connection.opened";
|
||||
|
||||
/**
|
||||
* <p>Notification type string for a connection-closed notification.
|
||||
*/
|
||||
public static final String CLOSED = "jmx.remote.connection.closed";
|
||||
|
||||
/**
|
||||
* <p>Notification type string for a connection-failed notification.
|
||||
*/
|
||||
public static final String FAILED = "jmx.remote.connection.failed";
|
||||
|
||||
/**
|
||||
* <p>Notification type string for a connection that has possibly
|
||||
* lost notifications.</p>
|
||||
*/
|
||||
public static final String NOTIFS_LOST =
|
||||
"jmx.remote.connection.notifs.lost";
|
||||
|
||||
/**
|
||||
* Constructs a new connection notification. The {@link
|
||||
* #getSource() source} of the notification depends on whether it
|
||||
* is being sent by a connector server or a connector client:
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li>For a connector server, if it is registered in an MBean
|
||||
* server, the source is the {@link ObjectName} under which it is
|
||||
* registered. Otherwise, it is a reference to the connector
|
||||
* server object itself, an instance of a subclass of {@link
|
||||
* JMXConnectorServer}.
|
||||
*
|
||||
* <li>For a connector client, the source is a reference to the
|
||||
* connector client object, an instance of a class implementing
|
||||
* {@link JMXConnector}.
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* @param type the type of the notification. This is usually one
|
||||
* of the constants {@link #OPENED}, {@link #CLOSED}, {@link
|
||||
* #FAILED}, {@link #NOTIFS_LOST}. It is not an error for it to
|
||||
* be a different string.
|
||||
*
|
||||
* @param source the connector server or client emitting the
|
||||
* notification.
|
||||
*
|
||||
* @param connectionId the ID of the connection within its
|
||||
* connector server.
|
||||
*
|
||||
* @param sequenceNumber a non-negative integer. It is expected
|
||||
* but not required that this number will be greater than any
|
||||
* previous <code>sequenceNumber</code> in a notification from
|
||||
* this source.
|
||||
*
|
||||
* @param message an unspecified text message, typically containing
|
||||
* a human-readable description of the event. Can be null.
|
||||
*
|
||||
* @param userData an object whose type and meaning is defined by
|
||||
* the connector server. Can be null.
|
||||
*
|
||||
* @exception NullPointerException if <code>type</code>,
|
||||
* <code>source</code>, or <code>connectionId</code> is null.
|
||||
*
|
||||
* @exception IllegalArgumentException if
|
||||
* <code>sequenceNumber</code> is negative.
|
||||
*/
|
||||
public JMXConnectionNotification(String type,
|
||||
Object source,
|
||||
String connectionId,
|
||||
long sequenceNumber,
|
||||
String message,
|
||||
Object userData) {
|
||||
/* We don't know whether the parent class (Notification) will
|
||||
throw an exception if the type or source is null, because
|
||||
JMX 1.2 doesn't specify that. So we make sure it is not
|
||||
null, in case it would throw the wrong exception
|
||||
(e.g. IllegalArgumentException instead of
|
||||
NullPointerException). Likewise for the sequence number. */
|
||||
super((String) nonNull(type),
|
||||
nonNull(source),
|
||||
Math.max(0, sequenceNumber),
|
||||
System.currentTimeMillis(),
|
||||
message);
|
||||
if (type == null || source == null || connectionId == null)
|
||||
throw new NullPointerException("Illegal null argument");
|
||||
if (sequenceNumber < 0)
|
||||
throw new IllegalArgumentException("Negative sequence number");
|
||||
this.connectionId = connectionId;
|
||||
setUserData(userData);
|
||||
}
|
||||
|
||||
private static Object nonNull(Object arg) {
|
||||
if (arg == null)
|
||||
return "";
|
||||
else
|
||||
return arg;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The connection ID to which this notification pertains.
|
||||
*
|
||||
* @return the connection ID.
|
||||
*/
|
||||
public String getConnectionId() {
|
||||
return connectionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @serial The connection ID to which this notification pertains.
|
||||
* @see #getConnectionId()
|
||||
**/
|
||||
private final String connectionId;
|
||||
}
|
||||
299
jdkSrc/jdk8/javax/management/remote/JMXConnector.java
Normal file
299
jdkSrc/jdk8/javax/management/remote/JMXConnector.java
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import javax.management.ListenerNotFoundException;
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.NotificationFilter;
|
||||
import javax.management.NotificationListener;
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
/**
|
||||
* <p>The client end of a JMX API connector. An object of this type can
|
||||
* be used to establish a connection to a connector server.</p>
|
||||
*
|
||||
* <p>A newly-created object of this type is unconnected. Its {@link
|
||||
* #connect connect} method must be called before it can be used.
|
||||
* However, objects created by {@link
|
||||
* JMXConnectorFactory#connect(JMXServiceURL, Map)
|
||||
* JMXConnectorFactory.connect} are already connected.</p>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface JMXConnector extends Closeable {
|
||||
/**
|
||||
* <p>Name of the attribute that specifies the credentials to send
|
||||
* to the connector server during connection. The value
|
||||
* associated with this attribute, if any, is a serializable
|
||||
* object of an appropriate type for the server's {@link
|
||||
* JMXAuthenticator}.
|
||||
*/
|
||||
public static final String CREDENTIALS =
|
||||
"jmx.remote.credentials";
|
||||
|
||||
/**
|
||||
* <p>Establishes the connection to the connector server. This
|
||||
* method is equivalent to {@link #connect(Map)
|
||||
* connect(null)}.</p>
|
||||
*
|
||||
* @exception IOException if the connection could not be made
|
||||
* because of a communication problem.
|
||||
*
|
||||
* @exception SecurityException if the connection could not be
|
||||
* made for security reasons.
|
||||
*/
|
||||
public void connect() throws IOException;
|
||||
|
||||
/**
|
||||
* <p>Establishes the connection to the connector server.</p>
|
||||
*
|
||||
* <p>If <code>connect</code> has already been called successfully
|
||||
* on this object, calling it again has no effect. If, however,
|
||||
* {@link #close} was called after <code>connect</code>, the new
|
||||
* <code>connect</code> will throw an <code>IOException</code>.
|
||||
*
|
||||
* <p>Otherwise, either <code>connect</code> has never been called
|
||||
* on this object, or it has been called but produced an
|
||||
* exception. Then calling <code>connect</code> will attempt to
|
||||
* establish a connection to the connector server.</p>
|
||||
*
|
||||
* @param env the properties of the connection. Properties in
|
||||
* this map override properties in the map specified when the
|
||||
* <code>JMXConnector</code> was created, if any. This parameter
|
||||
* can be null, which is equivalent to an empty map.
|
||||
*
|
||||
* @exception IOException if the connection could not be made
|
||||
* because of a communication problem.
|
||||
*
|
||||
* @exception SecurityException if the connection could not be
|
||||
* made for security reasons.
|
||||
*/
|
||||
public void connect(Map<String,?> env) throws IOException;
|
||||
|
||||
/**
|
||||
* <p>Returns an <code>MBeanServerConnection</code> object
|
||||
* representing a remote MBean server. For a given
|
||||
* <code>JMXConnector</code>, two successful calls to this method
|
||||
* will usually return the same <code>MBeanServerConnection</code>
|
||||
* object, though this is not required.</p>
|
||||
*
|
||||
* <p>For each method in the returned
|
||||
* <code>MBeanServerConnection</code>, calling the method causes
|
||||
* the corresponding method to be called in the remote MBean
|
||||
* server. The value returned by the MBean server method is the
|
||||
* value returned to the client. If the MBean server method
|
||||
* produces an <code>Exception</code>, the same
|
||||
* <code>Exception</code> is seen by the client. If the MBean
|
||||
* server method, or the attempt to call it, produces an
|
||||
* <code>Error</code>, the <code>Error</code> is wrapped in a
|
||||
* {@link JMXServerErrorException}, which is seen by the
|
||||
* client.</p>
|
||||
*
|
||||
* <p>Calling this method is equivalent to calling
|
||||
* {@link #getMBeanServerConnection(Subject) getMBeanServerConnection(null)}
|
||||
* meaning that no delegation subject is specified and that all the
|
||||
* operations called on the <code>MBeanServerConnection</code> must
|
||||
* use the authenticated subject, if any.</p>
|
||||
*
|
||||
* @return an object that implements the
|
||||
* <code>MBeanServerConnection</code> interface by forwarding its
|
||||
* methods to the remote MBean server.
|
||||
*
|
||||
* @exception IOException if a valid
|
||||
* <code>MBeanServerConnection</code> cannot be created, for
|
||||
* instance because the connection to the remote MBean server has
|
||||
* not yet been established (with the {@link #connect(Map)
|
||||
* connect} method), or it has been closed, or it has broken.
|
||||
*/
|
||||
public MBeanServerConnection getMBeanServerConnection()
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* <p>Returns an <code>MBeanServerConnection</code> object representing
|
||||
* a remote MBean server on which operations are performed on behalf of
|
||||
* the supplied delegation subject. For a given <code>JMXConnector</code>
|
||||
* and <code>Subject</code>, two successful calls to this method will
|
||||
* usually return the same <code>MBeanServerConnection</code> object,
|
||||
* though this is not required.</p>
|
||||
*
|
||||
* <p>For each method in the returned
|
||||
* <code>MBeanServerConnection</code>, calling the method causes
|
||||
* the corresponding method to be called in the remote MBean
|
||||
* server on behalf of the given delegation subject instead of the
|
||||
* authenticated subject. The value returned by the MBean server
|
||||
* method is the value returned to the client. If the MBean server
|
||||
* method produces an <code>Exception</code>, the same
|
||||
* <code>Exception</code> is seen by the client. If the MBean
|
||||
* server method, or the attempt to call it, produces an
|
||||
* <code>Error</code>, the <code>Error</code> is wrapped in a
|
||||
* {@link JMXServerErrorException}, which is seen by the
|
||||
* client.</p>
|
||||
*
|
||||
* @param delegationSubject the <code>Subject</code> on behalf of
|
||||
* which requests will be performed. Can be null, in which case
|
||||
* requests will be performed on behalf of the authenticated
|
||||
* Subject, if any.
|
||||
*
|
||||
* @return an object that implements the <code>MBeanServerConnection</code>
|
||||
* interface by forwarding its methods to the remote MBean server on behalf
|
||||
* of a given delegation subject.
|
||||
*
|
||||
* @exception IOException if a valid <code>MBeanServerConnection</code>
|
||||
* cannot be created, for instance because the connection to the remote
|
||||
* MBean server has not yet been established (with the {@link #connect(Map)
|
||||
* connect} method), or it has been closed, or it has broken.
|
||||
*/
|
||||
public MBeanServerConnection getMBeanServerConnection(
|
||||
Subject delegationSubject)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* <p>Closes the client connection to its server. Any ongoing or new
|
||||
* request using the MBeanServerConnection returned by {@link
|
||||
* #getMBeanServerConnection()} will get an
|
||||
* <code>IOException</code>.</p>
|
||||
*
|
||||
* <p>If <code>close</code> has already been called successfully
|
||||
* on this object, calling it again has no effect. If
|
||||
* <code>close</code> has never been called, or if it was called
|
||||
* but produced an exception, an attempt will be made to close the
|
||||
* connection. This attempt can succeed, in which case
|
||||
* <code>close</code> will return normally, or it can generate an
|
||||
* exception.</p>
|
||||
*
|
||||
* <p>Closing a connection is a potentially slow operation. For
|
||||
* example, if the server has crashed, the close operation might
|
||||
* have to wait for a network protocol timeout. Callers that do
|
||||
* not want to block in a close operation should do it in a
|
||||
* separate thread.</p>
|
||||
*
|
||||
* @exception IOException if the connection cannot be closed
|
||||
* cleanly. If this exception is thrown, it is not known whether
|
||||
* the server end of the connection has been cleanly closed.
|
||||
*/
|
||||
public void close() throws IOException;
|
||||
|
||||
/**
|
||||
* <p>Adds a listener to be informed of changes in connection
|
||||
* status. The listener will receive notifications of type {@link
|
||||
* JMXConnectionNotification}. An implementation can send other
|
||||
* types of notifications too.</p>
|
||||
*
|
||||
* <p>Any number of listeners can be added with this method. The
|
||||
* same listener can be added more than once with the same or
|
||||
* different values for the filter and handback. There is no
|
||||
* special treatment of a duplicate entry. For example, if a
|
||||
* listener is registered twice with no filter, then its
|
||||
* <code>handleNotification</code> method will be called twice for
|
||||
* each notification.</p>
|
||||
*
|
||||
* @param listener a listener to receive connection status
|
||||
* notifications.
|
||||
* @param filter a filter to select which notifications are to be
|
||||
* delivered to the listener, or null if all notifications are to
|
||||
* be delivered.
|
||||
* @param handback an object to be given to the listener along
|
||||
* with each notification. Can be null.
|
||||
*
|
||||
* @exception NullPointerException if <code>listener</code> is
|
||||
* null.
|
||||
*
|
||||
* @see #removeConnectionNotificationListener
|
||||
* @see javax.management.NotificationBroadcaster#addNotificationListener
|
||||
*/
|
||||
public void
|
||||
addConnectionNotificationListener(NotificationListener listener,
|
||||
NotificationFilter filter,
|
||||
Object handback);
|
||||
|
||||
/**
|
||||
* <p>Removes a listener from the list to be informed of changes
|
||||
* in status. The listener must previously have been added. If
|
||||
* there is more than one matching listener, all are removed.</p>
|
||||
*
|
||||
* @param listener a listener to receive connection status
|
||||
* notifications.
|
||||
*
|
||||
* @exception NullPointerException if <code>listener</code> is
|
||||
* null.
|
||||
*
|
||||
* @exception ListenerNotFoundException if the listener is not
|
||||
* registered with this <code>JMXConnector</code>.
|
||||
*
|
||||
* @see #removeConnectionNotificationListener(NotificationListener,
|
||||
* NotificationFilter, Object)
|
||||
* @see #addConnectionNotificationListener
|
||||
* @see javax.management.NotificationEmitter#removeNotificationListener
|
||||
*/
|
||||
public void
|
||||
removeConnectionNotificationListener(NotificationListener listener)
|
||||
throws ListenerNotFoundException;
|
||||
|
||||
/**
|
||||
* <p>Removes a listener from the list to be informed of changes
|
||||
* in status. The listener must previously have been added with
|
||||
* the same three parameters. If there is more than one matching
|
||||
* listener, only one is removed.</p>
|
||||
*
|
||||
* @param l a listener to receive connection status notifications.
|
||||
* @param f a filter to select which notifications are to be
|
||||
* delivered to the listener. Can be null.
|
||||
* @param handback an object to be given to the listener along
|
||||
* with each notification. Can be null.
|
||||
*
|
||||
* @exception ListenerNotFoundException if the listener is not
|
||||
* registered with this <code>JMXConnector</code>, or is not
|
||||
* registered with the given filter and handback.
|
||||
*
|
||||
* @see #removeConnectionNotificationListener(NotificationListener)
|
||||
* @see #addConnectionNotificationListener
|
||||
* @see javax.management.NotificationEmitter#removeNotificationListener
|
||||
*/
|
||||
public void removeConnectionNotificationListener(NotificationListener l,
|
||||
NotificationFilter f,
|
||||
Object handback)
|
||||
throws ListenerNotFoundException;
|
||||
|
||||
/**
|
||||
* <p>Gets this connection's ID from the connector server. For a
|
||||
* given connector server, every connection will have a unique id
|
||||
* which does not change during the lifetime of the
|
||||
* connection.</p>
|
||||
*
|
||||
* @return the unique ID of this connection. This is the same as
|
||||
* the ID that the connector server includes in its {@link
|
||||
* JMXConnectionNotification}s. The {@link
|
||||
* javax.management.remote package description} describes the
|
||||
* conventions for connection IDs.
|
||||
*
|
||||
* @exception IOException if the connection ID cannot be obtained,
|
||||
* for instance because the connection is closed or broken.
|
||||
*/
|
||||
public String getConnectionId() throws IOException;
|
||||
}
|
||||
574
jdkSrc/jdk8/javax/management/remote/JMXConnectorFactory.java
Normal file
574
jdkSrc/jdk8/javax/management/remote/JMXConnectorFactory.java
Normal file
@@ -0,0 +1,574 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
import com.sun.jmx.mbeanserver.Util;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Iterator;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.StringTokenizer;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import com.sun.jmx.remote.util.ClassLogger;
|
||||
import com.sun.jmx.remote.util.EnvHelp;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
|
||||
|
||||
/**
|
||||
* <p>Factory to create JMX API connector clients. There
|
||||
* are no instances of this class.</p>
|
||||
*
|
||||
* <p>Connections are usually made using the {@link
|
||||
* #connect(JMXServiceURL) connect} method of this class. More
|
||||
* advanced applications can separate the creation of the connector
|
||||
* client, using {@link #newJMXConnector(JMXServiceURL, Map)
|
||||
* newJMXConnector} and the establishment of the connection itself, using
|
||||
* {@link JMXConnector#connect(Map)}.</p>
|
||||
*
|
||||
* <p>Each client is created by an instance of {@link
|
||||
* JMXConnectorProvider}. This instance is found as follows. Suppose
|
||||
* the given {@link JMXServiceURL} looks like
|
||||
* <code>"service:jmx:<em>protocol</em>:<em>remainder</em>"</code>.
|
||||
* Then the factory will attempt to find the appropriate {@link
|
||||
* JMXConnectorProvider} for <code><em>protocol</em></code>. Each
|
||||
* occurrence of the character <code>+</code> or <code>-</code> in
|
||||
* <code><em>protocol</em></code> is replaced by <code>.</code> or
|
||||
* <code>_</code>, respectively.</p>
|
||||
*
|
||||
* <p>A <em>provider package list</em> is searched for as follows:</p>
|
||||
*
|
||||
* <ol>
|
||||
*
|
||||
* <li>If the <code>environment</code> parameter to {@link
|
||||
* #newJMXConnector(JMXServiceURL, Map) newJMXConnector} contains the
|
||||
* key <code>jmx.remote.protocol.provider.pkgs</code> then the
|
||||
* associated value is the provider package list.
|
||||
*
|
||||
* <li>Otherwise, if the system property
|
||||
* <code>jmx.remote.protocol.provider.pkgs</code> exists, then its value
|
||||
* is the provider package list.
|
||||
*
|
||||
* <li>Otherwise, there is no provider package list.
|
||||
*
|
||||
* </ol>
|
||||
*
|
||||
* <p>The provider package list is a string that is interpreted as a
|
||||
* list of non-empty Java package names separated by vertical bars
|
||||
* (<code>|</code>). If the string is empty, then so is the provider
|
||||
* package list. If the provider package list is not a String, or if
|
||||
* it contains an element that is an empty string, a {@link
|
||||
* JMXProviderException} is thrown.</p>
|
||||
*
|
||||
* <p>If the provider package list exists and is not empty, then for
|
||||
* each element <code><em>pkg</em></code> of the list, the factory
|
||||
* will attempt to load the class
|
||||
*
|
||||
* <blockquote>
|
||||
* <code><em>pkg</em>.<em>protocol</em>.ClientProvider</code>
|
||||
* </blockquote>
|
||||
|
||||
* <p>If the <code>environment</code> parameter to {@link
|
||||
* #newJMXConnector(JMXServiceURL, Map) newJMXConnector} contains the
|
||||
* key <code>jmx.remote.protocol.provider.class.loader</code> then the
|
||||
* associated value is the class loader to use to load the provider.
|
||||
* If the associated value is not an instance of {@link
|
||||
* java.lang.ClassLoader}, an {@link
|
||||
* java.lang.IllegalArgumentException} is thrown.</p>
|
||||
*
|
||||
* <p>If the <code>jmx.remote.protocol.provider.class.loader</code>
|
||||
* key is not present in the <code>environment</code> parameter, the
|
||||
* calling thread's context class loader is used.</p>
|
||||
*
|
||||
* <p>If the attempt to load this class produces a {@link
|
||||
* ClassNotFoundException}, the search for a handler continues with
|
||||
* the next element of the list.</p>
|
||||
*
|
||||
* <p>Otherwise, a problem with the provider found is signalled by a
|
||||
* {@link JMXProviderException} whose {@link
|
||||
* JMXProviderException#getCause() <em>cause</em>} indicates the underlying
|
||||
* exception, as follows:</p>
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li>if the attempt to load the class produces an exception other
|
||||
* than <code>ClassNotFoundException</code>, that is the
|
||||
* <em>cause</em>;
|
||||
*
|
||||
* <li>if {@link Class#newInstance()} for the class produces an
|
||||
* exception, that is the <em>cause</em>.
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <p>If no provider is found by the above steps, including the
|
||||
* default case where there is no provider package list, then the
|
||||
* implementation will use its own provider for
|
||||
* <code><em>protocol</em></code>, or it will throw a
|
||||
* <code>MalformedURLException</code> if there is none. An
|
||||
* implementation may choose to find providers by other means. For
|
||||
* example, it may support the <a
|
||||
* href="{@docRoot}/../technotes/guides/jar/jar.html#Service Provider">
|
||||
* JAR conventions for service providers</a>, where the service
|
||||
* interface is <code>JMXConnectorProvider</code>.</p>
|
||||
*
|
||||
* <p>Every implementation must support the RMI connector protocol with
|
||||
* the default RMI transport, specified with string <code>rmi</code>.
|
||||
* An implementation may optionally support the RMI connector protocol
|
||||
* with the RMI/IIOP transport, specified with the string
|
||||
* <code>iiop</code>.</p>
|
||||
*
|
||||
* <p>Once a provider is found, the result of the
|
||||
* <code>newJMXConnector</code> method is the result of calling {@link
|
||||
* JMXConnectorProvider#newJMXConnector(JMXServiceURL,Map) newJMXConnector}
|
||||
* on the provider.</p>
|
||||
*
|
||||
* <p>The <code>Map</code> parameter passed to the
|
||||
* <code>JMXConnectorProvider</code> is a new read-only
|
||||
* <code>Map</code> that contains all the entries that were in the
|
||||
* <code>environment</code> parameter to {@link
|
||||
* #newJMXConnector(JMXServiceURL,Map)
|
||||
* JMXConnectorFactory.newJMXConnector}, if there was one.
|
||||
* Additionally, if the
|
||||
* <code>jmx.remote.protocol.provider.class.loader</code> key is not
|
||||
* present in the <code>environment</code> parameter, it is added to
|
||||
* the new read-only <code>Map</code>. The associated value is the
|
||||
* calling thread's context class loader.</p>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class JMXConnectorFactory {
|
||||
|
||||
/**
|
||||
* <p>Name of the attribute that specifies the default class
|
||||
* loader. This class loader is used to deserialize return values and
|
||||
* exceptions from remote <code>MBeanServerConnection</code>
|
||||
* calls. The value associated with this attribute is an instance
|
||||
* of {@link ClassLoader}.</p>
|
||||
*/
|
||||
public static final String DEFAULT_CLASS_LOADER =
|
||||
"jmx.remote.default.class.loader";
|
||||
|
||||
/**
|
||||
* <p>Name of the attribute that specifies the provider packages
|
||||
* that are consulted when looking for the handler for a protocol.
|
||||
* The value associated with this attribute is a string with
|
||||
* package names separated by vertical bars (<code>|</code>).</p>
|
||||
*/
|
||||
public static final String PROTOCOL_PROVIDER_PACKAGES =
|
||||
"jmx.remote.protocol.provider.pkgs";
|
||||
|
||||
/**
|
||||
* <p>Name of the attribute that specifies the class
|
||||
* loader for loading protocol providers.
|
||||
* The value associated with this attribute is an instance
|
||||
* of {@link ClassLoader}.</p>
|
||||
*/
|
||||
public static final String PROTOCOL_PROVIDER_CLASS_LOADER =
|
||||
"jmx.remote.protocol.provider.class.loader";
|
||||
|
||||
private static final String PROTOCOL_PROVIDER_DEFAULT_PACKAGE =
|
||||
"com.sun.jmx.remote.protocol";
|
||||
|
||||
private static final ClassLogger logger =
|
||||
new ClassLogger("javax.management.remote.misc", "JMXConnectorFactory");
|
||||
|
||||
/** There are no instances of this class. */
|
||||
private JMXConnectorFactory() {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a connection to the connector server at the given
|
||||
* address.</p>
|
||||
*
|
||||
* <p>This method is equivalent to {@link
|
||||
* #connect(JMXServiceURL,Map) connect(serviceURL, null)}.</p>
|
||||
*
|
||||
* @param serviceURL the address of the connector server to
|
||||
* connect to.
|
||||
*
|
||||
* @return a <code>JMXConnector</code> whose {@link
|
||||
* JMXConnector#connect connect} method has been called.
|
||||
*
|
||||
* @exception NullPointerException if <code>serviceURL</code> is null.
|
||||
*
|
||||
* @exception IOException if the connector client or the
|
||||
* connection cannot be made because of a communication problem.
|
||||
*
|
||||
* @exception SecurityException if the connection cannot be made
|
||||
* for security reasons.
|
||||
*/
|
||||
public static JMXConnector connect(JMXServiceURL serviceURL)
|
||||
throws IOException {
|
||||
return connect(serviceURL, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a connection to the connector server at the given
|
||||
* address.</p>
|
||||
*
|
||||
* <p>This method is equivalent to:</p>
|
||||
*
|
||||
* <pre>
|
||||
* JMXConnector conn = JMXConnectorFactory.newJMXConnector(serviceURL,
|
||||
* environment);
|
||||
* conn.connect(environment);
|
||||
* </pre>
|
||||
*
|
||||
* @param serviceURL the address of the connector server to connect to.
|
||||
*
|
||||
* @param environment a set of attributes to determine how the
|
||||
* connection is made. This parameter can be null. Keys in this
|
||||
* map must be Strings. The appropriate type of each associated
|
||||
* value depends on the attribute. The contents of
|
||||
* <code>environment</code> are not changed by this call.
|
||||
*
|
||||
* @return a <code>JMXConnector</code> representing the newly-made
|
||||
* connection. Each successful call to this method produces a
|
||||
* different object.
|
||||
*
|
||||
* @exception NullPointerException if <code>serviceURL</code> is null.
|
||||
*
|
||||
* @exception IOException if the connector client or the
|
||||
* connection cannot be made because of a communication problem.
|
||||
*
|
||||
* @exception SecurityException if the connection cannot be made
|
||||
* for security reasons.
|
||||
*/
|
||||
public static JMXConnector connect(JMXServiceURL serviceURL,
|
||||
Map<String,?> environment)
|
||||
throws IOException {
|
||||
if (serviceURL == null)
|
||||
throw new NullPointerException("Null JMXServiceURL");
|
||||
JMXConnector conn = newJMXConnector(serviceURL, environment);
|
||||
conn.connect(environment);
|
||||
return conn;
|
||||
}
|
||||
|
||||
private static <K,V> Map<K,V> newHashMap() {
|
||||
return new HashMap<K,V>();
|
||||
}
|
||||
|
||||
private static <K> Map<K,Object> newHashMap(Map<K,?> map) {
|
||||
return new HashMap<K,Object>(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a connector client for the connector server at the
|
||||
* given address. The resultant client is not connected until its
|
||||
* {@link JMXConnector#connect(Map) connect} method is called.</p>
|
||||
*
|
||||
* @param serviceURL the address of the connector server to connect to.
|
||||
*
|
||||
* @param environment a set of attributes to determine how the
|
||||
* connection is made. This parameter can be null. Keys in this
|
||||
* map must be Strings. The appropriate type of each associated
|
||||
* value depends on the attribute. The contents of
|
||||
* <code>environment</code> are not changed by this call.
|
||||
*
|
||||
* @return a <code>JMXConnector</code> representing the new
|
||||
* connector client. Each successful call to this method produces
|
||||
* a different object.
|
||||
*
|
||||
* @exception NullPointerException if <code>serviceURL</code> is null.
|
||||
*
|
||||
* @exception IOException if the connector client cannot be made
|
||||
* because of a communication problem.
|
||||
*
|
||||
* @exception MalformedURLException if there is no provider for the
|
||||
* protocol in <code>serviceURL</code>.
|
||||
*
|
||||
* @exception JMXProviderException if there is a provider for the
|
||||
* protocol in <code>serviceURL</code> but it cannot be used for
|
||||
* some reason.
|
||||
*/
|
||||
public static JMXConnector newJMXConnector(JMXServiceURL serviceURL,
|
||||
Map<String,?> environment)
|
||||
throws IOException {
|
||||
|
||||
final Map<String,Object> envcopy;
|
||||
if (environment == null)
|
||||
envcopy = newHashMap();
|
||||
else {
|
||||
EnvHelp.checkAttributes(environment);
|
||||
envcopy = newHashMap(environment);
|
||||
}
|
||||
|
||||
final ClassLoader loader = resolveClassLoader(envcopy);
|
||||
final Class<JMXConnectorProvider> targetInterface =
|
||||
JMXConnectorProvider.class;
|
||||
final String protocol = serviceURL.getProtocol();
|
||||
final String providerClassName = "ClientProvider";
|
||||
final JMXServiceURL providerURL = serviceURL;
|
||||
|
||||
JMXConnectorProvider provider = getProvider(providerURL, envcopy,
|
||||
providerClassName,
|
||||
targetInterface,
|
||||
loader);
|
||||
|
||||
IOException exception = null;
|
||||
if (provider == null) {
|
||||
// Loader is null when context class loader is set to null
|
||||
// and no loader has been provided in map.
|
||||
// com.sun.jmx.remote.util.Service class extracted from j2se
|
||||
// provider search algorithm doesn't handle well null classloader.
|
||||
if (loader != null) {
|
||||
try {
|
||||
JMXConnector connection =
|
||||
getConnectorAsService(loader, providerURL, envcopy);
|
||||
if (connection != null)
|
||||
return connection;
|
||||
} catch (JMXProviderException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
provider = getProvider(protocol, PROTOCOL_PROVIDER_DEFAULT_PACKAGE,
|
||||
JMXConnectorFactory.class.getClassLoader(),
|
||||
providerClassName, targetInterface);
|
||||
}
|
||||
|
||||
if (provider == null) {
|
||||
MalformedURLException e =
|
||||
new MalformedURLException("Unsupported protocol: " + protocol);
|
||||
if (exception == null) {
|
||||
throw e;
|
||||
} else {
|
||||
throw EnvHelp.initCause(e, exception);
|
||||
}
|
||||
}
|
||||
|
||||
final Map<String,Object> fixedenv =
|
||||
Collections.unmodifiableMap(envcopy);
|
||||
|
||||
return provider.newJMXConnector(serviceURL, fixedenv);
|
||||
}
|
||||
|
||||
private static String resolvePkgs(Map<String, ?> env)
|
||||
throws JMXProviderException {
|
||||
|
||||
Object pkgsObject = null;
|
||||
|
||||
if (env != null)
|
||||
pkgsObject = env.get(PROTOCOL_PROVIDER_PACKAGES);
|
||||
|
||||
if (pkgsObject == null)
|
||||
pkgsObject =
|
||||
AccessController.doPrivileged(new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return System.getProperty(PROTOCOL_PROVIDER_PACKAGES);
|
||||
}
|
||||
});
|
||||
|
||||
if (pkgsObject == null)
|
||||
return null;
|
||||
|
||||
if (!(pkgsObject instanceof String)) {
|
||||
final String msg = "Value of " + PROTOCOL_PROVIDER_PACKAGES +
|
||||
" parameter is not a String: " +
|
||||
pkgsObject.getClass().getName();
|
||||
throw new JMXProviderException(msg);
|
||||
}
|
||||
|
||||
final String pkgs = (String) pkgsObject;
|
||||
if (pkgs.trim().equals(""))
|
||||
return null;
|
||||
|
||||
// pkgs may not contain an empty element
|
||||
if (pkgs.startsWith("|") || pkgs.endsWith("|") ||
|
||||
pkgs.indexOf("||") >= 0) {
|
||||
final String msg = "Value of " + PROTOCOL_PROVIDER_PACKAGES +
|
||||
" contains an empty element: " + pkgs;
|
||||
throw new JMXProviderException(msg);
|
||||
}
|
||||
|
||||
return pkgs;
|
||||
}
|
||||
|
||||
static <T> T getProvider(JMXServiceURL serviceURL,
|
||||
final Map<String, Object> environment,
|
||||
String providerClassName,
|
||||
Class<T> targetInterface,
|
||||
final ClassLoader loader)
|
||||
throws IOException {
|
||||
|
||||
final String protocol = serviceURL.getProtocol();
|
||||
|
||||
final String pkgs = resolvePkgs(environment);
|
||||
|
||||
T instance = null;
|
||||
|
||||
if (pkgs != null) {
|
||||
instance =
|
||||
getProvider(protocol, pkgs, loader, providerClassName,
|
||||
targetInterface);
|
||||
|
||||
if (instance != null) {
|
||||
boolean needsWrap = (loader != instance.getClass().getClassLoader());
|
||||
environment.put(PROTOCOL_PROVIDER_CLASS_LOADER, needsWrap ? wrap(loader) : loader);
|
||||
}
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
static <T> Iterator<T> getProviderIterator(final Class<T> providerClass,
|
||||
final ClassLoader loader) {
|
||||
ServiceLoader<T> serviceLoader =
|
||||
ServiceLoader.load(providerClass, loader);
|
||||
return serviceLoader.iterator();
|
||||
}
|
||||
|
||||
private static ClassLoader wrap(final ClassLoader parent) {
|
||||
return parent != null ? AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
|
||||
@Override
|
||||
public ClassLoader run() {
|
||||
return new ClassLoader(parent) {
|
||||
@Override
|
||||
protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
|
||||
ReflectUtil.checkPackageAccess(name);
|
||||
return super.loadClass(name, resolve);
|
||||
}
|
||||
};
|
||||
}
|
||||
}) : null;
|
||||
}
|
||||
|
||||
private static JMXConnector getConnectorAsService(ClassLoader loader,
|
||||
JMXServiceURL url,
|
||||
Map<String, ?> map)
|
||||
throws IOException {
|
||||
|
||||
Iterator<JMXConnectorProvider> providers =
|
||||
getProviderIterator(JMXConnectorProvider.class, loader);
|
||||
JMXConnector connection;
|
||||
IOException exception = null;
|
||||
while (providers.hasNext()) {
|
||||
JMXConnectorProvider provider = providers.next();
|
||||
try {
|
||||
connection = provider.newJMXConnector(url, map);
|
||||
return connection;
|
||||
} catch (JMXProviderException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
if (logger.traceOn())
|
||||
logger.trace("getConnectorAsService",
|
||||
"URL[" + url +
|
||||
"] Service provider exception: " + e);
|
||||
if (!(e instanceof MalformedURLException)) {
|
||||
if (exception == null) {
|
||||
if (e instanceof IOException) {
|
||||
exception = (IOException) e;
|
||||
} else {
|
||||
exception = EnvHelp.initCause(
|
||||
new IOException(e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (exception == null)
|
||||
return null;
|
||||
else
|
||||
throw exception;
|
||||
}
|
||||
|
||||
static <T> T getProvider(String protocol,
|
||||
String pkgs,
|
||||
ClassLoader loader,
|
||||
String providerClassName,
|
||||
Class<T> targetInterface)
|
||||
throws IOException {
|
||||
|
||||
StringTokenizer tokenizer = new StringTokenizer(pkgs, "|");
|
||||
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
String pkg = tokenizer.nextToken();
|
||||
String className = (pkg + "." + protocol2package(protocol) +
|
||||
"." + providerClassName);
|
||||
Class<?> providerClass;
|
||||
try {
|
||||
providerClass = Class.forName(className, true, loader);
|
||||
} catch (ClassNotFoundException e) {
|
||||
//Add trace.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!targetInterface.isAssignableFrom(providerClass)) {
|
||||
final String msg =
|
||||
"Provider class does not implement " +
|
||||
targetInterface.getName() + ": " +
|
||||
providerClass.getName();
|
||||
throw new JMXProviderException(msg);
|
||||
}
|
||||
|
||||
// We have just proved that this cast is correct
|
||||
Class<? extends T> providerClassT = Util.cast(providerClass);
|
||||
try {
|
||||
return providerClassT.newInstance();
|
||||
} catch (Exception e) {
|
||||
final String msg =
|
||||
"Exception when instantiating provider [" + className +
|
||||
"]";
|
||||
throw new JMXProviderException(msg, e);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
static ClassLoader resolveClassLoader(Map<String, ?> environment) {
|
||||
ClassLoader loader = null;
|
||||
|
||||
if (environment != null) {
|
||||
try {
|
||||
loader = (ClassLoader)
|
||||
environment.get(PROTOCOL_PROVIDER_CLASS_LOADER);
|
||||
} catch (ClassCastException e) {
|
||||
final String msg =
|
||||
"The ClassLoader supplied in the environment map using " +
|
||||
"the " + PROTOCOL_PROVIDER_CLASS_LOADER +
|
||||
" attribute is not an instance of java.lang.ClassLoader";
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (loader == null) {
|
||||
loader = Thread.currentThread().getContextClassLoader();
|
||||
}
|
||||
|
||||
return loader;
|
||||
}
|
||||
|
||||
private static String protocol2package(String protocol) {
|
||||
return protocol.replace('+', '.').replace('-', '_');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>A provider for creating JMX API connector clients using a given
|
||||
* protocol. Instances of this interface are created by {@link
|
||||
* JMXConnectorFactory} as part of its {@link
|
||||
* JMXConnectorFactory#newJMXConnector(JMXServiceURL, Map)
|
||||
* newJMXConnector} method.</p>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface JMXConnectorProvider {
|
||||
/**
|
||||
* <p>Creates a new connector client that is ready to connect
|
||||
* to the connector server at the given address. Each successful
|
||||
* call to this method produces a different
|
||||
* <code>JMXConnector</code> object.</p>
|
||||
*
|
||||
* @param serviceURL the address of the connector server to connect to.
|
||||
*
|
||||
* @param environment a read-only Map containing named attributes
|
||||
* to determine how the connection is made. Keys in this map must
|
||||
* be Strings. The appropriate type of each associated value
|
||||
* depends on the attribute.
|
||||
*
|
||||
* @return a <code>JMXConnector</code> representing the new
|
||||
* connector client. Each successful call to this method produces
|
||||
* a different object.
|
||||
*
|
||||
* @exception NullPointerException if <code>serviceURL</code> or
|
||||
* <code>environment</code> is null.
|
||||
*
|
||||
* @exception IOException It is recommended for a provider
|
||||
* implementation to throw {@code MalformedURLException} if the
|
||||
* protocol in the {@code serviceURL} is not recognized by this
|
||||
* provider, {@code JMXProviderException} if this is a provider
|
||||
* for the protocol in {@code serviceURL} but it cannot be used
|
||||
* for some reason or any other {@code IOException} if the
|
||||
* connection cannot be made because of a communication problem.
|
||||
*/
|
||||
public JMXConnector newJMXConnector(JMXServiceURL serviceURL,
|
||||
Map<String,?> environment)
|
||||
throws IOException;
|
||||
}
|
||||
414
jdkSrc/jdk8/javax/management/remote/JMXConnectorServer.java
Normal file
414
jdkSrc/jdk8/javax/management/remote/JMXConnectorServer.java
Normal file
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2008, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.management.MBeanNotificationInfo;
|
||||
import javax.management.MBeanRegistration;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.Notification;
|
||||
import javax.management.NotificationBroadcasterSupport;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
/**
|
||||
* <p>Superclass of every connector server. A connector server is
|
||||
* attached to an MBean server. It listens for client connection
|
||||
* requests and creates a connection for each one.</p>
|
||||
*
|
||||
* <p>A connector server is associated with an MBean server either by
|
||||
* registering it in that MBean server, or by passing the MBean server
|
||||
* to its constructor.</p>
|
||||
*
|
||||
* <p>A connector server is inactive when created. It only starts
|
||||
* listening for client connections when the {@link #start() start}
|
||||
* method is called. A connector server stops listening for client
|
||||
* connections when the {@link #stop() stop} method is called or when
|
||||
* the connector server is unregistered from its MBean server.</p>
|
||||
*
|
||||
* <p>Stopping a connector server does not unregister it from its
|
||||
* MBean server. A connector server once stopped cannot be
|
||||
* restarted.</p>
|
||||
*
|
||||
* <p>Each time a client connection is made or broken, a notification
|
||||
* of class {@link JMXConnectionNotification} is emitted.</p>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public abstract class JMXConnectorServer
|
||||
extends NotificationBroadcasterSupport
|
||||
implements JMXConnectorServerMBean, MBeanRegistration, JMXAddressable {
|
||||
|
||||
/**
|
||||
* <p>Name of the attribute that specifies the authenticator for a
|
||||
* connector server. The value associated with this attribute, if
|
||||
* any, must be an object that implements the interface {@link
|
||||
* JMXAuthenticator}.</p>
|
||||
*/
|
||||
public static final String AUTHENTICATOR =
|
||||
"jmx.remote.authenticator";
|
||||
|
||||
/**
|
||||
* <p>Constructs a connector server that will be registered as an
|
||||
* MBean in the MBean server it is attached to. This constructor
|
||||
* is typically called by one of the <code>createMBean</code>
|
||||
* methods when creating, within an MBean server, a connector
|
||||
* server that makes it available remotely.</p>
|
||||
*/
|
||||
public JMXConnectorServer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Constructs a connector server that is attached to the given
|
||||
* MBean server. A connector server that is created in this way
|
||||
* can be registered in a different MBean server, or not registered
|
||||
* in any MBean server.</p>
|
||||
*
|
||||
* @param mbeanServer the MBean server that this connector server
|
||||
* is attached to. Null if this connector server will be attached
|
||||
* to an MBean server by being registered in it.
|
||||
*/
|
||||
public JMXConnectorServer(MBeanServer mbeanServer) {
|
||||
this.mbeanServer = mbeanServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns the MBean server that this connector server is
|
||||
* attached to.</p>
|
||||
*
|
||||
* @return the MBean server that this connector server is attached
|
||||
* to, or null if it is not yet attached to an MBean server.
|
||||
*/
|
||||
public synchronized MBeanServer getMBeanServer() {
|
||||
return mbeanServer;
|
||||
}
|
||||
|
||||
public synchronized void setMBeanServerForwarder(MBeanServerForwarder mbsf)
|
||||
{
|
||||
if (mbsf == null)
|
||||
throw new IllegalArgumentException("Invalid null argument: mbsf");
|
||||
|
||||
if (mbeanServer != null) mbsf.setMBeanServer(mbeanServer);
|
||||
mbeanServer = mbsf;
|
||||
}
|
||||
|
||||
public String[] getConnectionIds() {
|
||||
synchronized (connectionIds) {
|
||||
return connectionIds.toArray(new String[connectionIds.size()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns a client stub for this connector server. A client
|
||||
* stub is a serializable object whose {@link
|
||||
* JMXConnector#connect(Map) connect} method can be used to make
|
||||
* one new connection to this connector server.</p>
|
||||
*
|
||||
* <p>A given connector need not support the generation of client
|
||||
* stubs. However, the connectors specified by the JMX Remote API do
|
||||
* (JMXMP Connector and RMI Connector).</p>
|
||||
*
|
||||
* <p>The default implementation of this method uses {@link
|
||||
* #getAddress} and {@link JMXConnectorFactory} to generate the
|
||||
* stub, with code equivalent to the following:</p>
|
||||
*
|
||||
* <pre>
|
||||
* JMXServiceURL addr = {@link #getAddress() getAddress()};
|
||||
* return {@link JMXConnectorFactory#newJMXConnector(JMXServiceURL, Map)
|
||||
* JMXConnectorFactory.newJMXConnector(addr, env)};
|
||||
* </pre>
|
||||
*
|
||||
* <p>A connector server for which this is inappropriate must
|
||||
* override this method so that it either implements the
|
||||
* appropriate logic or throws {@link
|
||||
* UnsupportedOperationException}.</p>
|
||||
*
|
||||
* @param env client connection parameters of the same sort that
|
||||
* could be provided to {@link JMXConnector#connect(Map)
|
||||
* JMXConnector.connect(Map)}. Can be null, which is equivalent
|
||||
* to an empty map.
|
||||
*
|
||||
* @return a client stub that can be used to make a new connection
|
||||
* to this connector server.
|
||||
*
|
||||
* @exception UnsupportedOperationException if this connector
|
||||
* server does not support the generation of client stubs.
|
||||
*
|
||||
* @exception IllegalStateException if the JMXConnectorServer is
|
||||
* not started (see {@link JMXConnectorServerMBean#isActive()}).
|
||||
*
|
||||
* @exception IOException if a communications problem means that a
|
||||
* stub cannot be created.
|
||||
**/
|
||||
public JMXConnector toJMXConnector(Map<String,?> env)
|
||||
throws IOException
|
||||
{
|
||||
if (!isActive()) throw new
|
||||
IllegalStateException("Connector is not active");
|
||||
JMXServiceURL addr = getAddress();
|
||||
return JMXConnectorFactory.newJMXConnector(addr, env);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns an array indicating the notifications that this MBean
|
||||
* sends. The implementation in <code>JMXConnectorServer</code>
|
||||
* returns an array with one element, indicating that it can emit
|
||||
* notifications of class {@link JMXConnectionNotification} with
|
||||
* the types defined in that class. A subclass that can emit other
|
||||
* notifications should return an array that contains this element
|
||||
* plus descriptions of the other notifications.</p>
|
||||
*
|
||||
* @return the array of possible notifications.
|
||||
*/
|
||||
@Override
|
||||
public MBeanNotificationInfo[] getNotificationInfo() {
|
||||
final String[] types = {
|
||||
JMXConnectionNotification.OPENED,
|
||||
JMXConnectionNotification.CLOSED,
|
||||
JMXConnectionNotification.FAILED,
|
||||
};
|
||||
final String className = JMXConnectionNotification.class.getName();
|
||||
final String description =
|
||||
"A client connection has been opened or closed";
|
||||
return new MBeanNotificationInfo[] {
|
||||
new MBeanNotificationInfo(types, className, description),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Called by a subclass when a new client connection is opened.
|
||||
* Adds <code>connectionId</code> to the list returned by {@link
|
||||
* #getConnectionIds()}, then emits a {@link
|
||||
* JMXConnectionNotification} with type {@link
|
||||
* JMXConnectionNotification#OPENED}.</p>
|
||||
*
|
||||
* @param connectionId the ID of the new connection. This must be
|
||||
* different from the ID of any connection previously opened by
|
||||
* this connector server.
|
||||
*
|
||||
* @param message the message for the emitted {@link
|
||||
* JMXConnectionNotification}. Can be null. See {@link
|
||||
* Notification#getMessage()}.
|
||||
*
|
||||
* @param userData the <code>userData</code> for the emitted
|
||||
* {@link JMXConnectionNotification}. Can be null. See {@link
|
||||
* Notification#getUserData()}.
|
||||
*
|
||||
* @exception NullPointerException if <code>connectionId</code> is
|
||||
* null.
|
||||
*/
|
||||
protected void connectionOpened(String connectionId,
|
||||
String message,
|
||||
Object userData) {
|
||||
|
||||
if (connectionId == null)
|
||||
throw new NullPointerException("Illegal null argument");
|
||||
|
||||
synchronized (connectionIds) {
|
||||
connectionIds.add(connectionId);
|
||||
}
|
||||
|
||||
sendNotification(JMXConnectionNotification.OPENED, connectionId,
|
||||
message, userData);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Called by a subclass when a client connection is closed
|
||||
* normally. Removes <code>connectionId</code> from the list returned
|
||||
* by {@link #getConnectionIds()}, then emits a {@link
|
||||
* JMXConnectionNotification} with type {@link
|
||||
* JMXConnectionNotification#CLOSED}.</p>
|
||||
*
|
||||
* @param connectionId the ID of the closed connection.
|
||||
*
|
||||
* @param message the message for the emitted {@link
|
||||
* JMXConnectionNotification}. Can be null. See {@link
|
||||
* Notification#getMessage()}.
|
||||
*
|
||||
* @param userData the <code>userData</code> for the emitted
|
||||
* {@link JMXConnectionNotification}. Can be null. See {@link
|
||||
* Notification#getUserData()}.
|
||||
*
|
||||
* @exception NullPointerException if <code>connectionId</code>
|
||||
* is null.
|
||||
*/
|
||||
protected void connectionClosed(String connectionId,
|
||||
String message,
|
||||
Object userData) {
|
||||
|
||||
if (connectionId == null)
|
||||
throw new NullPointerException("Illegal null argument");
|
||||
|
||||
synchronized (connectionIds) {
|
||||
connectionIds.remove(connectionId);
|
||||
}
|
||||
|
||||
sendNotification(JMXConnectionNotification.CLOSED, connectionId,
|
||||
message, userData);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Called by a subclass when a client connection fails.
|
||||
* Removes <code>connectionId</code> from the list returned by
|
||||
* {@link #getConnectionIds()}, then emits a {@link
|
||||
* JMXConnectionNotification} with type {@link
|
||||
* JMXConnectionNotification#FAILED}.</p>
|
||||
*
|
||||
* @param connectionId the ID of the failed connection.
|
||||
*
|
||||
* @param message the message for the emitted {@link
|
||||
* JMXConnectionNotification}. Can be null. See {@link
|
||||
* Notification#getMessage()}.
|
||||
*
|
||||
* @param userData the <code>userData</code> for the emitted
|
||||
* {@link JMXConnectionNotification}. Can be null. See {@link
|
||||
* Notification#getUserData()}.
|
||||
*
|
||||
* @exception NullPointerException if <code>connectionId</code> is
|
||||
* null.
|
||||
*/
|
||||
protected void connectionFailed(String connectionId,
|
||||
String message,
|
||||
Object userData) {
|
||||
|
||||
if (connectionId == null)
|
||||
throw new NullPointerException("Illegal null argument");
|
||||
|
||||
synchronized (connectionIds) {
|
||||
connectionIds.remove(connectionId);
|
||||
}
|
||||
|
||||
sendNotification(JMXConnectionNotification.FAILED, connectionId,
|
||||
message, userData);
|
||||
}
|
||||
|
||||
private void sendNotification(String type, String connectionId,
|
||||
String message, Object userData) {
|
||||
Notification notif =
|
||||
new JMXConnectionNotification(type,
|
||||
getNotificationSource(),
|
||||
connectionId,
|
||||
nextSequenceNumber(),
|
||||
message,
|
||||
userData);
|
||||
sendNotification(notif);
|
||||
}
|
||||
|
||||
private synchronized Object getNotificationSource() {
|
||||
if (myName != null)
|
||||
return myName;
|
||||
else
|
||||
return this;
|
||||
}
|
||||
|
||||
private static long nextSequenceNumber() {
|
||||
synchronized (sequenceNumberLock) {
|
||||
return sequenceNumber++;
|
||||
}
|
||||
}
|
||||
|
||||
// implements MBeanRegistration
|
||||
/**
|
||||
* <p>Called by an MBean server when this connector server is
|
||||
* registered in that MBean server. This connector server becomes
|
||||
* attached to the MBean server and its {@link #getMBeanServer()}
|
||||
* method will return <code>mbs</code>.</p>
|
||||
*
|
||||
* <p>If this connector server is already attached to an MBean
|
||||
* server, this method has no effect. The MBean server it is
|
||||
* attached to is not necessarily the one it is being registered
|
||||
* in.</p>
|
||||
*
|
||||
* @param mbs the MBean server in which this connection server is
|
||||
* being registered.
|
||||
*
|
||||
* @param name The object name of the MBean.
|
||||
*
|
||||
* @return The name under which the MBean is to be registered.
|
||||
*
|
||||
* @exception NullPointerException if <code>mbs</code> or
|
||||
* <code>name</code> is null.
|
||||
*/
|
||||
public synchronized ObjectName preRegister(MBeanServer mbs,
|
||||
ObjectName name) {
|
||||
if (mbs == null || name == null)
|
||||
throw new NullPointerException("Null MBeanServer or ObjectName");
|
||||
if (mbeanServer == null) {
|
||||
mbeanServer = mbs;
|
||||
myName = name;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public void postRegister(Boolean registrationDone) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Called by an MBean server when this connector server is
|
||||
* unregistered from that MBean server. If this connector server
|
||||
* was attached to that MBean server by being registered in it,
|
||||
* and if the connector server is still active,
|
||||
* then unregistering it will call the {@link #stop stop} method.
|
||||
* If the <code>stop</code> method throws an exception, the
|
||||
* unregistration attempt will fail. It is recommended to call
|
||||
* the <code>stop</code> method explicitly before unregistering
|
||||
* the MBean.</p>
|
||||
*
|
||||
* @exception IOException if thrown by the {@link #stop stop} method.
|
||||
*/
|
||||
public synchronized void preDeregister() throws Exception {
|
||||
if (myName != null && isActive()) {
|
||||
stop();
|
||||
myName = null; // just in case stop is buggy and doesn't stop
|
||||
}
|
||||
}
|
||||
|
||||
public void postDeregister() {
|
||||
myName = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The MBeanServer used by this server to execute a client request.
|
||||
*/
|
||||
private MBeanServer mbeanServer = null;
|
||||
|
||||
/**
|
||||
* The name used to registered this server in an MBeanServer.
|
||||
* It is null if the this server is not registered or has been unregistered.
|
||||
*/
|
||||
private ObjectName myName;
|
||||
|
||||
private final List<String> connectionIds = new ArrayList<String>();
|
||||
|
||||
private static final int[] sequenceNumberLock = new int[0];
|
||||
private static long sequenceNumber;
|
||||
}
|
||||
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2012, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
|
||||
import com.sun.jmx.remote.util.ClassLogger;
|
||||
import com.sun.jmx.remote.util.EnvHelp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
|
||||
/**
|
||||
* <p>Factory to create JMX API connector servers. There
|
||||
* are no instances of this class.</p>
|
||||
*
|
||||
* <p>Each connector server is created by an instance of {@link
|
||||
* JMXConnectorServerProvider}. This instance is found as follows. Suppose
|
||||
* the given {@link JMXServiceURL} looks like
|
||||
* <code>"service:jmx:<em>protocol</em>:<em>remainder</em>"</code>.
|
||||
* Then the factory will attempt to find the appropriate {@link
|
||||
* JMXConnectorServerProvider} for <code><em>protocol</em></code>. Each
|
||||
* occurrence of the character <code>+</code> or <code>-</code> in
|
||||
* <code><em>protocol</em></code> is replaced by <code>.</code> or
|
||||
* <code>_</code>, respectively.</p>
|
||||
*
|
||||
* <p>A <em>provider package list</em> is searched for as follows:</p>
|
||||
*
|
||||
* <ol>
|
||||
*
|
||||
* <li>If the <code>environment</code> parameter to {@link
|
||||
* #newJMXConnectorServer(JMXServiceURL,Map,MBeanServer)
|
||||
* newJMXConnectorServer} contains the key
|
||||
* <code>jmx.remote.protocol.provider.pkgs</code> then the associated
|
||||
* value is the provider package list.
|
||||
*
|
||||
* <li>Otherwise, if the system property
|
||||
* <code>jmx.remote.protocol.provider.pkgs</code> exists, then its value
|
||||
* is the provider package list.
|
||||
*
|
||||
* <li>Otherwise, there is no provider package list.
|
||||
*
|
||||
* </ol>
|
||||
*
|
||||
* <p>The provider package list is a string that is interpreted as a
|
||||
* list of non-empty Java package names separated by vertical bars
|
||||
* (<code>|</code>). If the string is empty, then so is the provider
|
||||
* package list. If the provider package list is not a String, or if
|
||||
* it contains an element that is an empty string, a {@link
|
||||
* JMXProviderException} is thrown.</p>
|
||||
*
|
||||
* <p>If the provider package list exists and is not empty, then for
|
||||
* each element <code><em>pkg</em></code> of the list, the factory
|
||||
* will attempt to load the class
|
||||
*
|
||||
* <blockquote>
|
||||
* <code><em>pkg</em>.<em>protocol</em>.ServerProvider</code>
|
||||
* </blockquote>
|
||||
|
||||
* <p>If the <code>environment</code> parameter to {@link
|
||||
* #newJMXConnectorServer(JMXServiceURL, Map, MBeanServer)
|
||||
* newJMXConnectorServer} contains the key
|
||||
* <code>jmx.remote.protocol.provider.class.loader</code> then the
|
||||
* associated value is the class loader to use to load the provider.
|
||||
* If the associated value is not an instance of {@link
|
||||
* java.lang.ClassLoader}, an {@link
|
||||
* java.lang.IllegalArgumentException} is thrown.</p>
|
||||
*
|
||||
* <p>If the <code>jmx.remote.protocol.provider.class.loader</code>
|
||||
* key is not present in the <code>environment</code> parameter, the
|
||||
* calling thread's context class loader is used.</p>
|
||||
*
|
||||
* <p>If the attempt to load this class produces a {@link
|
||||
* ClassNotFoundException}, the search for a handler continues with
|
||||
* the next element of the list.</p>
|
||||
*
|
||||
* <p>Otherwise, a problem with the provider found is signalled by a
|
||||
* {@link JMXProviderException} whose {@link
|
||||
* JMXProviderException#getCause() <em>cause</em>} indicates the
|
||||
* underlying exception, as follows:</p>
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li>if the attempt to load the class produces an exception other
|
||||
* than <code>ClassNotFoundException</code>, that is the
|
||||
* <em>cause</em>;
|
||||
*
|
||||
* <li>if {@link Class#newInstance()} for the class produces an
|
||||
* exception, that is the <em>cause</em>.
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <p>If no provider is found by the above steps, including the
|
||||
* default case where there is no provider package list, then the
|
||||
* implementation will use its own provider for
|
||||
* <code><em>protocol</em></code>, or it will throw a
|
||||
* <code>MalformedURLException</code> if there is none. An
|
||||
* implementation may choose to find providers by other means. For
|
||||
* example, it may support the <a
|
||||
* href="{@docRoot}/../technotes/guides/jar/jar.html#Service Provider">
|
||||
* JAR conventions for service providers</a>, where the service
|
||||
* interface is <code>JMXConnectorServerProvider</code>.</p>
|
||||
*
|
||||
* <p>Every implementation must support the RMI connector protocol with
|
||||
* the default RMI transport, specified with string <code>rmi</code>.
|
||||
* An implementation may optionally support the RMI connector protocol
|
||||
* with the RMI/IIOP transport, specified with the string
|
||||
* <code>iiop</code>.</p>
|
||||
*
|
||||
* <p>Once a provider is found, the result of the
|
||||
* <code>newJMXConnectorServer</code> method is the result of calling
|
||||
* {@link
|
||||
* JMXConnectorServerProvider#newJMXConnectorServer(JMXServiceURL,
|
||||
* Map, MBeanServer) newJMXConnectorServer} on the provider.</p>
|
||||
*
|
||||
* <p>The <code>Map</code> parameter passed to the
|
||||
* <code>JMXConnectorServerProvider</code> is a new read-only
|
||||
* <code>Map</code> that contains all the entries that were in the
|
||||
* <code>environment</code> parameter to {@link
|
||||
* #newJMXConnectorServer(JMXServiceURL,Map,MBeanServer)
|
||||
* JMXConnectorServerFactory.newJMXConnectorServer}, if there was one.
|
||||
* Additionally, if the
|
||||
* <code>jmx.remote.protocol.provider.class.loader</code> key is not
|
||||
* present in the <code>environment</code> parameter, it is added to
|
||||
* the new read-only <code>Map</code>. The associated value is the
|
||||
* calling thread's context class loader.</p>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class JMXConnectorServerFactory {
|
||||
|
||||
/**
|
||||
* <p>Name of the attribute that specifies the default class
|
||||
* loader. This class loader is used to deserialize objects in
|
||||
* requests received from the client, possibly after consulting an
|
||||
* MBean-specific class loader. The value associated with this
|
||||
* attribute is an instance of {@link ClassLoader}.</p>
|
||||
*/
|
||||
public static final String DEFAULT_CLASS_LOADER =
|
||||
JMXConnectorFactory.DEFAULT_CLASS_LOADER;
|
||||
|
||||
/**
|
||||
* <p>Name of the attribute that specifies the default class
|
||||
* loader MBean name. This class loader is used to deserialize objects in
|
||||
* requests received from the client, possibly after consulting an
|
||||
* MBean-specific class loader. The value associated with this
|
||||
* attribute is an instance of {@link javax.management.ObjectName
|
||||
* ObjectName}.</p>
|
||||
*/
|
||||
public static final String DEFAULT_CLASS_LOADER_NAME =
|
||||
"jmx.remote.default.class.loader.name";
|
||||
|
||||
/**
|
||||
* <p>Name of the attribute that specifies the provider packages
|
||||
* that are consulted when looking for the handler for a protocol.
|
||||
* The value associated with this attribute is a string with
|
||||
* package names separated by vertical bars (<code>|</code>).</p>
|
||||
*/
|
||||
public static final String PROTOCOL_PROVIDER_PACKAGES =
|
||||
"jmx.remote.protocol.provider.pkgs";
|
||||
|
||||
/**
|
||||
* <p>Name of the attribute that specifies the class
|
||||
* loader for loading protocol providers.
|
||||
* The value associated with this attribute is an instance
|
||||
* of {@link ClassLoader}.</p>
|
||||
*/
|
||||
public static final String PROTOCOL_PROVIDER_CLASS_LOADER =
|
||||
"jmx.remote.protocol.provider.class.loader";
|
||||
|
||||
private static final String PROTOCOL_PROVIDER_DEFAULT_PACKAGE =
|
||||
"com.sun.jmx.remote.protocol";
|
||||
|
||||
private static final ClassLogger logger =
|
||||
new ClassLogger("javax.management.remote.misc","JMXConnectorServerFactory");
|
||||
|
||||
/** There are no instances of this class. */
|
||||
private JMXConnectorServerFactory() {
|
||||
}
|
||||
|
||||
private static JMXConnectorServer
|
||||
getConnectorServerAsService(ClassLoader loader,
|
||||
JMXServiceURL url,
|
||||
Map<String, ?> map,
|
||||
MBeanServer mbs)
|
||||
throws IOException {
|
||||
Iterator<JMXConnectorServerProvider> providers =
|
||||
JMXConnectorFactory.
|
||||
getProviderIterator(JMXConnectorServerProvider.class, loader);
|
||||
|
||||
IOException exception = null;
|
||||
while (providers.hasNext()) {
|
||||
try {
|
||||
return providers.next().newJMXConnectorServer(url, map, mbs);
|
||||
} catch (JMXProviderException e) {
|
||||
throw e;
|
||||
} catch (Exception e) {
|
||||
if (logger.traceOn())
|
||||
logger.trace("getConnectorAsService",
|
||||
"URL[" + url +
|
||||
"] Service provider exception: " + e);
|
||||
if (!(e instanceof MalformedURLException)) {
|
||||
if (exception == null) {
|
||||
if (e instanceof IOException) {
|
||||
exception = (IOException) e;
|
||||
} else {
|
||||
exception = EnvHelp.initCause(
|
||||
new IOException(e.getMessage()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (exception == null)
|
||||
return null;
|
||||
else
|
||||
throw exception;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a connector server at the given address. The
|
||||
* resultant server is not started until its {@link
|
||||
* JMXConnectorServer#start() start} method is called.</p>
|
||||
*
|
||||
* @param serviceURL the address of the new connector server. The
|
||||
* actual address of the new connector server, as returned by its
|
||||
* {@link JMXConnectorServer#getAddress() getAddress} method, will
|
||||
* not necessarily be exactly the same. For example, it might
|
||||
* include a port number if the original address did not.
|
||||
*
|
||||
* @param environment a set of attributes to control the new
|
||||
* connector server's behavior. This parameter can be null.
|
||||
* Keys in this map must be Strings. The appropriate type of each
|
||||
* associated value depends on the attribute. The contents of
|
||||
* <code>environment</code> are not changed by this call.
|
||||
*
|
||||
* @param mbeanServer the MBean server that this connector server
|
||||
* is attached to. Null if this connector server will be attached
|
||||
* to an MBean server by being registered in it.
|
||||
*
|
||||
* @return a <code>JMXConnectorServer</code> representing the new
|
||||
* connector server. Each successful call to this method produces
|
||||
* a different object.
|
||||
*
|
||||
* @exception NullPointerException if <code>serviceURL</code> is null.
|
||||
*
|
||||
* @exception IOException if the connector server cannot be made
|
||||
* because of a communication problem.
|
||||
*
|
||||
* @exception MalformedURLException if there is no provider for the
|
||||
* protocol in <code>serviceURL</code>.
|
||||
*
|
||||
* @exception JMXProviderException if there is a provider for the
|
||||
* protocol in <code>serviceURL</code> but it cannot be used for
|
||||
* some reason.
|
||||
*/
|
||||
public static JMXConnectorServer
|
||||
newJMXConnectorServer(JMXServiceURL serviceURL,
|
||||
Map<String,?> environment,
|
||||
MBeanServer mbeanServer)
|
||||
throws IOException {
|
||||
Map<String, Object> envcopy;
|
||||
if (environment == null)
|
||||
envcopy = new HashMap<String, Object>();
|
||||
else {
|
||||
EnvHelp.checkAttributes(environment);
|
||||
envcopy = new HashMap<String, Object>(environment);
|
||||
}
|
||||
|
||||
final Class<JMXConnectorServerProvider> targetInterface =
|
||||
JMXConnectorServerProvider.class;
|
||||
final ClassLoader loader =
|
||||
JMXConnectorFactory.resolveClassLoader(envcopy);
|
||||
final String protocol = serviceURL.getProtocol();
|
||||
final String providerClassName = "ServerProvider";
|
||||
|
||||
JMXConnectorServerProvider provider =
|
||||
JMXConnectorFactory.getProvider(serviceURL,
|
||||
envcopy,
|
||||
providerClassName,
|
||||
targetInterface,
|
||||
loader);
|
||||
|
||||
IOException exception = null;
|
||||
if (provider == null) {
|
||||
// Loader is null when context class loader is set to null
|
||||
// and no loader has been provided in map.
|
||||
// com.sun.jmx.remote.util.Service class extracted from j2se
|
||||
// provider search algorithm doesn't handle well null classloader.
|
||||
if (loader != null) {
|
||||
try {
|
||||
JMXConnectorServer connection =
|
||||
getConnectorServerAsService(loader,
|
||||
serviceURL,
|
||||
envcopy,
|
||||
mbeanServer);
|
||||
if (connection != null)
|
||||
return connection;
|
||||
} catch (JMXProviderException e) {
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
provider =
|
||||
JMXConnectorFactory.getProvider(
|
||||
protocol,
|
||||
PROTOCOL_PROVIDER_DEFAULT_PACKAGE,
|
||||
JMXConnectorFactory.class.getClassLoader(),
|
||||
providerClassName,
|
||||
targetInterface);
|
||||
}
|
||||
|
||||
if (provider == null) {
|
||||
MalformedURLException e =
|
||||
new MalformedURLException("Unsupported protocol: " + protocol);
|
||||
if (exception == null) {
|
||||
throw e;
|
||||
} else {
|
||||
throw EnvHelp.initCause(e, exception);
|
||||
}
|
||||
}
|
||||
|
||||
envcopy = Collections.unmodifiableMap(envcopy);
|
||||
|
||||
return provider.newJMXConnectorServer(serviceURL,
|
||||
envcopy,
|
||||
mbeanServer);
|
||||
}
|
||||
}
|
||||
212
jdkSrc/jdk8/javax/management/remote/JMXConnectorServerMBean.java
Normal file
212
jdkSrc/jdk8/javax/management/remote/JMXConnectorServerMBean.java
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2008, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>MBean interface for connector servers. A JMX API connector server
|
||||
* is attached to an MBean server, and establishes connections to that
|
||||
* MBean server for remote clients.</p>
|
||||
*
|
||||
* <p>A newly-created connector server is <em>inactive</em>, and does
|
||||
* not yet listen for connections. Only when its {@link #start start}
|
||||
* method has been called does it start listening for connections.</p>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface JMXConnectorServerMBean {
|
||||
/**
|
||||
* <p>Activates the connector server, that is, starts listening for
|
||||
* client connections. Calling this method when the connector
|
||||
* server is already active has no effect. Calling this method
|
||||
* when the connector server has been stopped will generate an
|
||||
* {@link IOException}.</p>
|
||||
*
|
||||
* @exception IOException if it is not possible to start listening
|
||||
* or if the connector server has been stopped.
|
||||
*
|
||||
* @exception IllegalStateException if the connector server has
|
||||
* not been attached to an MBean server.
|
||||
*/
|
||||
public void start() throws IOException;
|
||||
|
||||
/**
|
||||
* <p>Deactivates the connector server, that is, stops listening for
|
||||
* client connections. Calling this method will also close all
|
||||
* client connections that were made by this server. After this
|
||||
* method returns, whether normally or with an exception, the
|
||||
* connector server will not create any new client
|
||||
* connections.</p>
|
||||
*
|
||||
* <p>Once a connector server has been stopped, it cannot be started
|
||||
* again.</p>
|
||||
*
|
||||
* <p>Calling this method when the connector server has already
|
||||
* been stopped has no effect. Calling this method when the
|
||||
* connector server has not yet been started will disable the
|
||||
* connector server object permanently.</p>
|
||||
*
|
||||
* <p>If closing a client connection produces an exception, that
|
||||
* exception is not thrown from this method. A {@link
|
||||
* JMXConnectionNotification} with type {@link
|
||||
* JMXConnectionNotification#FAILED} is emitted from this MBean
|
||||
* with the connection ID of the connection that could not be
|
||||
* closed.</p>
|
||||
*
|
||||
* <p>Closing a connector server is a potentially slow operation.
|
||||
* For example, if a client machine with an open connection has
|
||||
* crashed, the close operation might have to wait for a network
|
||||
* protocol timeout. Callers that do not want to block in a close
|
||||
* operation should do it in a separate thread.</p>
|
||||
*
|
||||
* @exception IOException if the server cannot be closed cleanly.
|
||||
* When this exception is thrown, the server has already attempted
|
||||
* to close all client connections. All client connections are
|
||||
* closed except possibly those that generated exceptions when the
|
||||
* server attempted to close them.
|
||||
*/
|
||||
public void stop() throws IOException;
|
||||
|
||||
/**
|
||||
* <p>Determines whether the connector server is active. A connector
|
||||
* server starts being active when its {@link #start start} method
|
||||
* returns successfully and remains active until either its
|
||||
* {@link #stop stop} method is called or the connector server
|
||||
* fails.</p>
|
||||
*
|
||||
* @return true if the connector server is active.
|
||||
*/
|
||||
public boolean isActive();
|
||||
|
||||
/**
|
||||
* <p>Inserts an object that intercepts requests for the MBean server
|
||||
* that arrive through this connector server. This object will be
|
||||
* supplied as the <code>MBeanServer</code> for any new connection
|
||||
* created by this connector server. Existing connections are
|
||||
* unaffected.</p>
|
||||
*
|
||||
* <p>This method can be called more than once with different
|
||||
* {@link MBeanServerForwarder} objects. The result is a chain
|
||||
* of forwarders. The last forwarder added is the first in the chain.
|
||||
* In more detail:</p>
|
||||
*
|
||||
* <ul>
|
||||
* <li><p>If this connector server is already associated with an
|
||||
* <code>MBeanServer</code> object, then that object is given to
|
||||
* {@link MBeanServerForwarder#setMBeanServer
|
||||
* mbsf.setMBeanServer}. If doing so produces an exception, this
|
||||
* method throws the same exception without any other effect.</p>
|
||||
*
|
||||
* <li><p>If this connector is not already associated with an
|
||||
* <code>MBeanServer</code> object, or if the
|
||||
* <code>mbsf.setMBeanServer</code> call just mentioned succeeds,
|
||||
* then <code>mbsf</code> becomes this connector server's
|
||||
* <code>MBeanServer</code>.</p>
|
||||
* </ul>
|
||||
*
|
||||
* @param mbsf the new <code>MBeanServerForwarder</code>.
|
||||
*
|
||||
* @exception IllegalArgumentException if the call to {@link
|
||||
* MBeanServerForwarder#setMBeanServer mbsf.setMBeanServer} fails
|
||||
* with <code>IllegalArgumentException</code>. This includes the
|
||||
* case where <code>mbsf</code> is null.
|
||||
*/
|
||||
public void setMBeanServerForwarder(MBeanServerForwarder mbsf);
|
||||
|
||||
/**
|
||||
* <p>The list of IDs for currently-open connections to this
|
||||
* connector server.</p>
|
||||
*
|
||||
* @return a new string array containing the list of IDs. If
|
||||
* there are no currently-open connections, this array will be
|
||||
* empty.
|
||||
*/
|
||||
public String[] getConnectionIds();
|
||||
|
||||
/**
|
||||
* <p>The address of this connector server.</p>
|
||||
* <p>
|
||||
* The address returned may not be the exact original {@link JMXServiceURL}
|
||||
* that was supplied when creating the connector server, since the original
|
||||
* address may not always be complete. For example the port number may be
|
||||
* dynamically allocated when starting the connector server. Instead the
|
||||
* address returned is the actual {@link JMXServiceURL} of the
|
||||
* {@link JMXConnectorServer}. This is the address that clients supply
|
||||
* to {@link JMXConnectorFactory#connect(JMXServiceURL)}.
|
||||
* </p>
|
||||
* <p>Note that the address returned may be {@code null} if
|
||||
* the {@code JMXConnectorServer} is not yet {@link #isActive active}.
|
||||
* </p>
|
||||
*
|
||||
* @return the address of this connector server, or null if it
|
||||
* does not have one.
|
||||
*/
|
||||
public JMXServiceURL getAddress();
|
||||
|
||||
/**
|
||||
* <p>The attributes for this connector server.</p>
|
||||
*
|
||||
* @return a read-only map containing the attributes for this
|
||||
* connector server. Attributes whose values are not serializable
|
||||
* are omitted from this map. If there are no serializable
|
||||
* attributes, the returned map is empty.
|
||||
*/
|
||||
public Map<String,?> getAttributes();
|
||||
|
||||
/**
|
||||
* <p>Returns a client stub for this connector server. A client
|
||||
* stub is a serializable object whose {@link
|
||||
* JMXConnector#connect(Map) connect} method can be used to make
|
||||
* one new connection to this connector server.</p>
|
||||
*
|
||||
* <p>A given connector need not support the generation of client
|
||||
* stubs. However, the connectors specified by the JMX Remote API do
|
||||
* (JMXMP Connector and RMI Connector).</p>
|
||||
*
|
||||
* @param env client connection parameters of the same sort that
|
||||
* can be provided to {@link JMXConnector#connect(Map)
|
||||
* JMXConnector.connect(Map)}. Can be null, which is equivalent
|
||||
* to an empty map.
|
||||
*
|
||||
* @return a client stub that can be used to make a new connection
|
||||
* to this connector server.
|
||||
*
|
||||
* @exception UnsupportedOperationException if this connector
|
||||
* server does not support the generation of client stubs.
|
||||
*
|
||||
* @exception IllegalStateException if the JMXConnectorServer is
|
||||
* not started (see {@link JMXConnectorServerMBean#isActive()}).
|
||||
*
|
||||
* @exception IOException if a communications problem means that a
|
||||
* stub cannot be created.
|
||||
*
|
||||
*/
|
||||
public JMXConnector toJMXConnector(Map<String,?> env)
|
||||
throws IOException;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2007, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
|
||||
/**
|
||||
* <p>A provider for creating JMX API connector servers using a given
|
||||
* protocol. Instances of this interface are created by {@link
|
||||
* JMXConnectorServerFactory} as part of its {@link
|
||||
* JMXConnectorServerFactory#newJMXConnectorServer(JMXServiceURL,Map,MBeanServer)
|
||||
* newJMXConnectorServer} method.</p>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface JMXConnectorServerProvider {
|
||||
/**
|
||||
* <p>Creates a new connector server at the given address. Each
|
||||
* successful call to this method produces a different
|
||||
* <code>JMXConnectorServer</code> object.</p>
|
||||
*
|
||||
* @param serviceURL the address of the new connector server. The
|
||||
* actual address of the new connector server, as returned by its
|
||||
* {@link JMXConnectorServer#getAddress() getAddress} method, will
|
||||
* not necessarily be exactly the same. For example, it might
|
||||
* include a port number if the original address did not.
|
||||
*
|
||||
* @param environment a read-only Map containing named attributes
|
||||
* to control the new connector server's behavior. Keys in this
|
||||
* map must be Strings. The appropriate type of each associated
|
||||
* value depends on the attribute.
|
||||
*
|
||||
* @param mbeanServer the MBean server that this connector server
|
||||
* is attached to. Null if this connector server will be attached
|
||||
* to an MBean server by being registered in it.
|
||||
*
|
||||
* @return a <code>JMXConnectorServer</code> representing the new
|
||||
* connector server. Each successful call to this method produces
|
||||
* a different object.
|
||||
*
|
||||
* @exception NullPointerException if <code>serviceURL</code> or
|
||||
* <code>environment</code> is null.
|
||||
*
|
||||
* @exception IOException It is recommended for a provider
|
||||
* implementation to throw {@code MalformedURLException} if the
|
||||
* protocol in the {@code serviceURL} is not recognized by this
|
||||
* provider, {@code JMXProviderException} if this is a provider
|
||||
* for the protocol in {@code serviceURL} but it cannot be used
|
||||
* for some reason or any other {@code IOException} if the
|
||||
* connector server cannot be created.
|
||||
*/
|
||||
public JMXConnectorServer newJMXConnectorServer(JMXServiceURL serviceURL,
|
||||
Map<String,?> environment,
|
||||
MBeanServer mbeanServer)
|
||||
throws IOException;
|
||||
}
|
||||
150
jdkSrc/jdk8/javax/management/remote/JMXPrincipal.java
Normal file
150
jdkSrc/jdk8/javax/management/remote/JMXPrincipal.java
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
import java.security.Principal;
|
||||
|
||||
/**
|
||||
* <p>The identity of a remote client of the JMX Remote API.</p>
|
||||
*
|
||||
* <p>Principals such as this <code>JMXPrincipal</code>
|
||||
* may be associated with a particular <code>Subject</code>
|
||||
* to augment that <code>Subject</code> with an additional
|
||||
* identity. Refer to the {@link javax.security.auth.Subject}
|
||||
* class for more information on how to achieve this.
|
||||
* Authorization decisions can then be based upon
|
||||
* the Principals associated with a <code>Subject</code>.
|
||||
*
|
||||
* @see java.security.Principal
|
||||
* @see javax.security.auth.Subject
|
||||
* @since 1.5
|
||||
*/
|
||||
public class JMXPrincipal implements Principal, Serializable {
|
||||
|
||||
private static final long serialVersionUID = -4184480100214577411L;
|
||||
|
||||
/**
|
||||
* @serial The JMX Remote API name for the identity represented by
|
||||
* this <code>JMXPrincipal</code> object.
|
||||
* @see #getName()
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* <p>Creates a JMXPrincipal for a given identity.</p>
|
||||
*
|
||||
* @param name the JMX Remote API name for this identity.
|
||||
*
|
||||
* @exception NullPointerException if the <code>name</code> is
|
||||
* <code>null</code>.
|
||||
*/
|
||||
public JMXPrincipal(String name) {
|
||||
validate(name);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this principal.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return the name of this <code>JMXPrincipal</code>.
|
||||
*/
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this <code>JMXPrincipal</code>.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return a string representation of this <code>JMXPrincipal</code>.
|
||||
*/
|
||||
public String toString() {
|
||||
return("JMXPrincipal: " + name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the specified Object with this <code>JMXPrincipal</code>
|
||||
* for equality. Returns true if the given object is also a
|
||||
* <code>JMXPrincipal</code> and the two JMXPrincipals
|
||||
* have the same name.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @param o Object to be compared for equality with this
|
||||
* <code>JMXPrincipal</code>.
|
||||
*
|
||||
* @return true if the specified Object is equal to this
|
||||
* <code>JMXPrincipal</code>.
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (o == null)
|
||||
return false;
|
||||
|
||||
if (this == o)
|
||||
return true;
|
||||
|
||||
if (!(o instanceof JMXPrincipal))
|
||||
return false;
|
||||
JMXPrincipal that = (JMXPrincipal)o;
|
||||
|
||||
return (this.getName().equals(that.getName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hash code for this <code>JMXPrincipal</code>.
|
||||
*
|
||||
* <p>
|
||||
*
|
||||
* @return a hash code for this <code>JMXPrincipal</code>.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return name.hashCode();
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
ObjectInputStream.GetField gf = ois.readFields();
|
||||
String principalName = (String)gf.get("name", null);
|
||||
try {
|
||||
validate(principalName);
|
||||
this.name = principalName;
|
||||
} catch (NullPointerException e) {
|
||||
throw new InvalidObjectException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static void validate(String name) throws NullPointerException {
|
||||
if (name == null)
|
||||
throw new NullPointerException("illegal null input");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2007, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* <p>Exception thrown by {@link JMXConnectorFactory} and
|
||||
* {@link JMXConnectorServerFactory} when a provider exists for
|
||||
* the required protocol but cannot be used for some reason.</p>
|
||||
*
|
||||
* @see JMXConnectorFactory#newJMXConnector
|
||||
* @see JMXConnectorServerFactory#newJMXConnectorServer
|
||||
* @since 1.5
|
||||
*/
|
||||
public class JMXProviderException extends IOException {
|
||||
|
||||
private static final long serialVersionUID = -3166703627550447198L;
|
||||
|
||||
/**
|
||||
* <p>Constructs a <code>JMXProviderException</code> with no
|
||||
* specified detail message.</p>
|
||||
*/
|
||||
public JMXProviderException() {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Constructs a <code>JMXProviderException</code> with the
|
||||
* specified detail message.</p>
|
||||
*
|
||||
* @param message the detail message
|
||||
*/
|
||||
public JMXProviderException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Constructs a <code>JMXProviderException</code> with the
|
||||
* specified detail message and nested exception.</p>
|
||||
*
|
||||
* @param message the detail message
|
||||
* @param cause the nested exception
|
||||
*/
|
||||
public JMXProviderException(String message, Throwable cause) {
|
||||
super(message);
|
||||
this.cause = cause;
|
||||
}
|
||||
|
||||
public Throwable getCause() {
|
||||
return cause;
|
||||
}
|
||||
|
||||
/**
|
||||
* @serial An exception that caused this exception to be thrown.
|
||||
* This field may be null.
|
||||
* @see #getCause()
|
||||
**/
|
||||
private Throwable cause = null;
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2007, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
// imports for javadoc
|
||||
import javax.management.MBeanServer;
|
||||
|
||||
/**
|
||||
* Exception thrown as the result of a remote {@link MBeanServer}
|
||||
* method invocation when an <code>Error</code> is thrown while
|
||||
* processing the invocation in the remote MBean server. A
|
||||
* <code>JMXServerErrorException</code> instance contains the original
|
||||
* <code>Error</code> that occurred as its cause.
|
||||
*
|
||||
* @see java.rmi.ServerError
|
||||
* @since 1.5
|
||||
*/
|
||||
public class JMXServerErrorException extends IOException {
|
||||
|
||||
private static final long serialVersionUID = 3996732239558744666L;
|
||||
|
||||
/**
|
||||
* Constructs a <code>JMXServerErrorException</code> with the specified
|
||||
* detail message and nested error.
|
||||
*
|
||||
* @param s the detail message.
|
||||
* @param err the nested error. An instance of this class can be
|
||||
* constructed where this parameter is null, but the standard
|
||||
* connectors will never do so.
|
||||
*/
|
||||
public JMXServerErrorException(String s, Error err) {
|
||||
super(s);
|
||||
cause = err;
|
||||
}
|
||||
|
||||
public Throwable getCause() {
|
||||
return cause;
|
||||
}
|
||||
|
||||
/**
|
||||
* @serial An {@link Error} that caused this exception to be thrown.
|
||||
* @see #getCause()
|
||||
**/
|
||||
private final Error cause;
|
||||
}
|
||||
733
jdkSrc/jdk8/javax/management/remote/JMXServiceURL.java
Normal file
733
jdkSrc/jdk8/javax/management/remote/JMXServiceURL.java
Normal file
@@ -0,0 +1,733 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
|
||||
import com.sun.jmx.remote.util.ClassLogger;
|
||||
import com.sun.jmx.remote.util.EnvHelp;
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.BitSet;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* <p>The address of a JMX API connector server. Instances of this class
|
||||
* are immutable.</p>
|
||||
*
|
||||
* <p>The address is an <em>Abstract Service URL</em> for SLP, as
|
||||
* defined in RFC 2609 and amended by RFC 3111. It must look like
|
||||
* this:</p>
|
||||
*
|
||||
* <blockquote>
|
||||
*
|
||||
* <code>service:jmx:<em>protocol</em>:<em>sap</em></code>
|
||||
*
|
||||
* </blockquote>
|
||||
*
|
||||
* <p>Here, <code><em>protocol</em></code> is the transport
|
||||
* protocol to be used to connect to the connector server. It is
|
||||
* a string of one or more ASCII characters, each of which is a
|
||||
* letter, a digit, or one of the characters <code>+</code> or
|
||||
* <code>-</code>. The first character must be a letter.
|
||||
* Uppercase letters are converted into lowercase ones.</p>
|
||||
*
|
||||
* <p><code><em>sap</em></code> is the address at which the connector
|
||||
* server is found. This address uses a subset of the syntax defined
|
||||
* by RFC 2609 for IP-based protocols. It is a subset because the
|
||||
* <code>user@host</code> syntax is not supported.</p>
|
||||
*
|
||||
* <p>The other syntaxes defined by RFC 2609 are not currently
|
||||
* supported by this class.</p>
|
||||
*
|
||||
* <p>The supported syntax is:</p>
|
||||
*
|
||||
* <blockquote>
|
||||
*
|
||||
* <code>//<em>[host[</em>:<em>port]][url-path]</em></code>
|
||||
*
|
||||
* </blockquote>
|
||||
*
|
||||
* <p>Square brackets <code>[]</code> indicate optional parts of
|
||||
* the address. Not all protocols will recognize all optional
|
||||
* parts.</p>
|
||||
*
|
||||
* <p>The <code><em>host</em></code> is a host name, an IPv4 numeric
|
||||
* host address, or an IPv6 numeric address enclosed in square
|
||||
* brackets.</p>
|
||||
*
|
||||
* <p>The <code><em>port</em></code> is a decimal port number. 0
|
||||
* means a default or anonymous port, depending on the protocol.</p>
|
||||
*
|
||||
* <p>The <code><em>host</em></code> and <code><em>port</em></code>
|
||||
* can be omitted. The <code><em>port</em></code> cannot be supplied
|
||||
* without a <code><em>host</em></code>.</p>
|
||||
*
|
||||
* <p>The <code><em>url-path</em></code>, if any, begins with a slash
|
||||
* (<code>/</code>) or a semicolon (<code>;</code>) and continues to
|
||||
* the end of the address. It can contain attributes using the
|
||||
* semicolon syntax specified in RFC 2609. Those attributes are not
|
||||
* parsed by this class and incorrect attribute syntax is not
|
||||
* detected.</p>
|
||||
*
|
||||
* <p>Although it is legal according to RFC 2609 to have a
|
||||
* <code><em>url-path</em></code> that begins with a semicolon, not
|
||||
* all implementations of SLP allow it, so it is recommended to avoid
|
||||
* that syntax.</p>
|
||||
*
|
||||
* <p>Case is not significant in the initial
|
||||
* <code>service:jmx:<em>protocol</em></code> string or in the host
|
||||
* part of the address. Depending on the protocol, case can be
|
||||
* significant in the <code><em>url-path</em></code>.</p>
|
||||
*
|
||||
* @see <a
|
||||
* href="http://www.ietf.org/rfc/rfc2609.txt">RFC 2609,
|
||||
* "Service Templates and <code>Service:</code> Schemes"</a>
|
||||
* @see <a
|
||||
* href="http://www.ietf.org/rfc/rfc3111.txt">RFC 3111,
|
||||
* "Service Location Protocol Modifications for IPv6"</a>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class JMXServiceURL implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 8173364409860779292L;
|
||||
|
||||
/**
|
||||
* <p>Constructs a <code>JMXServiceURL</code> by parsing a Service URL
|
||||
* string.</p>
|
||||
*
|
||||
* @param serviceURL the URL string to be parsed.
|
||||
*
|
||||
* @exception NullPointerException if <code>serviceURL</code> is
|
||||
* null.
|
||||
*
|
||||
* @exception MalformedURLException if <code>serviceURL</code>
|
||||
* does not conform to the syntax for an Abstract Service URL or
|
||||
* if it is not a valid name for a JMX Remote API service. A
|
||||
* <code>JMXServiceURL</code> must begin with the string
|
||||
* <code>"service:jmx:"</code> (case-insensitive). It must not
|
||||
* contain any characters that are not printable ASCII characters.
|
||||
*/
|
||||
public JMXServiceURL(String serviceURL) throws MalformedURLException {
|
||||
final int serviceURLLength = serviceURL.length();
|
||||
|
||||
/* Check that there are no non-ASCII characters in the URL,
|
||||
following RFC 2609. */
|
||||
for (int i = 0; i < serviceURLLength; i++) {
|
||||
char c = serviceURL.charAt(i);
|
||||
if (c < 32 || c >= 127) {
|
||||
throw new MalformedURLException("Service URL contains " +
|
||||
"non-ASCII character 0x" +
|
||||
Integer.toHexString(c));
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the required prefix
|
||||
final String requiredPrefix = "service:jmx:";
|
||||
final int requiredPrefixLength = requiredPrefix.length();
|
||||
if (!serviceURL.regionMatches(true, // ignore case
|
||||
0, // serviceURL offset
|
||||
requiredPrefix,
|
||||
0, // requiredPrefix offset
|
||||
requiredPrefixLength)) {
|
||||
throw new MalformedURLException("Service URL must start with " +
|
||||
requiredPrefix);
|
||||
}
|
||||
|
||||
// Parse the protocol name
|
||||
final int protoStart = requiredPrefixLength;
|
||||
final int protoEnd = indexOf(serviceURL, ':', protoStart);
|
||||
this.protocol =
|
||||
serviceURL.substring(protoStart, protoEnd).toLowerCase();
|
||||
|
||||
if (!serviceURL.regionMatches(protoEnd, "://", 0, 3)) {
|
||||
throw new MalformedURLException("Missing \"://\" after " +
|
||||
"protocol name");
|
||||
}
|
||||
|
||||
// Parse the host name
|
||||
final int hostStart = protoEnd + 3;
|
||||
final int hostEnd;
|
||||
if (hostStart < serviceURLLength
|
||||
&& serviceURL.charAt(hostStart) == '[') {
|
||||
hostEnd = serviceURL.indexOf(']', hostStart) + 1;
|
||||
if (hostEnd == 0)
|
||||
throw new MalformedURLException("Bad host name: [ without ]");
|
||||
this.host = serviceURL.substring(hostStart + 1, hostEnd - 1);
|
||||
if (!isNumericIPv6Address(this.host)) {
|
||||
throw new MalformedURLException("Address inside [...] must " +
|
||||
"be numeric IPv6 address");
|
||||
}
|
||||
} else {
|
||||
hostEnd =
|
||||
indexOfFirstNotInSet(serviceURL, hostNameBitSet, hostStart);
|
||||
this.host = serviceURL.substring(hostStart, hostEnd);
|
||||
}
|
||||
|
||||
// Parse the port number
|
||||
final int portEnd;
|
||||
if (hostEnd < serviceURLLength && serviceURL.charAt(hostEnd) == ':') {
|
||||
if (this.host.length() == 0) {
|
||||
throw new MalformedURLException("Cannot give port number " +
|
||||
"without host name");
|
||||
}
|
||||
final int portStart = hostEnd + 1;
|
||||
portEnd =
|
||||
indexOfFirstNotInSet(serviceURL, numericBitSet, portStart);
|
||||
final String portString = serviceURL.substring(portStart, portEnd);
|
||||
try {
|
||||
this.port = Integer.parseInt(portString);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new MalformedURLException("Bad port number: \"" +
|
||||
portString + "\": " + e);
|
||||
}
|
||||
} else {
|
||||
portEnd = hostEnd;
|
||||
this.port = 0;
|
||||
}
|
||||
|
||||
// Parse the URL path
|
||||
final int urlPathStart = portEnd;
|
||||
if (urlPathStart < serviceURLLength)
|
||||
this.urlPath = serviceURL.substring(urlPathStart);
|
||||
else
|
||||
this.urlPath = "";
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Constructs a <code>JMXServiceURL</code> with the given protocol,
|
||||
* host, and port. This constructor is equivalent to
|
||||
* {@link #JMXServiceURL(String, String, int, String)
|
||||
* JMXServiceURL(protocol, host, port, null)}.</p>
|
||||
*
|
||||
* @param protocol the protocol part of the URL. If null, defaults
|
||||
* to <code>jmxmp</code>.
|
||||
*
|
||||
* @param host the host part of the URL. If null, defaults to the
|
||||
* local host name, as determined by
|
||||
* <code>InetAddress.getLocalHost().getHostName()</code>. If it
|
||||
* is a numeric IPv6 address, it can optionally be enclosed in
|
||||
* square brackets <code>[]</code>.
|
||||
*
|
||||
* @param port the port part of the URL.
|
||||
*
|
||||
* @exception MalformedURLException if one of the parts is
|
||||
* syntactically incorrect, or if <code>host</code> is null and it
|
||||
* is not possible to find the local host name, or if
|
||||
* <code>port</code> is negative.
|
||||
*/
|
||||
public JMXServiceURL(String protocol, String host, int port)
|
||||
throws MalformedURLException {
|
||||
this(protocol, host, port, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Constructs a <code>JMXServiceURL</code> with the given parts.
|
||||
*
|
||||
* @param protocol the protocol part of the URL. If null, defaults
|
||||
* to <code>jmxmp</code>.
|
||||
*
|
||||
* @param host the host part of the URL. If null, defaults to the
|
||||
* local host name, as determined by
|
||||
* <code>InetAddress.getLocalHost().getHostName()</code>. If it
|
||||
* is a numeric IPv6 address, it can optionally be enclosed in
|
||||
* square brackets <code>[]</code>.
|
||||
*
|
||||
* @param port the port part of the URL.
|
||||
*
|
||||
* @param urlPath the URL path part of the URL. If null, defaults to
|
||||
* the empty string.
|
||||
*
|
||||
* @exception MalformedURLException if one of the parts is
|
||||
* syntactically incorrect, or if <code>host</code> is null and it
|
||||
* is not possible to find the local host name, or if
|
||||
* <code>port</code> is negative.
|
||||
*/
|
||||
public JMXServiceURL(String protocol, String host, int port,
|
||||
String urlPath)
|
||||
throws MalformedURLException {
|
||||
if (protocol == null)
|
||||
protocol = "jmxmp";
|
||||
|
||||
if (host == null) {
|
||||
InetAddress local;
|
||||
try {
|
||||
local = InetAddress.getLocalHost();
|
||||
} catch (UnknownHostException e) {
|
||||
throw new MalformedURLException("Local host name unknown: " +
|
||||
e);
|
||||
}
|
||||
|
||||
host = local.getHostName();
|
||||
|
||||
/* We might have a hostname that violates DNS naming
|
||||
rules, for example that contains an `_'. While we
|
||||
could be strict and throw an exception, this is rather
|
||||
user-hostile. Instead we use its numerical IP address.
|
||||
We can only reasonably do this for the host==null case.
|
||||
If we're given an explicit host name that is illegal we
|
||||
have to reject it. (Bug 5057532.) */
|
||||
try {
|
||||
validateHost(host, port);
|
||||
} catch (MalformedURLException e) {
|
||||
if (logger.fineOn()) {
|
||||
logger.fine("JMXServiceURL",
|
||||
"Replacing illegal local host name " +
|
||||
host + " with numeric IP address " +
|
||||
"(see RFC 1034)", e);
|
||||
}
|
||||
host = local.getHostAddress();
|
||||
/* Use the numeric address, which could be either IPv4
|
||||
or IPv6. validateHost will accept either. */
|
||||
}
|
||||
}
|
||||
|
||||
if (host.startsWith("[")) {
|
||||
if (!host.endsWith("]")) {
|
||||
throw new MalformedURLException("Host starts with [ but " +
|
||||
"does not end with ]");
|
||||
}
|
||||
host = host.substring(1, host.length() - 1);
|
||||
if (!isNumericIPv6Address(host)) {
|
||||
throw new MalformedURLException("Address inside [...] must " +
|
||||
"be numeric IPv6 address");
|
||||
}
|
||||
if (host.startsWith("["))
|
||||
throw new MalformedURLException("More than one [[...]]");
|
||||
}
|
||||
|
||||
this.protocol = protocol.toLowerCase();
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
|
||||
if (urlPath == null)
|
||||
urlPath = "";
|
||||
this.urlPath = urlPath;
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
private static final String INVALID_INSTANCE_MSG =
|
||||
"Trying to deserialize an invalid instance of JMXServiceURL";
|
||||
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException {
|
||||
ObjectInputStream.GetField gf = inputStream.readFields();
|
||||
String h = (String)gf.get("host", null);
|
||||
int p = (int)gf.get("port", -1);
|
||||
String proto = (String)gf.get("protocol", null);
|
||||
String url = (String)gf.get("urlPath", null);
|
||||
|
||||
if (proto == null || url == null || h == null) {
|
||||
StringBuilder sb = new StringBuilder(INVALID_INSTANCE_MSG).append('[');
|
||||
boolean empty = true;
|
||||
if (proto == null) {
|
||||
sb.append("protocol=null");
|
||||
empty = false;
|
||||
}
|
||||
if (h == null) {
|
||||
sb.append(empty ? "" : ",").append("host=null");
|
||||
empty = false;
|
||||
}
|
||||
if (url == null) {
|
||||
sb.append(empty ? "" : ",").append("urlPath=null");
|
||||
}
|
||||
sb.append(']');
|
||||
throw new InvalidObjectException(sb.toString());
|
||||
}
|
||||
|
||||
if (h.contains("[") || h.contains("]")) {
|
||||
throw new InvalidObjectException("Invalid host name: " + h);
|
||||
}
|
||||
|
||||
try {
|
||||
validate(proto, h, p, url);
|
||||
this.protocol = proto;
|
||||
this.host = h;
|
||||
this.port = p;
|
||||
this.urlPath = url;
|
||||
} catch (MalformedURLException e) {
|
||||
throw new InvalidObjectException(INVALID_INSTANCE_MSG + ": " +
|
||||
e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void validate(String proto, String h, int p, String url)
|
||||
throws MalformedURLException {
|
||||
// Check protocol
|
||||
final int protoEnd = indexOfFirstNotInSet(proto, protocolBitSet, 0);
|
||||
if (protoEnd == 0 || protoEnd < proto.length()
|
||||
|| !alphaBitSet.get(proto.charAt(0))) {
|
||||
throw new MalformedURLException("Missing or invalid protocol " +
|
||||
"name: \"" + proto + "\"");
|
||||
}
|
||||
|
||||
// Check host
|
||||
validateHost(h, p);
|
||||
|
||||
// Check port
|
||||
if (p < 0)
|
||||
throw new MalformedURLException("Bad port: " + p);
|
||||
|
||||
// Check URL path
|
||||
if (url.length() > 0) {
|
||||
if (!url.startsWith("/") && !url.startsWith(";"))
|
||||
throw new MalformedURLException("Bad URL path: " + url);
|
||||
}
|
||||
}
|
||||
|
||||
private void validate() throws MalformedURLException {
|
||||
validate(this.protocol, this.host, this.port, this.urlPath);
|
||||
}
|
||||
|
||||
private static void validateHost(String h, int port)
|
||||
throws MalformedURLException {
|
||||
|
||||
if (h.length() == 0) {
|
||||
if (port != 0) {
|
||||
throw new MalformedURLException("Cannot give port number " +
|
||||
"without host name");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (isNumericIPv6Address(h)) {
|
||||
/* We assume J2SE >= 1.4 here. Otherwise you can't
|
||||
use the address anyway. We can't call
|
||||
InetAddress.getByName without checking for a
|
||||
numeric IPv6 address, because we mustn't try to do
|
||||
a DNS lookup in case the address is not actually
|
||||
numeric. */
|
||||
try {
|
||||
InetAddress.getByName(h);
|
||||
} catch (Exception e) {
|
||||
/* We should really catch UnknownHostException
|
||||
here, but a bug in JDK 1.4 causes it to throw
|
||||
ArrayIndexOutOfBoundsException, e.g. if the
|
||||
string is ":". */
|
||||
MalformedURLException bad =
|
||||
new MalformedURLException("Bad IPv6 address: " + h);
|
||||
EnvHelp.initCause(bad, e);
|
||||
throw bad;
|
||||
}
|
||||
} else {
|
||||
/* Tiny state machine to check valid host name. This
|
||||
checks the hostname grammar from RFC 1034 (DNS),
|
||||
page 11. A hostname is a dot-separated list of one
|
||||
or more labels, where each label consists of
|
||||
letters, numbers, or hyphens. A label cannot begin
|
||||
or end with a hyphen. Empty hostnames are not
|
||||
allowed. Note that numeric IPv4 addresses are a
|
||||
special case of this grammar.
|
||||
|
||||
The state is entirely captured by the last
|
||||
character seen, with a virtual `.' preceding the
|
||||
name. We represent any alphanumeric character by
|
||||
`a'.
|
||||
|
||||
We need a special hack to check, as required by the
|
||||
RFC 2609 (SLP) grammar, that the last component of
|
||||
the hostname begins with a letter. Respecting the
|
||||
intent of the RFC, we only do this if there is more
|
||||
than one component. If your local hostname begins
|
||||
with a digit, we don't reject it. */
|
||||
final int hostLen = h.length();
|
||||
char lastc = '.';
|
||||
boolean sawDot = false;
|
||||
char componentStart = 0;
|
||||
|
||||
loop:
|
||||
for (int i = 0; i < hostLen; i++) {
|
||||
char c = h.charAt(i);
|
||||
boolean isAlphaNumeric = alphaNumericBitSet.get(c);
|
||||
if (lastc == '.')
|
||||
componentStart = c;
|
||||
if (isAlphaNumeric)
|
||||
lastc = 'a';
|
||||
else if (c == '-') {
|
||||
if (lastc == '.')
|
||||
break; // will throw exception
|
||||
lastc = '-';
|
||||
} else if (c == '.') {
|
||||
sawDot = true;
|
||||
if (lastc != 'a')
|
||||
break; // will throw exception
|
||||
lastc = '.';
|
||||
} else {
|
||||
lastc = '.'; // will throw exception
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (lastc != 'a')
|
||||
throw randomException;
|
||||
if (sawDot && !alphaBitSet.get(componentStart)) {
|
||||
/* Must be a numeric IPv4 address. In addition to
|
||||
the explicitly-thrown exceptions, we can get
|
||||
NoSuchElementException from the calls to
|
||||
tok.nextToken and NumberFormatException from
|
||||
the call to Integer.parseInt. Using exceptions
|
||||
for control flow this way is a bit evil but it
|
||||
does simplify things enormously. */
|
||||
StringTokenizer tok = new StringTokenizer(h, ".", true);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
String ns = tok.nextToken();
|
||||
int n = Integer.parseInt(ns);
|
||||
if (n < 0 || n > 255)
|
||||
throw randomException;
|
||||
if (i < 3 && !tok.nextToken().equals("."))
|
||||
throw randomException;
|
||||
}
|
||||
if (tok.hasMoreTokens())
|
||||
throw randomException;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new MalformedURLException("Bad host: \"" + h + "\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final Exception randomException = new Exception();
|
||||
|
||||
|
||||
/**
|
||||
* <p>The protocol part of the Service URL.
|
||||
*
|
||||
* @return the protocol part of the Service URL. This is never null.
|
||||
*/
|
||||
public String getProtocol() {
|
||||
return protocol;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The host part of the Service URL. If the Service URL was
|
||||
* constructed with the constructor that takes a URL string
|
||||
* parameter, the result is the substring specifying the host in
|
||||
* that URL. If the Service URL was constructed with a
|
||||
* constructor that takes a separate host parameter, the result is
|
||||
* the string that was specified. If that string was null, the
|
||||
* result is
|
||||
* <code>InetAddress.getLocalHost().getHostName()</code>.</p>
|
||||
*
|
||||
* <p>In either case, if the host was specified using the
|
||||
* <code>[...]</code> syntax for numeric IPv6 addresses, the
|
||||
* square brackets are not included in the return value here.</p>
|
||||
*
|
||||
* @return the host part of the Service URL. This is never null.
|
||||
*/
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The port of the Service URL. If no port was
|
||||
* specified, the returned value is 0.</p>
|
||||
*
|
||||
* @return the port of the Service URL, or 0 if none.
|
||||
*/
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The URL Path part of the Service URL. This is an empty
|
||||
* string, or a string beginning with a slash (<code>/</code>), or
|
||||
* a string beginning with a semicolon (<code>;</code>).
|
||||
*
|
||||
* @return the URL Path part of the Service URL. This is never
|
||||
* null.
|
||||
*/
|
||||
public String getURLPath() {
|
||||
return urlPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The string representation of this Service URL. If the value
|
||||
* returned by this method is supplied to the
|
||||
* <code>JMXServiceURL</code> constructor, the resultant object is
|
||||
* equal to this one.</p>
|
||||
*
|
||||
* <p>The <code><em>host</em></code> part of the returned string
|
||||
* is the value returned by {@link #getHost()}. If that value
|
||||
* specifies a numeric IPv6 address, it is surrounded by square
|
||||
* brackets <code>[]</code>.</p>
|
||||
*
|
||||
* <p>The <code><em>port</em></code> part of the returned string
|
||||
* is the value returned by {@link #getPort()} in its shortest
|
||||
* decimal form. If the value is zero, it is omitted.</p>
|
||||
*
|
||||
* @return the string representation of this Service URL.
|
||||
*/
|
||||
public String toString() {
|
||||
/* We don't bother synchronizing the access to toString. At worst,
|
||||
n threads will independently compute and store the same value. */
|
||||
if (toString != null)
|
||||
return toString;
|
||||
StringBuilder buf = new StringBuilder("service:jmx:");
|
||||
buf.append(getProtocol()).append("://");
|
||||
final String getHost = getHost();
|
||||
if (isNumericIPv6Address(getHost))
|
||||
buf.append('[').append(getHost).append(']');
|
||||
else
|
||||
buf.append(getHost);
|
||||
final int getPort = getPort();
|
||||
if (getPort != 0)
|
||||
buf.append(':').append(getPort);
|
||||
buf.append(getURLPath());
|
||||
toString = buf.toString();
|
||||
return toString;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Indicates whether some other object is equal to this one.
|
||||
* This method returns true if and only if <code>obj</code> is an
|
||||
* instance of <code>JMXServiceURL</code> whose {@link
|
||||
* #getProtocol()}, {@link #getHost()}, {@link #getPort()}, and
|
||||
* {@link #getURLPath()} methods return the same values as for
|
||||
* this object. The values for {@link #getProtocol()} and {@link
|
||||
* #getHost()} can differ in case without affecting equality.
|
||||
*
|
||||
* @param obj the reference object with which to compare.
|
||||
*
|
||||
* @return <code>true</code> if this object is the same as the
|
||||
* <code>obj</code> argument; <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof JMXServiceURL))
|
||||
return false;
|
||||
JMXServiceURL u = (JMXServiceURL) obj;
|
||||
return
|
||||
(u.getProtocol().equalsIgnoreCase(getProtocol()) &&
|
||||
u.getHost().equalsIgnoreCase(getHost()) &&
|
||||
u.getPort() == getPort() &&
|
||||
u.getURLPath().equals(getURLPath()));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return toString().hashCode();
|
||||
}
|
||||
|
||||
/* True if this string, assumed to be a valid argument to
|
||||
* InetAddress.getByName, is a numeric IPv6 address.
|
||||
*/
|
||||
private static boolean isNumericIPv6Address(String s) {
|
||||
// address contains colon if and only if it's a numeric IPv6 address
|
||||
return (s.indexOf(':') >= 0);
|
||||
}
|
||||
|
||||
// like String.indexOf but returns string length not -1 if not present
|
||||
private static int indexOf(String s, char c, int fromIndex) {
|
||||
int index = s.indexOf(c, fromIndex);
|
||||
if (index < 0)
|
||||
return s.length();
|
||||
else
|
||||
return index;
|
||||
}
|
||||
|
||||
private static int indexOfFirstNotInSet(String s, BitSet set,
|
||||
int fromIndex) {
|
||||
final int slen = s.length();
|
||||
int i = fromIndex;
|
||||
while (true) {
|
||||
if (i >= slen)
|
||||
break;
|
||||
char c = s.charAt(i);
|
||||
if (c >= 128)
|
||||
break; // not ASCII
|
||||
if (!set.get(c))
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
private final static BitSet alphaBitSet = new BitSet(128);
|
||||
private final static BitSet numericBitSet = new BitSet(128);
|
||||
private final static BitSet alphaNumericBitSet = new BitSet(128);
|
||||
private final static BitSet protocolBitSet = new BitSet(128);
|
||||
private final static BitSet hostNameBitSet = new BitSet(128);
|
||||
static {
|
||||
/* J2SE 1.4 adds lots of handy methods to BitSet that would
|
||||
allow us to simplify here, e.g. by not writing loops, but
|
||||
we want to work on J2SE 1.3 too. */
|
||||
|
||||
for (char c = '0'; c <= '9'; c++)
|
||||
numericBitSet.set(c);
|
||||
|
||||
for (char c = 'A'; c <= 'Z'; c++)
|
||||
alphaBitSet.set(c);
|
||||
for (char c = 'a'; c <= 'z'; c++)
|
||||
alphaBitSet.set(c);
|
||||
|
||||
alphaNumericBitSet.or(alphaBitSet);
|
||||
alphaNumericBitSet.or(numericBitSet);
|
||||
|
||||
protocolBitSet.or(alphaNumericBitSet);
|
||||
protocolBitSet.set('+');
|
||||
protocolBitSet.set('-');
|
||||
|
||||
hostNameBitSet.or(alphaNumericBitSet);
|
||||
hostNameBitSet.set('-');
|
||||
hostNameBitSet.set('.');
|
||||
}
|
||||
|
||||
/**
|
||||
* The value returned by {@link #getProtocol()}.
|
||||
*/
|
||||
private String protocol;
|
||||
|
||||
/**
|
||||
* The value returned by {@link #getHost()}.
|
||||
*/
|
||||
private String host;
|
||||
|
||||
/**
|
||||
* The value returned by {@link #getPort()}.
|
||||
*/
|
||||
private int port;
|
||||
|
||||
/**
|
||||
* The value returned by {@link #getURLPath()}.
|
||||
*/
|
||||
private String urlPath;
|
||||
|
||||
/**
|
||||
* Cached result of {@link #toString()}.
|
||||
*/
|
||||
private transient String toString;
|
||||
|
||||
private static final ClassLogger logger =
|
||||
new ClassLogger("javax.management.remote.misc", "JMXServiceURL");
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2007, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
|
||||
/**
|
||||
* <p>An object of this class implements the MBeanServer interface and
|
||||
* wraps another object that also implements that interface.
|
||||
* Typically, an implementation of this interface performs some action
|
||||
* in some or all methods of the <code>MBeanServer</code> interface
|
||||
* before and/or after forwarding the method to the wrapped object.
|
||||
* Examples include security checking and logging.</p>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface MBeanServerForwarder extends MBeanServer {
|
||||
|
||||
/**
|
||||
* Returns the MBeanServer object to which requests will be forwarded.
|
||||
*
|
||||
* @return the MBeanServer object to which requests will be forwarded,
|
||||
* or null if there is none.
|
||||
*
|
||||
* @see #setMBeanServer
|
||||
*/
|
||||
public MBeanServer getMBeanServer();
|
||||
|
||||
/**
|
||||
* Sets the MBeanServer object to which requests will be forwarded
|
||||
* after treatment by this object.
|
||||
*
|
||||
* @param mbs the MBeanServer object to which requests will be forwarded.
|
||||
*
|
||||
* @exception IllegalArgumentException if this object is already
|
||||
* forwarding to an MBeanServer object or if <code>mbs</code> is
|
||||
* null or if <code>mbs</code> is identical to this object.
|
||||
*
|
||||
* @see #getMBeanServer
|
||||
*/
|
||||
public void setMBeanServer(MBeanServer mbs);
|
||||
}
|
||||
170
jdkSrc/jdk8/javax/management/remote/NotificationResult.java
Normal file
170
jdkSrc/jdk8/javax/management/remote/NotificationResult.java
Normal file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>Result of a query for buffered notifications. Notifications in
|
||||
* a notification buffer have positive, monotonically increasing
|
||||
* sequence numbers. The result of a notification query contains the
|
||||
* following elements:</p>
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li>The sequence number of the earliest notification still in
|
||||
* the buffer.
|
||||
*
|
||||
* <li>The sequence number of the next notification available for
|
||||
* querying. This will be the starting sequence number for the next
|
||||
* notification query.
|
||||
*
|
||||
* <li>An array of (Notification,listenerID) pairs corresponding to
|
||||
* the returned notifications and the listeners they correspond to.
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <p>It is possible for the <code>nextSequenceNumber</code> to be less
|
||||
* than the <code>earliestSequenceNumber</code>. This signifies that
|
||||
* notifications between the two might have been lost.</p>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class NotificationResult implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1191800228721395279L;
|
||||
|
||||
/**
|
||||
* <p>Constructs a notification query result.</p>
|
||||
*
|
||||
* @param earliestSequenceNumber the sequence number of the
|
||||
* earliest notification still in the buffer.
|
||||
* @param nextSequenceNumber the sequence number of the next
|
||||
* notification available for querying.
|
||||
* @param targetedNotifications the notifications resulting from
|
||||
* the query, and the listeners they correspond to. This array
|
||||
* can be empty.
|
||||
*
|
||||
* @exception IllegalArgumentException if
|
||||
* <code>targetedNotifications</code> is null or if
|
||||
* <code>earliestSequenceNumber</code> or
|
||||
* <code>nextSequenceNumber</code> is negative.
|
||||
*/
|
||||
public NotificationResult(long earliestSequenceNumber,
|
||||
long nextSequenceNumber,
|
||||
TargetedNotification[] targetedNotifications) {
|
||||
validate(targetedNotifications, earliestSequenceNumber, nextSequenceNumber);
|
||||
this.earliestSequenceNumber = earliestSequenceNumber;
|
||||
this.nextSequenceNumber = nextSequenceNumber;
|
||||
this.targetedNotifications = (targetedNotifications.length == 0 ? targetedNotifications : targetedNotifications.clone());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sequence number of the earliest notification still
|
||||
* in the buffer.
|
||||
*
|
||||
* @return the sequence number of the earliest notification still
|
||||
* in the buffer.
|
||||
*/
|
||||
public long getEarliestSequenceNumber() {
|
||||
return earliestSequenceNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sequence number of the next notification available
|
||||
* for querying.
|
||||
*
|
||||
* @return the sequence number of the next notification available
|
||||
* for querying.
|
||||
*/
|
||||
public long getNextSequenceNumber() {
|
||||
return nextSequenceNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the notifications resulting from the query, and the
|
||||
* listeners they correspond to.
|
||||
*
|
||||
* @return the notifications resulting from the query, and the
|
||||
* listeners they correspond to. This array can be empty.
|
||||
*/
|
||||
public TargetedNotification[] getTargetedNotifications() {
|
||||
return targetedNotifications.length == 0 ? targetedNotifications : targetedNotifications.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of the object. The result
|
||||
* should be a concise but informative representation that is easy
|
||||
* for a person to read.
|
||||
*
|
||||
* @return a string representation of the object.
|
||||
*/
|
||||
public String toString() {
|
||||
return "NotificationResult: earliest=" + getEarliestSequenceNumber() +
|
||||
"; next=" + getNextSequenceNumber() + "; nnotifs=" +
|
||||
getTargetedNotifications().length;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
ois.defaultReadObject();
|
||||
try {
|
||||
validate(
|
||||
this.targetedNotifications,
|
||||
this.earliestSequenceNumber,
|
||||
this.nextSequenceNumber
|
||||
);
|
||||
|
||||
this.targetedNotifications = this.targetedNotifications.length == 0 ?
|
||||
this.targetedNotifications :
|
||||
this.targetedNotifications.clone();
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new InvalidObjectException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private long earliestSequenceNumber;
|
||||
private long nextSequenceNumber;
|
||||
private TargetedNotification[] targetedNotifications;
|
||||
|
||||
private static void validate(TargetedNotification[] targetedNotifications,
|
||||
long earliestSequenceNumber,
|
||||
long nextSequenceNumber)
|
||||
throws IllegalArgumentException {
|
||||
if (targetedNotifications == null) {
|
||||
final String msg = "Notifications null";
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
|
||||
if (earliestSequenceNumber < 0 || nextSequenceNumber < 0)
|
||||
throw new IllegalArgumentException("Bad sequence numbers");
|
||||
/* We used to check nextSequenceNumber >= earliestSequenceNumber
|
||||
here. But in fact the opposite can legitimately be true if
|
||||
notifications have been lost. */
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2007, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
import java.security.BasicPermission;
|
||||
|
||||
/**
|
||||
* <p>Permission required by an authentication identity to perform
|
||||
* operations on behalf of an authorization identity.</p>
|
||||
*
|
||||
* <p>A SubjectDelegationPermission contains a name (also referred
|
||||
* to as a "target name") but no actions list; you either have the
|
||||
* named permission or you don't.</p>
|
||||
*
|
||||
* <p>The target name is the name of the authorization principal
|
||||
* classname followed by a period and the authorization principal
|
||||
* name, that is
|
||||
* <code>"<em>PrincipalClassName</em>.<em>PrincipalName</em>"</code>.</p>
|
||||
*
|
||||
* <p>An asterisk may appear by itself, or if immediately preceded
|
||||
* by a "." may appear at the end of the target name, to signify a
|
||||
* wildcard match.</p>
|
||||
*
|
||||
* <p>For example, "*", "javax.management.remote.JMXPrincipal.*" and
|
||||
* "javax.management.remote.JMXPrincipal.delegate" are valid target
|
||||
* names. The first one denotes any principal name from any principal
|
||||
* class, the second one denotes any principal name of the concrete
|
||||
* principal class <code>javax.management.remote.JMXPrincipal</code>
|
||||
* and the third one denotes a concrete principal name
|
||||
* <code>delegate</code> of the concrete principal class
|
||||
* <code>javax.management.remote.JMXPrincipal</code>.</p>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public final class SubjectDelegationPermission extends BasicPermission {
|
||||
|
||||
private static final long serialVersionUID = 1481618113008682343L;
|
||||
|
||||
/**
|
||||
* Creates a new SubjectDelegationPermission with the specified name.
|
||||
* The name is the symbolic name of the SubjectDelegationPermission.
|
||||
*
|
||||
* @param name the name of the SubjectDelegationPermission
|
||||
*
|
||||
* @throws NullPointerException if <code>name</code> is
|
||||
* <code>null</code>.
|
||||
* @throws IllegalArgumentException if <code>name</code> is empty.
|
||||
*/
|
||||
public SubjectDelegationPermission(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new SubjectDelegationPermission object with the
|
||||
* specified name. The name is the symbolic name of the
|
||||
* SubjectDelegationPermission, and the actions String is
|
||||
* currently unused and must be null.
|
||||
*
|
||||
* @param name the name of the SubjectDelegationPermission
|
||||
* @param actions must be null.
|
||||
*
|
||||
* @throws NullPointerException if <code>name</code> is
|
||||
* <code>null</code>.
|
||||
* @throws IllegalArgumentException if <code>name</code> is empty
|
||||
* or <code>actions</code> is not null.
|
||||
*/
|
||||
public SubjectDelegationPermission(String name, String actions) {
|
||||
super(name, actions);
|
||||
|
||||
if (actions != null)
|
||||
throw new IllegalArgumentException("Non-null actions");
|
||||
}
|
||||
}
|
||||
151
jdkSrc/jdk8/javax/management/remote/TargetedNotification.java
Normal file
151
jdkSrc/jdk8/javax/management/remote/TargetedNotification.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package javax.management.remote;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
import javax.management.Notification;
|
||||
|
||||
/**
|
||||
* <p>A (Notification, Listener ID) pair.</p>
|
||||
* <p>This class is used to associate an emitted notification
|
||||
* with the listener ID to which it is targeted.</p>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class TargetedNotification implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 7676132089779300926L;
|
||||
|
||||
// If we replace Integer with int...
|
||||
// /**
|
||||
// * <p>Constructs a <code>TargetedNotification</code> object. The
|
||||
// * object contains a pair (Notification, Listener ID).
|
||||
// * The Listener ID identifies the client listener to which that
|
||||
// * notification is targeted. The client listener ID is one
|
||||
// * previously returned by the connector server in response to an
|
||||
// * <code>addNotificationListener</code> request.</p>
|
||||
// * @param notification Notification emitted from the MBean server.
|
||||
// * @param listenerID The ID of the listener to which this
|
||||
// * notification is targeted.
|
||||
// */
|
||||
// public TargetedNotification(Notification notification,
|
||||
// int listenerID) {
|
||||
// this.notif = notification;
|
||||
// this.id = listenerID;
|
||||
// }
|
||||
|
||||
/**
|
||||
* <p>Constructs a <code>TargetedNotification</code> object. The
|
||||
* object contains a pair (Notification, Listener ID).
|
||||
* The Listener ID identifies the client listener to which that
|
||||
* notification is targeted. The client listener ID is one
|
||||
* previously returned by the connector server in response to an
|
||||
* <code>addNotificationListener</code> request.</p>
|
||||
* @param notification Notification emitted from the MBean server.
|
||||
* @param listenerID The ID of the listener to which this
|
||||
* notification is targeted.
|
||||
* @exception IllegalArgumentException if the <var>listenerID</var>
|
||||
* or <var>notification</var> is null.
|
||||
*/
|
||||
public TargetedNotification(Notification notification,
|
||||
Integer listenerID) {
|
||||
validate(notification, listenerID);
|
||||
// If we replace integer with int...
|
||||
// this(notification,intValue(listenerID));
|
||||
this.notif = notification;
|
||||
this.id = listenerID;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The emitted notification.</p>
|
||||
*
|
||||
* @return The notification.
|
||||
*/
|
||||
public Notification getNotification() {
|
||||
return notif;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The ID of the listener to which the notification is
|
||||
* targeted.</p>
|
||||
*
|
||||
* @return The listener ID.
|
||||
*/
|
||||
public Integer getListenerID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a textual representation of this Targeted Notification.
|
||||
*
|
||||
* @return a String representation of this Targeted Notification.
|
||||
**/
|
||||
public String toString() {
|
||||
return "{" + notif + ", " + id + "}";
|
||||
}
|
||||
|
||||
/**
|
||||
* @serial A notification to transmit to the other side.
|
||||
* @see #getNotification()
|
||||
**/
|
||||
private Notification notif;
|
||||
/**
|
||||
* @serial The ID of the listener to which the notification is
|
||||
* targeted.
|
||||
* @see #getListenerID()
|
||||
**/
|
||||
private Integer id;
|
||||
//private final int id;
|
||||
|
||||
// Needed if we use int instead of Integer...
|
||||
// private static int intValue(Integer id) {
|
||||
// if (id == null) throw new
|
||||
// IllegalArgumentException("Invalid listener ID: null");
|
||||
// return id.intValue();
|
||||
// }
|
||||
|
||||
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
|
||||
ois.defaultReadObject();
|
||||
try {
|
||||
validate(this.notif, this.id);
|
||||
} catch (IllegalArgumentException e) {
|
||||
throw new InvalidObjectException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static void validate(Notification notif, Integer id) throws IllegalArgumentException {
|
||||
if (notif == null) {
|
||||
throw new IllegalArgumentException("Invalid notification: null");
|
||||
}
|
||||
if (id == null) {
|
||||
throw new IllegalArgumentException("Invalid listener ID: null");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.management.remote.rmi;
|
||||
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
/**
|
||||
<p>A class loader that only knows how to define a limited number
|
||||
of classes, and load a limited number of other classes through
|
||||
delegation to another loader. It is used to get around a problem
|
||||
with Serialization, in particular as used by RMI (including
|
||||
RMI/IIOP). The JMX Remote API defines exactly what class loader
|
||||
must be used to deserialize arguments on the server, and return
|
||||
values on the client. We communicate this class loader to RMI by
|
||||
setting it as the context class loader. RMI uses the context
|
||||
class loader to load classes as it deserializes, which is what we
|
||||
want. However, before consulting the context class loader, it
|
||||
looks up the call stack for a class with a non-null class loader,
|
||||
and uses that if it finds one. So, in the standalone version of
|
||||
javax.management.remote, if the class you're looking for is known
|
||||
to the loader of jmxremote.jar (typically the system class loader)
|
||||
then that loader will load it. This contradicts the class-loading
|
||||
semantics required.
|
||||
|
||||
<p>We get around the problem by ensuring that the search up the
|
||||
call stack will find a non-null class loader that doesn't load any
|
||||
classes of interest, namely this one. So even though this loader
|
||||
is indeed consulted during deserialization, it never finds the
|
||||
class being deserialized. RMI then proceeds to use the context
|
||||
class loader, as we require.
|
||||
|
||||
<p>This loader is constructed with the name and byte-code of one
|
||||
or more classes that it defines, and a class-loader to which it
|
||||
will delegate certain other classes required by that byte-code.
|
||||
We construct the byte-code somewhat painstakingly, by compiling
|
||||
the Java code directly, converting into a string, copying that
|
||||
string into the class that needs this loader, and using the
|
||||
stringToBytes method to convert it into the byte array. We
|
||||
compile with -g:none because there's not much point in having
|
||||
line-number information and the like in these directly-encoded
|
||||
classes.
|
||||
|
||||
<p>The referencedClassNames should contain the names of all
|
||||
classes that are referenced by the classes defined by this loader.
|
||||
It is not necessary to include standard J2SE classes, however.
|
||||
Here, a class is referenced if it is the superclass or a
|
||||
superinterface of a defined class, or if it is the type of a
|
||||
field, parameter, or return value. A class is not referenced if
|
||||
it only appears in the throws clause of a method or constructor.
|
||||
Of course, referencedClassNames should not contain any classes
|
||||
that the user might want to deserialize, because the whole point
|
||||
of this loader is that it does not find such classes.
|
||||
*/
|
||||
|
||||
class NoCallStackClassLoader extends ClassLoader {
|
||||
/** Simplified constructor when this loader only defines one class. */
|
||||
public NoCallStackClassLoader(String className,
|
||||
byte[] byteCode,
|
||||
String[] referencedClassNames,
|
||||
ClassLoader referencedClassLoader,
|
||||
ProtectionDomain protectionDomain) {
|
||||
this(new String[] {className}, new byte[][] {byteCode},
|
||||
referencedClassNames, referencedClassLoader, protectionDomain);
|
||||
}
|
||||
|
||||
public NoCallStackClassLoader(String[] classNames,
|
||||
byte[][] byteCodes,
|
||||
String[] referencedClassNames,
|
||||
ClassLoader referencedClassLoader,
|
||||
ProtectionDomain protectionDomain) {
|
||||
super(null);
|
||||
|
||||
/* Validation. */
|
||||
if (classNames == null || classNames.length == 0
|
||||
|| byteCodes == null || classNames.length != byteCodes.length
|
||||
|| referencedClassNames == null || protectionDomain == null)
|
||||
throw new IllegalArgumentException();
|
||||
for (int i = 0; i < classNames.length; i++) {
|
||||
if (classNames[i] == null || byteCodes[i] == null)
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
for (int i = 0; i < referencedClassNames.length; i++) {
|
||||
if (referencedClassNames[i] == null)
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
this.classNames = classNames;
|
||||
this.byteCodes = byteCodes;
|
||||
this.referencedClassNames = referencedClassNames;
|
||||
this.referencedClassLoader = referencedClassLoader;
|
||||
this.protectionDomain = protectionDomain;
|
||||
}
|
||||
|
||||
/* This method is called at most once per name. Define the name
|
||||
* if it is one of the classes whose byte code we have, or
|
||||
* delegate the load if it is one of the referenced classes.
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException {
|
||||
// Note: classNames is guaranteed by the constructor to be non-null.
|
||||
for (int i = 0; i < classNames.length; i++) {
|
||||
if (name.equals(classNames[i])) {
|
||||
return defineClass(classNames[i], byteCodes[i], 0,
|
||||
byteCodes[i].length, protectionDomain);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the referencedClassLoader is null, it is the bootstrap
|
||||
* class loader, and there's no point in delegating to it
|
||||
* because it's already our parent class loader.
|
||||
*/
|
||||
if (referencedClassLoader != null) {
|
||||
for (int i = 0; i < referencedClassNames.length; i++) {
|
||||
if (name.equals(referencedClassNames[i]))
|
||||
return referencedClassLoader.loadClass(name);
|
||||
}
|
||||
}
|
||||
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
|
||||
private final String[] classNames;
|
||||
private final byte[][] byteCodes;
|
||||
private final String[] referencedClassNames;
|
||||
private final ClassLoader referencedClassLoader;
|
||||
private final ProtectionDomain protectionDomain;
|
||||
|
||||
/**
|
||||
* <p>Construct a <code>byte[]</code> using the characters of the
|
||||
* given <code>String</code>. Only the low-order byte of each
|
||||
* character is used. This method is useful to reduce the
|
||||
* footprint of classes that include big byte arrays (e.g. the
|
||||
* byte code of other classes), because a string takes up much
|
||||
* less space in a class file than the byte code to initialize a
|
||||
* <code>byte[]</code> with the same number of bytes.</p>
|
||||
*
|
||||
* <p>We use just one byte per character even though characters
|
||||
* contain two bytes. The resultant output length is much the
|
||||
* same: using one byte per character is shorter because it has
|
||||
* more characters in the optimal 1-127 range but longer because
|
||||
* it has more zero bytes (which are frequent, and are encoded as
|
||||
* two bytes in classfile UTF-8). But one byte per character has
|
||||
* two key advantages: (1) you can see the string constants, which
|
||||
* is reassuring, (2) you don't need to know whether the class
|
||||
* file length is odd.</p>
|
||||
*
|
||||
* <p>This method differs from {@link String#getBytes()} in that
|
||||
* it does not use any encoding. So it is guaranteed that each
|
||||
* byte of the result is numerically identical (mod 256) to the
|
||||
* corresponding character of the input.
|
||||
*/
|
||||
public static byte[] stringToBytes(String s) {
|
||||
final int slen = s.length();
|
||||
byte[] bytes = new byte[slen];
|
||||
for (int i = 0; i < slen; i++)
|
||||
bytes[i] = (byte) s.charAt(i);
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
You can use the following Emacs function to convert class files into
|
||||
strings to be used by the stringToBytes method above. Select the
|
||||
whole (defun...) with the mouse and type M-x eval-region, or save it
|
||||
to a file and do M-x load-file. Then visit the *.class file and do
|
||||
M-x class-string.
|
||||
|
||||
;; class-string.el
|
||||
;; visit the *.class file with emacs, then invoke this function
|
||||
|
||||
(defun class-string ()
|
||||
"Construct a Java string whose bytes are the same as the current
|
||||
buffer. The resultant string is put in a buffer called *string*,
|
||||
possibly with a numeric suffix like <2>. From there it can be
|
||||
insert-buffer'd into a Java program."
|
||||
(interactive)
|
||||
(let* ((s (buffer-string))
|
||||
(slen (length s))
|
||||
(i 0)
|
||||
(buf (generate-new-buffer "*string*")))
|
||||
(set-buffer buf)
|
||||
(insert "\"")
|
||||
(while (< i slen)
|
||||
(if (> (current-column) 61)
|
||||
(insert "\"+\n\""))
|
||||
(let ((c (aref s i)))
|
||||
(insert (cond
|
||||
((> c 126) (format "\\%o" c))
|
||||
((= c ?\") "\\\"")
|
||||
((= c ?\\) "\\\\")
|
||||
((< c 33)
|
||||
(let ((nextc (if (< (1+ i) slen)
|
||||
(aref s (1+ i))
|
||||
?\0)))
|
||||
(cond
|
||||
((and (<= nextc ?7) (>= nextc ?0))
|
||||
(format "\\%03o" c))
|
||||
(t
|
||||
(format "\\%o" c)))))
|
||||
(t c))))
|
||||
(setq i (1+ i)))
|
||||
(insert "\"")
|
||||
(switch-to-buffer buf)))
|
||||
|
||||
Alternatively, the following class reads a class file and outputs a string
|
||||
that can be used by the stringToBytes method above.
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public class BytesToString {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
File f = new File(args[0]);
|
||||
int len = (int)f.length();
|
||||
byte[] classBytes = new byte[len];
|
||||
|
||||
FileInputStream in = new FileInputStream(args[0]);
|
||||
try {
|
||||
int pos = 0;
|
||||
for (;;) {
|
||||
int n = in.read(classBytes, pos, (len-pos));
|
||||
if (n < 0)
|
||||
throw new RuntimeException("class file changed??");
|
||||
pos += n;
|
||||
if (pos >= n)
|
||||
break;
|
||||
}
|
||||
} finally {
|
||||
in.close();
|
||||
}
|
||||
|
||||
int pos = 0;
|
||||
boolean lastWasOctal = false;
|
||||
for (int i=0; i<len; i++) {
|
||||
int value = classBytes[i];
|
||||
if (value < 0)
|
||||
value += 256;
|
||||
String s = null;
|
||||
if (value == '\\')
|
||||
s = "\\\\";
|
||||
else if (value == '\"')
|
||||
s = "\\\"";
|
||||
else {
|
||||
if ((value >= 32 && value < 127) && ((!lastWasOctal ||
|
||||
(value < '0' || value > '7')))) {
|
||||
s = Character.toString((char)value);
|
||||
}
|
||||
}
|
||||
if (s == null) {
|
||||
s = "\\" + Integer.toString(value, 8);
|
||||
lastWasOctal = true;
|
||||
} else {
|
||||
lastWasOctal = false;
|
||||
}
|
||||
if (pos > 61) {
|
||||
System.out.print("\"");
|
||||
if (i<len)
|
||||
System.out.print("+");
|
||||
System.out.println();
|
||||
pos = 0;
|
||||
}
|
||||
if (pos == 0)
|
||||
System.out.print(" \"");
|
||||
System.out.print(s);
|
||||
pos += s.length();
|
||||
}
|
||||
System.out.println("\"");
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
1092
jdkSrc/jdk8/javax/management/remote/rmi/RMIConnection.java
Normal file
1092
jdkSrc/jdk8/javax/management/remote/rmi/RMIConnection.java
Normal file
File diff suppressed because it is too large
Load Diff
1836
jdkSrc/jdk8/javax/management/remote/rmi/RMIConnectionImpl.java
Normal file
1836
jdkSrc/jdk8/javax/management/remote/rmi/RMIConnectionImpl.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,604 @@
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
package javax.management.remote.rmi;
|
||||
|
||||
public final class RMIConnectionImpl_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements javax.management.remote.rmi.RMIConnection
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static java.lang.reflect.Method $method_addNotificationListener_0;
|
||||
private static java.lang.reflect.Method $method_addNotificationListeners_1;
|
||||
private static java.lang.reflect.Method $method_close_2;
|
||||
private static java.lang.reflect.Method $method_createMBean_3;
|
||||
private static java.lang.reflect.Method $method_createMBean_4;
|
||||
private static java.lang.reflect.Method $method_createMBean_5;
|
||||
private static java.lang.reflect.Method $method_createMBean_6;
|
||||
private static java.lang.reflect.Method $method_fetchNotifications_7;
|
||||
private static java.lang.reflect.Method $method_getAttribute_8;
|
||||
private static java.lang.reflect.Method $method_getAttributes_9;
|
||||
private static java.lang.reflect.Method $method_getConnectionId_10;
|
||||
private static java.lang.reflect.Method $method_getDefaultDomain_11;
|
||||
private static java.lang.reflect.Method $method_getDomains_12;
|
||||
private static java.lang.reflect.Method $method_getMBeanCount_13;
|
||||
private static java.lang.reflect.Method $method_getMBeanInfo_14;
|
||||
private static java.lang.reflect.Method $method_getObjectInstance_15;
|
||||
private static java.lang.reflect.Method $method_invoke_16;
|
||||
private static java.lang.reflect.Method $method_isInstanceOf_17;
|
||||
private static java.lang.reflect.Method $method_isRegistered_18;
|
||||
private static java.lang.reflect.Method $method_queryMBeans_19;
|
||||
private static java.lang.reflect.Method $method_queryNames_20;
|
||||
private static java.lang.reflect.Method $method_removeNotificationListener_21;
|
||||
private static java.lang.reflect.Method $method_removeNotificationListener_22;
|
||||
private static java.lang.reflect.Method $method_removeNotificationListeners_23;
|
||||
private static java.lang.reflect.Method $method_setAttribute_24;
|
||||
private static java.lang.reflect.Method $method_setAttributes_25;
|
||||
private static java.lang.reflect.Method $method_unregisterMBean_26;
|
||||
|
||||
static {
|
||||
try {
|
||||
$method_addNotificationListener_0 = javax.management.remote.rmi.RMIConnection.class.getMethod("addNotificationListener", new java.lang.Class[] {javax.management.ObjectName.class, javax.management.ObjectName.class, java.rmi.MarshalledObject.class, java.rmi.MarshalledObject.class, javax.security.auth.Subject.class});
|
||||
$method_addNotificationListeners_1 = javax.management.remote.rmi.RMIConnection.class.getMethod("addNotificationListeners", new java.lang.Class[] {javax.management.ObjectName[].class, java.rmi.MarshalledObject[].class, javax.security.auth.Subject[].class});
|
||||
$method_close_2 = java.lang.AutoCloseable.class.getMethod("close", new java.lang.Class[] {});
|
||||
$method_createMBean_3 = javax.management.remote.rmi.RMIConnection.class.getMethod("createMBean", new java.lang.Class[] {java.lang.String.class, javax.management.ObjectName.class, java.rmi.MarshalledObject.class, java.lang.String[].class, javax.security.auth.Subject.class});
|
||||
$method_createMBean_4 = javax.management.remote.rmi.RMIConnection.class.getMethod("createMBean", new java.lang.Class[] {java.lang.String.class, javax.management.ObjectName.class, javax.management.ObjectName.class, java.rmi.MarshalledObject.class, java.lang.String[].class, javax.security.auth.Subject.class});
|
||||
$method_createMBean_5 = javax.management.remote.rmi.RMIConnection.class.getMethod("createMBean", new java.lang.Class[] {java.lang.String.class, javax.management.ObjectName.class, javax.management.ObjectName.class, javax.security.auth.Subject.class});
|
||||
$method_createMBean_6 = javax.management.remote.rmi.RMIConnection.class.getMethod("createMBean", new java.lang.Class[] {java.lang.String.class, javax.management.ObjectName.class, javax.security.auth.Subject.class});
|
||||
$method_fetchNotifications_7 = javax.management.remote.rmi.RMIConnection.class.getMethod("fetchNotifications", new java.lang.Class[] {long.class, int.class, long.class});
|
||||
$method_getAttribute_8 = javax.management.remote.rmi.RMIConnection.class.getMethod("getAttribute", new java.lang.Class[] {javax.management.ObjectName.class, java.lang.String.class, javax.security.auth.Subject.class});
|
||||
$method_getAttributes_9 = javax.management.remote.rmi.RMIConnection.class.getMethod("getAttributes", new java.lang.Class[] {javax.management.ObjectName.class, java.lang.String[].class, javax.security.auth.Subject.class});
|
||||
$method_getConnectionId_10 = javax.management.remote.rmi.RMIConnection.class.getMethod("getConnectionId", new java.lang.Class[] {});
|
||||
$method_getDefaultDomain_11 = javax.management.remote.rmi.RMIConnection.class.getMethod("getDefaultDomain", new java.lang.Class[] {javax.security.auth.Subject.class});
|
||||
$method_getDomains_12 = javax.management.remote.rmi.RMIConnection.class.getMethod("getDomains", new java.lang.Class[] {javax.security.auth.Subject.class});
|
||||
$method_getMBeanCount_13 = javax.management.remote.rmi.RMIConnection.class.getMethod("getMBeanCount", new java.lang.Class[] {javax.security.auth.Subject.class});
|
||||
$method_getMBeanInfo_14 = javax.management.remote.rmi.RMIConnection.class.getMethod("getMBeanInfo", new java.lang.Class[] {javax.management.ObjectName.class, javax.security.auth.Subject.class});
|
||||
$method_getObjectInstance_15 = javax.management.remote.rmi.RMIConnection.class.getMethod("getObjectInstance", new java.lang.Class[] {javax.management.ObjectName.class, javax.security.auth.Subject.class});
|
||||
$method_invoke_16 = javax.management.remote.rmi.RMIConnection.class.getMethod("invoke", new java.lang.Class[] {javax.management.ObjectName.class, java.lang.String.class, java.rmi.MarshalledObject.class, java.lang.String[].class, javax.security.auth.Subject.class});
|
||||
$method_isInstanceOf_17 = javax.management.remote.rmi.RMIConnection.class.getMethod("isInstanceOf", new java.lang.Class[] {javax.management.ObjectName.class, java.lang.String.class, javax.security.auth.Subject.class});
|
||||
$method_isRegistered_18 = javax.management.remote.rmi.RMIConnection.class.getMethod("isRegistered", new java.lang.Class[] {javax.management.ObjectName.class, javax.security.auth.Subject.class});
|
||||
$method_queryMBeans_19 = javax.management.remote.rmi.RMIConnection.class.getMethod("queryMBeans", new java.lang.Class[] {javax.management.ObjectName.class, java.rmi.MarshalledObject.class, javax.security.auth.Subject.class});
|
||||
$method_queryNames_20 = javax.management.remote.rmi.RMIConnection.class.getMethod("queryNames", new java.lang.Class[] {javax.management.ObjectName.class, java.rmi.MarshalledObject.class, javax.security.auth.Subject.class});
|
||||
$method_removeNotificationListener_21 = javax.management.remote.rmi.RMIConnection.class.getMethod("removeNotificationListener", new java.lang.Class[] {javax.management.ObjectName.class, javax.management.ObjectName.class, java.rmi.MarshalledObject.class, java.rmi.MarshalledObject.class, javax.security.auth.Subject.class});
|
||||
$method_removeNotificationListener_22 = javax.management.remote.rmi.RMIConnection.class.getMethod("removeNotificationListener", new java.lang.Class[] {javax.management.ObjectName.class, javax.management.ObjectName.class, javax.security.auth.Subject.class});
|
||||
$method_removeNotificationListeners_23 = javax.management.remote.rmi.RMIConnection.class.getMethod("removeNotificationListeners", new java.lang.Class[] {javax.management.ObjectName.class, java.lang.Integer[].class, javax.security.auth.Subject.class});
|
||||
$method_setAttribute_24 = javax.management.remote.rmi.RMIConnection.class.getMethod("setAttribute", new java.lang.Class[] {javax.management.ObjectName.class, java.rmi.MarshalledObject.class, javax.security.auth.Subject.class});
|
||||
$method_setAttributes_25 = javax.management.remote.rmi.RMIConnection.class.getMethod("setAttributes", new java.lang.Class[] {javax.management.ObjectName.class, java.rmi.MarshalledObject.class, javax.security.auth.Subject.class});
|
||||
$method_unregisterMBean_26 = javax.management.remote.rmi.RMIConnection.class.getMethod("unregisterMBean", new java.lang.Class[] {javax.management.ObjectName.class, javax.security.auth.Subject.class});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
throw new java.lang.NoSuchMethodError(
|
||||
"stub class initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public RMIConnectionImpl_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of addNotificationListener(ObjectName, ObjectName, MarshalledObject, MarshalledObject, Subject)
|
||||
public void addNotificationListener(javax.management.ObjectName $param_ObjectName_1, javax.management.ObjectName $param_ObjectName_2, java.rmi.MarshalledObject $param_MarshalledObject_3, java.rmi.MarshalledObject $param_MarshalledObject_4, javax.security.auth.Subject $param_Subject_5)
|
||||
throws java.io.IOException, javax.management.InstanceNotFoundException
|
||||
{
|
||||
try {
|
||||
ref.invoke(this, $method_addNotificationListener_0, new java.lang.Object[] {$param_ObjectName_1, $param_ObjectName_2, $param_MarshalledObject_3, $param_MarshalledObject_4, $param_Subject_5}, -8578317696269497109L);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceNotFoundException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of addNotificationListeners(ObjectName[], MarshalledObject[], Subject[])
|
||||
public java.lang.Integer[] addNotificationListeners(javax.management.ObjectName[] $param_arrayOf_ObjectName_1, java.rmi.MarshalledObject[] $param_arrayOf_MarshalledObject_2, javax.security.auth.Subject[] $param_arrayOf_Subject_3)
|
||||
throws java.io.IOException, javax.management.InstanceNotFoundException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_addNotificationListeners_1, new java.lang.Object[] {$param_arrayOf_ObjectName_1, $param_arrayOf_MarshalledObject_2, $param_arrayOf_Subject_3}, -5321691879380783377L);
|
||||
return ((java.lang.Integer[]) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceNotFoundException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of close()
|
||||
public void close()
|
||||
throws java.io.IOException
|
||||
{
|
||||
try {
|
||||
ref.invoke(this, $method_close_2, null, -4742752445160157748L);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of createMBean(String, ObjectName, MarshalledObject, String[], Subject)
|
||||
public javax.management.ObjectInstance createMBean(java.lang.String $param_String_1, javax.management.ObjectName $param_ObjectName_2, java.rmi.MarshalledObject $param_MarshalledObject_3, java.lang.String[] $param_arrayOf_String_4, javax.security.auth.Subject $param_Subject_5)
|
||||
throws java.io.IOException, javax.management.InstanceAlreadyExistsException, javax.management.MBeanException, javax.management.MBeanRegistrationException, javax.management.NotCompliantMBeanException, javax.management.ReflectionException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_createMBean_3, new java.lang.Object[] {$param_String_1, $param_ObjectName_2, $param_MarshalledObject_3, $param_arrayOf_String_4, $param_Subject_5}, 4867822117947806114L);
|
||||
return ((javax.management.ObjectInstance) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceAlreadyExistsException e) {
|
||||
throw e;
|
||||
} catch (javax.management.MBeanException e) {
|
||||
throw e;
|
||||
} catch (javax.management.NotCompliantMBeanException e) {
|
||||
throw e;
|
||||
} catch (javax.management.ReflectionException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of createMBean(String, ObjectName, ObjectName, MarshalledObject, String[], Subject)
|
||||
public javax.management.ObjectInstance createMBean(java.lang.String $param_String_1, javax.management.ObjectName $param_ObjectName_2, javax.management.ObjectName $param_ObjectName_3, java.rmi.MarshalledObject $param_MarshalledObject_4, java.lang.String[] $param_arrayOf_String_5, javax.security.auth.Subject $param_Subject_6)
|
||||
throws java.io.IOException, javax.management.InstanceAlreadyExistsException, javax.management.InstanceNotFoundException, javax.management.MBeanException, javax.management.MBeanRegistrationException, javax.management.NotCompliantMBeanException, javax.management.ReflectionException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_createMBean_4, new java.lang.Object[] {$param_String_1, $param_ObjectName_2, $param_ObjectName_3, $param_MarshalledObject_4, $param_arrayOf_String_5, $param_Subject_6}, -6604955182088909937L);
|
||||
return ((javax.management.ObjectInstance) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceAlreadyExistsException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceNotFoundException e) {
|
||||
throw e;
|
||||
} catch (javax.management.MBeanException e) {
|
||||
throw e;
|
||||
} catch (javax.management.NotCompliantMBeanException e) {
|
||||
throw e;
|
||||
} catch (javax.management.ReflectionException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of createMBean(String, ObjectName, ObjectName, Subject)
|
||||
public javax.management.ObjectInstance createMBean(java.lang.String $param_String_1, javax.management.ObjectName $param_ObjectName_2, javax.management.ObjectName $param_ObjectName_3, javax.security.auth.Subject $param_Subject_4)
|
||||
throws java.io.IOException, javax.management.InstanceAlreadyExistsException, javax.management.InstanceNotFoundException, javax.management.MBeanException, javax.management.MBeanRegistrationException, javax.management.NotCompliantMBeanException, javax.management.ReflectionException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_createMBean_5, new java.lang.Object[] {$param_String_1, $param_ObjectName_2, $param_ObjectName_3, $param_Subject_4}, -8679469989872508324L);
|
||||
return ((javax.management.ObjectInstance) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceAlreadyExistsException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceNotFoundException e) {
|
||||
throw e;
|
||||
} catch (javax.management.MBeanException e) {
|
||||
throw e;
|
||||
} catch (javax.management.NotCompliantMBeanException e) {
|
||||
throw e;
|
||||
} catch (javax.management.ReflectionException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of createMBean(String, ObjectName, Subject)
|
||||
public javax.management.ObjectInstance createMBean(java.lang.String $param_String_1, javax.management.ObjectName $param_ObjectName_2, javax.security.auth.Subject $param_Subject_3)
|
||||
throws java.io.IOException, javax.management.InstanceAlreadyExistsException, javax.management.MBeanException, javax.management.MBeanRegistrationException, javax.management.NotCompliantMBeanException, javax.management.ReflectionException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_createMBean_6, new java.lang.Object[] {$param_String_1, $param_ObjectName_2, $param_Subject_3}, 2510753813974665446L);
|
||||
return ((javax.management.ObjectInstance) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceAlreadyExistsException e) {
|
||||
throw e;
|
||||
} catch (javax.management.MBeanException e) {
|
||||
throw e;
|
||||
} catch (javax.management.NotCompliantMBeanException e) {
|
||||
throw e;
|
||||
} catch (javax.management.ReflectionException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of fetchNotifications(long, int, long)
|
||||
public javax.management.remote.NotificationResult fetchNotifications(long $param_long_1, int $param_int_2, long $param_long_3)
|
||||
throws java.io.IOException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_fetchNotifications_7, new java.lang.Object[] {new java.lang.Long($param_long_1), new java.lang.Integer($param_int_2), new java.lang.Long($param_long_3)}, -5037523307973544478L);
|
||||
return ((javax.management.remote.NotificationResult) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of getAttribute(ObjectName, String, Subject)
|
||||
public java.lang.Object getAttribute(javax.management.ObjectName $param_ObjectName_1, java.lang.String $param_String_2, javax.security.auth.Subject $param_Subject_3)
|
||||
throws java.io.IOException, javax.management.AttributeNotFoundException, javax.management.InstanceNotFoundException, javax.management.MBeanException, javax.management.ReflectionException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_getAttribute_8, new java.lang.Object[] {$param_ObjectName_1, $param_String_2, $param_Subject_3}, -1089783104982388203L);
|
||||
return ((java.lang.Object) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.AttributeNotFoundException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceNotFoundException e) {
|
||||
throw e;
|
||||
} catch (javax.management.MBeanException e) {
|
||||
throw e;
|
||||
} catch (javax.management.ReflectionException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of getAttributes(ObjectName, String[], Subject)
|
||||
public javax.management.AttributeList getAttributes(javax.management.ObjectName $param_ObjectName_1, java.lang.String[] $param_arrayOf_String_2, javax.security.auth.Subject $param_Subject_3)
|
||||
throws java.io.IOException, javax.management.InstanceNotFoundException, javax.management.ReflectionException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_getAttributes_9, new java.lang.Object[] {$param_ObjectName_1, $param_arrayOf_String_2, $param_Subject_3}, 6285293806596348999L);
|
||||
return ((javax.management.AttributeList) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceNotFoundException e) {
|
||||
throw e;
|
||||
} catch (javax.management.ReflectionException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of getConnectionId()
|
||||
public java.lang.String getConnectionId()
|
||||
throws java.io.IOException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_getConnectionId_10, null, -67907180346059933L);
|
||||
return ((java.lang.String) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of getDefaultDomain(Subject)
|
||||
public java.lang.String getDefaultDomain(javax.security.auth.Subject $param_Subject_1)
|
||||
throws java.io.IOException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_getDefaultDomain_11, new java.lang.Object[] {$param_Subject_1}, 6047668923998658472L);
|
||||
return ((java.lang.String) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of getDomains(Subject)
|
||||
public java.lang.String[] getDomains(javax.security.auth.Subject $param_Subject_1)
|
||||
throws java.io.IOException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_getDomains_12, new java.lang.Object[] {$param_Subject_1}, -6662314179953625551L);
|
||||
return ((java.lang.String[]) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of getMBeanCount(Subject)
|
||||
public java.lang.Integer getMBeanCount(javax.security.auth.Subject $param_Subject_1)
|
||||
throws java.io.IOException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_getMBeanCount_13, new java.lang.Object[] {$param_Subject_1}, -2042362057335820635L);
|
||||
return ((java.lang.Integer) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of getMBeanInfo(ObjectName, Subject)
|
||||
public javax.management.MBeanInfo getMBeanInfo(javax.management.ObjectName $param_ObjectName_1, javax.security.auth.Subject $param_Subject_2)
|
||||
throws java.io.IOException, javax.management.InstanceNotFoundException, javax.management.IntrospectionException, javax.management.ReflectionException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_getMBeanInfo_14, new java.lang.Object[] {$param_ObjectName_1, $param_Subject_2}, -7404813916326233354L);
|
||||
return ((javax.management.MBeanInfo) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceNotFoundException e) {
|
||||
throw e;
|
||||
} catch (javax.management.IntrospectionException e) {
|
||||
throw e;
|
||||
} catch (javax.management.ReflectionException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of getObjectInstance(ObjectName, Subject)
|
||||
public javax.management.ObjectInstance getObjectInstance(javax.management.ObjectName $param_ObjectName_1, javax.security.auth.Subject $param_Subject_2)
|
||||
throws java.io.IOException, javax.management.InstanceNotFoundException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_getObjectInstance_15, new java.lang.Object[] {$param_ObjectName_1, $param_Subject_2}, 6950095694996159938L);
|
||||
return ((javax.management.ObjectInstance) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceNotFoundException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of invoke(ObjectName, String, MarshalledObject, String[], Subject)
|
||||
public java.lang.Object invoke(javax.management.ObjectName $param_ObjectName_1, java.lang.String $param_String_2, java.rmi.MarshalledObject $param_MarshalledObject_3, java.lang.String[] $param_arrayOf_String_4, javax.security.auth.Subject $param_Subject_5)
|
||||
throws java.io.IOException, javax.management.InstanceNotFoundException, javax.management.MBeanException, javax.management.ReflectionException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_invoke_16, new java.lang.Object[] {$param_ObjectName_1, $param_String_2, $param_MarshalledObject_3, $param_arrayOf_String_4, $param_Subject_5}, 1434350937885235744L);
|
||||
return ((java.lang.Object) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceNotFoundException e) {
|
||||
throw e;
|
||||
} catch (javax.management.MBeanException e) {
|
||||
throw e;
|
||||
} catch (javax.management.ReflectionException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of isInstanceOf(ObjectName, String, Subject)
|
||||
public boolean isInstanceOf(javax.management.ObjectName $param_ObjectName_1, java.lang.String $param_String_2, javax.security.auth.Subject $param_Subject_3)
|
||||
throws java.io.IOException, javax.management.InstanceNotFoundException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_isInstanceOf_17, new java.lang.Object[] {$param_ObjectName_1, $param_String_2, $param_Subject_3}, -2147516868461740814L);
|
||||
return ((java.lang.Boolean) $result).booleanValue();
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceNotFoundException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of isRegistered(ObjectName, Subject)
|
||||
public boolean isRegistered(javax.management.ObjectName $param_ObjectName_1, javax.security.auth.Subject $param_Subject_2)
|
||||
throws java.io.IOException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_isRegistered_18, new java.lang.Object[] {$param_ObjectName_1, $param_Subject_2}, 8325683335228268564L);
|
||||
return ((java.lang.Boolean) $result).booleanValue();
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of queryMBeans(ObjectName, MarshalledObject, Subject)
|
||||
public java.util.Set queryMBeans(javax.management.ObjectName $param_ObjectName_1, java.rmi.MarshalledObject $param_MarshalledObject_2, javax.security.auth.Subject $param_Subject_3)
|
||||
throws java.io.IOException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_queryMBeans_19, new java.lang.Object[] {$param_ObjectName_1, $param_MarshalledObject_2, $param_Subject_3}, 2915881009400597976L);
|
||||
return ((java.util.Set) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of queryNames(ObjectName, MarshalledObject, Subject)
|
||||
public java.util.Set queryNames(javax.management.ObjectName $param_ObjectName_1, java.rmi.MarshalledObject $param_MarshalledObject_2, javax.security.auth.Subject $param_Subject_3)
|
||||
throws java.io.IOException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_queryNames_20, new java.lang.Object[] {$param_ObjectName_1, $param_MarshalledObject_2, $param_Subject_3}, 9152567528369059802L);
|
||||
return ((java.util.Set) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of removeNotificationListener(ObjectName, ObjectName, MarshalledObject, MarshalledObject, Subject)
|
||||
public void removeNotificationListener(javax.management.ObjectName $param_ObjectName_1, javax.management.ObjectName $param_ObjectName_2, java.rmi.MarshalledObject $param_MarshalledObject_3, java.rmi.MarshalledObject $param_MarshalledObject_4, javax.security.auth.Subject $param_Subject_5)
|
||||
throws java.io.IOException, javax.management.InstanceNotFoundException, javax.management.ListenerNotFoundException
|
||||
{
|
||||
try {
|
||||
ref.invoke(this, $method_removeNotificationListener_21, new java.lang.Object[] {$param_ObjectName_1, $param_ObjectName_2, $param_MarshalledObject_3, $param_MarshalledObject_4, $param_Subject_5}, 2578029900065214857L);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceNotFoundException e) {
|
||||
throw e;
|
||||
} catch (javax.management.ListenerNotFoundException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of removeNotificationListener(ObjectName, ObjectName, Subject)
|
||||
public void removeNotificationListener(javax.management.ObjectName $param_ObjectName_1, javax.management.ObjectName $param_ObjectName_2, javax.security.auth.Subject $param_Subject_3)
|
||||
throws java.io.IOException, javax.management.InstanceNotFoundException, javax.management.ListenerNotFoundException
|
||||
{
|
||||
try {
|
||||
ref.invoke(this, $method_removeNotificationListener_22, new java.lang.Object[] {$param_ObjectName_1, $param_ObjectName_2, $param_Subject_3}, 6604721169198089513L);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceNotFoundException e) {
|
||||
throw e;
|
||||
} catch (javax.management.ListenerNotFoundException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of removeNotificationListeners(ObjectName, Integer[], Subject)
|
||||
public void removeNotificationListeners(javax.management.ObjectName $param_ObjectName_1, java.lang.Integer[] $param_arrayOf_Integer_2, javax.security.auth.Subject $param_Subject_3)
|
||||
throws java.io.IOException, javax.management.InstanceNotFoundException, javax.management.ListenerNotFoundException
|
||||
{
|
||||
try {
|
||||
ref.invoke(this, $method_removeNotificationListeners_23, new java.lang.Object[] {$param_ObjectName_1, $param_arrayOf_Integer_2, $param_Subject_3}, 2549120024456183446L);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceNotFoundException e) {
|
||||
throw e;
|
||||
} catch (javax.management.ListenerNotFoundException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of setAttribute(ObjectName, MarshalledObject, Subject)
|
||||
public void setAttribute(javax.management.ObjectName $param_ObjectName_1, java.rmi.MarshalledObject $param_MarshalledObject_2, javax.security.auth.Subject $param_Subject_3)
|
||||
throws java.io.IOException, javax.management.AttributeNotFoundException, javax.management.InstanceNotFoundException, javax.management.InvalidAttributeValueException, javax.management.MBeanException, javax.management.ReflectionException
|
||||
{
|
||||
try {
|
||||
ref.invoke(this, $method_setAttribute_24, new java.lang.Object[] {$param_ObjectName_1, $param_MarshalledObject_2, $param_Subject_3}, 6738606893952597516L);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.AttributeNotFoundException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceNotFoundException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InvalidAttributeValueException e) {
|
||||
throw e;
|
||||
} catch (javax.management.MBeanException e) {
|
||||
throw e;
|
||||
} catch (javax.management.ReflectionException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of setAttributes(ObjectName, MarshalledObject, Subject)
|
||||
public javax.management.AttributeList setAttributes(javax.management.ObjectName $param_ObjectName_1, java.rmi.MarshalledObject $param_MarshalledObject_2, javax.security.auth.Subject $param_Subject_3)
|
||||
throws java.io.IOException, javax.management.InstanceNotFoundException, javax.management.ReflectionException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_setAttributes_25, new java.lang.Object[] {$param_ObjectName_1, $param_MarshalledObject_2, $param_Subject_3}, -230470228399681820L);
|
||||
return ((javax.management.AttributeList) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceNotFoundException e) {
|
||||
throw e;
|
||||
} catch (javax.management.ReflectionException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of unregisterMBean(ObjectName, Subject)
|
||||
public void unregisterMBean(javax.management.ObjectName $param_ObjectName_1, javax.security.auth.Subject $param_Subject_2)
|
||||
throws java.io.IOException, javax.management.InstanceNotFoundException, javax.management.MBeanRegistrationException
|
||||
{
|
||||
try {
|
||||
ref.invoke(this, $method_unregisterMBean_26, new java.lang.Object[] {$param_ObjectName_1, $param_Subject_2}, -159498580868721452L);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (javax.management.InstanceNotFoundException e) {
|
||||
throw e;
|
||||
} catch (javax.management.MBeanRegistrationException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
2645
jdkSrc/jdk8/javax/management/remote/rmi/RMIConnector.java
Normal file
2645
jdkSrc/jdk8/javax/management/remote/rmi/RMIConnector.java
Normal file
File diff suppressed because it is too large
Load Diff
853
jdkSrc/jdk8/javax/management/remote/rmi/RMIConnectorServer.java
Normal file
853
jdkSrc/jdk8/javax/management/remote/rmi/RMIConnectorServer.java
Normal file
@@ -0,0 +1,853 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.management.remote.rmi;
|
||||
|
||||
|
||||
import com.sun.jmx.remote.security.MBeanServerFileAccessController;
|
||||
import com.sun.jmx.remote.internal.IIOPHelper;
|
||||
import com.sun.jmx.remote.util.ClassLogger;
|
||||
import com.sun.jmx.remote.util.EnvHelp;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.rmi.server.RMIClientSocketFactory;
|
||||
import java.rmi.server.RMIServerSocketFactory;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.management.InstanceNotFoundException;
|
||||
import javax.management.MBeanServer;
|
||||
|
||||
import javax.management.remote.JMXConnectionNotification;
|
||||
import javax.management.remote.JMXConnector;
|
||||
import javax.management.remote.JMXConnectorServer;
|
||||
import javax.management.remote.JMXServiceURL;
|
||||
import javax.management.remote.MBeanServerForwarder;
|
||||
|
||||
import javax.naming.InitialContext;
|
||||
import javax.naming.NamingException;
|
||||
|
||||
/**
|
||||
* <p>A JMX API connector server that creates RMI-based connections
|
||||
* from remote clients. Usually, such connector servers are made
|
||||
* using {@link javax.management.remote.JMXConnectorServerFactory
|
||||
* JMXConnectorServerFactory}. However, specialized applications can
|
||||
* use this class directly, for example with an {@link RMIServerImpl}
|
||||
* object.</p>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class RMIConnectorServer extends JMXConnectorServer {
|
||||
/**
|
||||
* <p>Name of the attribute that specifies whether the {@link
|
||||
* RMIServer} stub that represents an RMI connector server should
|
||||
* override an existing stub at the same address. The value
|
||||
* associated with this attribute, if any, should be a string that
|
||||
* is equal, ignoring case, to <code>"true"</code> or
|
||||
* <code>"false"</code>. The default value is false.</p>
|
||||
*/
|
||||
public static final String JNDI_REBIND_ATTRIBUTE =
|
||||
"jmx.remote.jndi.rebind";
|
||||
|
||||
/**
|
||||
* <p>Name of the attribute that specifies the {@link
|
||||
* RMIClientSocketFactory} for the RMI objects created in
|
||||
* conjunction with this connector. The value associated with this
|
||||
* attribute must be of type <code>RMIClientSocketFactory</code> and can
|
||||
* only be specified in the <code>Map</code> argument supplied when
|
||||
* creating a connector server.</p>
|
||||
*/
|
||||
public static final String RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE =
|
||||
"jmx.remote.rmi.client.socket.factory";
|
||||
|
||||
/**
|
||||
* <p>Name of the attribute that specifies the {@link
|
||||
* RMIServerSocketFactory} for the RMI objects created in
|
||||
* conjunction with this connector. The value associated with this
|
||||
* attribute must be of type <code>RMIServerSocketFactory</code> and can
|
||||
* only be specified in the <code>Map</code> argument supplied when
|
||||
* creating a connector server.</p>
|
||||
*/
|
||||
public static final String RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE =
|
||||
"jmx.remote.rmi.server.socket.factory";
|
||||
|
||||
/**
|
||||
* <p>Makes an <code>RMIConnectorServer</code>.
|
||||
* This is equivalent to calling {@link #RMIConnectorServer(
|
||||
* JMXServiceURL,Map,RMIServerImpl,MBeanServer)
|
||||
* RMIConnectorServer(directoryURL,environment,null,null)}</p>
|
||||
*
|
||||
* @param url the URL defining how to create the connector server.
|
||||
* Cannot be null.
|
||||
*
|
||||
* @param environment attributes governing the creation and
|
||||
* storing of the RMI object. Can be null, which is equivalent to
|
||||
* an empty Map.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>url</code> is null.
|
||||
*
|
||||
* @exception MalformedURLException if <code>url</code> does not
|
||||
* conform to the syntax for an RMI connector, or if its protocol
|
||||
* is not recognized by this implementation. Only "rmi" and "iiop"
|
||||
* are valid when this constructor is used.
|
||||
*
|
||||
* @exception IOException if the connector server cannot be created
|
||||
* for some reason or if it is inevitable that its {@link #start()
|
||||
* start} method will fail.
|
||||
*/
|
||||
public RMIConnectorServer(JMXServiceURL url, Map<String,?> environment)
|
||||
throws IOException {
|
||||
this(url, environment, (MBeanServer) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Makes an <code>RMIConnectorServer</code> for the given MBean
|
||||
* server.
|
||||
* This is equivalent to calling {@link #RMIConnectorServer(
|
||||
* JMXServiceURL,Map,RMIServerImpl,MBeanServer)
|
||||
* RMIConnectorServer(directoryURL,environment,null,mbeanServer)}</p>
|
||||
*
|
||||
* @param url the URL defining how to create the connector server.
|
||||
* Cannot be null.
|
||||
*
|
||||
* @param environment attributes governing the creation and
|
||||
* storing of the RMI object. Can be null, which is equivalent to
|
||||
* an empty Map.
|
||||
*
|
||||
* @param mbeanServer the MBean server to which the new connector
|
||||
* server is attached, or null if it will be attached by being
|
||||
* registered as an MBean in the MBean server.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>url</code> is null.
|
||||
*
|
||||
* @exception MalformedURLException if <code>url</code> does not
|
||||
* conform to the syntax for an RMI connector, or if its protocol
|
||||
* is not recognized by this implementation. Only "rmi" and "iiop"
|
||||
* are valid when this constructor is used.
|
||||
*
|
||||
* @exception IOException if the connector server cannot be created
|
||||
* for some reason or if it is inevitable that its {@link #start()
|
||||
* start} method will fail.
|
||||
*/
|
||||
public RMIConnectorServer(JMXServiceURL url, Map<String,?> environment,
|
||||
MBeanServer mbeanServer)
|
||||
throws IOException {
|
||||
this(url, environment, (RMIServerImpl) null, mbeanServer);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Makes an <code>RMIConnectorServer</code> for the given MBean
|
||||
* server.</p>
|
||||
*
|
||||
* @param url the URL defining how to create the connector server.
|
||||
* Cannot be null.
|
||||
*
|
||||
* @param environment attributes governing the creation and
|
||||
* storing of the RMI object. Can be null, which is equivalent to
|
||||
* an empty Map.
|
||||
*
|
||||
* @param rmiServerImpl An implementation of the RMIServer interface,
|
||||
* consistent with the protocol type specified in <var>url</var>.
|
||||
* If this parameter is non null, the protocol type specified by
|
||||
* <var>url</var> is not constrained, and is assumed to be valid.
|
||||
* Otherwise, only "rmi" and "iiop" will be recognized.
|
||||
*
|
||||
* @param mbeanServer the MBean server to which the new connector
|
||||
* server is attached, or null if it will be attached by being
|
||||
* registered as an MBean in the MBean server.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>url</code> is null.
|
||||
*
|
||||
* @exception MalformedURLException if <code>url</code> does not
|
||||
* conform to the syntax for an RMI connector, or if its protocol
|
||||
* is not recognized by this implementation. Only "rmi" and "iiop"
|
||||
* are recognized when <var>rmiServerImpl</var> is null.
|
||||
*
|
||||
* @exception IOException if the connector server cannot be created
|
||||
* for some reason or if it is inevitable that its {@link #start()
|
||||
* start} method will fail.
|
||||
*
|
||||
* @see #start
|
||||
*/
|
||||
public RMIConnectorServer(JMXServiceURL url, Map<String,?> environment,
|
||||
RMIServerImpl rmiServerImpl,
|
||||
MBeanServer mbeanServer)
|
||||
throws IOException {
|
||||
super(mbeanServer);
|
||||
|
||||
if (url == null) throw new
|
||||
IllegalArgumentException("Null JMXServiceURL");
|
||||
if (rmiServerImpl == null) {
|
||||
final String prt = url.getProtocol();
|
||||
if (prt == null || !(prt.equals("rmi") || prt.equals("iiop"))) {
|
||||
final String msg = "Invalid protocol type: " + prt;
|
||||
throw new MalformedURLException(msg);
|
||||
}
|
||||
final String urlPath = url.getURLPath();
|
||||
if (!urlPath.equals("")
|
||||
&& !urlPath.equals("/")
|
||||
&& !urlPath.startsWith("/jndi/")) {
|
||||
final String msg = "URL path must be empty or start with " +
|
||||
"/jndi/";
|
||||
throw new MalformedURLException(msg);
|
||||
}
|
||||
}
|
||||
|
||||
if (environment == null)
|
||||
this.attributes = Collections.emptyMap();
|
||||
else {
|
||||
EnvHelp.checkAttributes(environment);
|
||||
this.attributes = Collections.unmodifiableMap(environment);
|
||||
}
|
||||
|
||||
this.address = url;
|
||||
this.rmiServerImpl = rmiServerImpl;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns a client stub for this connector server. A client
|
||||
* stub is a serializable object whose {@link
|
||||
* JMXConnector#connect(Map) connect} method can be used to make
|
||||
* one new connection to this connector server.</p>
|
||||
*
|
||||
* @param env client connection parameters of the same sort that
|
||||
* could be provided to {@link JMXConnector#connect(Map)
|
||||
* JMXConnector.connect(Map)}. Can be null, which is equivalent
|
||||
* to an empty map.
|
||||
*
|
||||
* @return a client stub that can be used to make a new connection
|
||||
* to this connector server.
|
||||
*
|
||||
* @exception UnsupportedOperationException if this connector
|
||||
* server does not support the generation of client stubs.
|
||||
*
|
||||
* @exception IllegalStateException if the JMXConnectorServer is
|
||||
* not started (see {@link #isActive()}).
|
||||
*
|
||||
* @exception IOException if a communications problem means that a
|
||||
* stub cannot be created.
|
||||
**/
|
||||
public JMXConnector toJMXConnector(Map<String,?> env) throws IOException {
|
||||
// The serialized for of rmiServerImpl is automatically
|
||||
// a RMI server stub.
|
||||
if (!isActive()) throw new
|
||||
IllegalStateException("Connector is not active");
|
||||
|
||||
// Merge maps
|
||||
Map<String, Object> usemap = new HashMap<String, Object>(
|
||||
(this.attributes==null)?Collections.<String, Object>emptyMap():
|
||||
this.attributes);
|
||||
|
||||
if (env != null) {
|
||||
EnvHelp.checkAttributes(env);
|
||||
usemap.putAll(env);
|
||||
}
|
||||
|
||||
usemap = EnvHelp.filterAttributes(usemap);
|
||||
|
||||
final RMIServer stub=(RMIServer)rmiServerImpl.toStub();
|
||||
|
||||
return new RMIConnector(stub, usemap);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Activates the connector server, that is starts listening for
|
||||
* client connections. Calling this method when the connector
|
||||
* server is already active has no effect. Calling this method
|
||||
* when the connector server has been stopped will generate an
|
||||
* <code>IOException</code>.</p>
|
||||
*
|
||||
* <p>The behavior of this method when called for the first time
|
||||
* depends on the parameters that were supplied at construction,
|
||||
* as described below.</p>
|
||||
*
|
||||
* <p>First, an object of a subclass of {@link RMIServerImpl} is
|
||||
* required, to export the connector server through RMI:</p>
|
||||
*
|
||||
* <ul>
|
||||
*
|
||||
* <li>If an <code>RMIServerImpl</code> was supplied to the
|
||||
* constructor, it is used.
|
||||
*
|
||||
* <li>Otherwise, if the protocol part of the
|
||||
* <code>JMXServiceURL</code> supplied to the constructor was
|
||||
* <code>iiop</code>, an object of type {@link RMIIIOPServerImpl}
|
||||
* is created.
|
||||
*
|
||||
* <li>Otherwise, if the <code>JMXServiceURL</code>
|
||||
* was null, or its protocol part was <code>rmi</code>, an object
|
||||
* of type {@link RMIJRMPServerImpl} is created.
|
||||
*
|
||||
* <li>Otherwise, the implementation can create an
|
||||
* implementation-specific {@link RMIServerImpl} or it can throw
|
||||
* {@link MalformedURLException}.
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* <p>If the given address includes a JNDI directory URL as
|
||||
* specified in the package documentation for {@link
|
||||
* javax.management.remote.rmi}, then this
|
||||
* <code>RMIConnectorServer</code> will bootstrap by binding the
|
||||
* <code>RMIServerImpl</code> to the given address.</p>
|
||||
*
|
||||
* <p>If the URL path part of the <code>JMXServiceURL</code> was
|
||||
* empty or a single slash (<code>/</code>), then the RMI object
|
||||
* will not be bound to a directory. Instead, a reference to it
|
||||
* will be encoded in the URL path of the RMIConnectorServer
|
||||
* address (returned by {@link #getAddress()}). The encodings for
|
||||
* <code>rmi</code> and <code>iiop</code> are described in the
|
||||
* package documentation for {@link
|
||||
* javax.management.remote.rmi}.</p>
|
||||
*
|
||||
* <p>The behavior when the URL path is neither empty nor a JNDI
|
||||
* directory URL, or when the protocol is neither <code>rmi</code>
|
||||
* nor <code>iiop</code>, is implementation defined, and may
|
||||
* include throwing {@link MalformedURLException} when the
|
||||
* connector server is created or when it is started.</p>
|
||||
*
|
||||
* @exception IllegalStateException if the connector server has
|
||||
* not been attached to an MBean server.
|
||||
* @exception IOException if the connector server cannot be
|
||||
* started, or in the case of the {@code iiop} protocol, that
|
||||
* RMI/IIOP is not supported.
|
||||
*/
|
||||
public synchronized void start() throws IOException {
|
||||
final boolean tracing = logger.traceOn();
|
||||
|
||||
if (state == STARTED) {
|
||||
if (tracing) logger.trace("start", "already started");
|
||||
return;
|
||||
} else if (state == STOPPED) {
|
||||
if (tracing) logger.trace("start", "already stopped");
|
||||
throw new IOException("The server has been stopped.");
|
||||
}
|
||||
|
||||
if (getMBeanServer() == null)
|
||||
throw new IllegalStateException("This connector server is not " +
|
||||
"attached to an MBean server");
|
||||
|
||||
// Check the internal access file property to see
|
||||
// if an MBeanServerForwarder is to be provided
|
||||
//
|
||||
if (attributes != null) {
|
||||
// Check if access file property is specified
|
||||
//
|
||||
String accessFile =
|
||||
(String) attributes.get("jmx.remote.x.access.file");
|
||||
if (accessFile != null) {
|
||||
// Access file property specified, create an instance
|
||||
// of the MBeanServerFileAccessController class
|
||||
//
|
||||
MBeanServerForwarder mbsf;
|
||||
try {
|
||||
mbsf = new MBeanServerFileAccessController(accessFile);
|
||||
} catch (IOException e) {
|
||||
throw EnvHelp.initCause(
|
||||
new IllegalArgumentException(e.getMessage()), e);
|
||||
}
|
||||
// Set the MBeanServerForwarder
|
||||
//
|
||||
setMBeanServerForwarder(mbsf);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (tracing) logger.trace("start", "setting default class loader");
|
||||
defaultClassLoader = EnvHelp.resolveServerClassLoader(
|
||||
attributes, getMBeanServer());
|
||||
} catch (InstanceNotFoundException infc) {
|
||||
IllegalArgumentException x = new
|
||||
IllegalArgumentException("ClassLoader not found: "+infc);
|
||||
throw EnvHelp.initCause(x,infc);
|
||||
}
|
||||
|
||||
if (tracing) logger.trace("start", "setting RMIServer object");
|
||||
final RMIServerImpl rmiServer;
|
||||
|
||||
if (rmiServerImpl != null)
|
||||
rmiServer = rmiServerImpl;
|
||||
else
|
||||
rmiServer = newServer();
|
||||
|
||||
rmiServer.setMBeanServer(getMBeanServer());
|
||||
rmiServer.setDefaultClassLoader(defaultClassLoader);
|
||||
rmiServer.setRMIConnectorServer(this);
|
||||
rmiServer.export();
|
||||
|
||||
try {
|
||||
if (tracing) logger.trace("start", "getting RMIServer object to export");
|
||||
final RMIServer objref = objectToBind(rmiServer, attributes);
|
||||
|
||||
if (address != null && address.getURLPath().startsWith("/jndi/")) {
|
||||
final String jndiUrl = address.getURLPath().substring(6);
|
||||
|
||||
if (tracing)
|
||||
logger.trace("start", "Using external directory: " + jndiUrl);
|
||||
|
||||
String stringBoolean = (String) attributes.get(JNDI_REBIND_ATTRIBUTE);
|
||||
final boolean rebind = EnvHelp.computeBooleanFromString( stringBoolean );
|
||||
|
||||
if (tracing)
|
||||
logger.trace("start", JNDI_REBIND_ATTRIBUTE + "=" + rebind);
|
||||
|
||||
try {
|
||||
if (tracing) logger.trace("start", "binding to " + jndiUrl);
|
||||
|
||||
final Hashtable<?, ?> usemap = EnvHelp.mapToHashtable(attributes);
|
||||
|
||||
bind(jndiUrl, usemap, objref, rebind);
|
||||
|
||||
boundJndiUrl = jndiUrl;
|
||||
} catch (NamingException e) {
|
||||
// fit e in the nested exception if we are on 1.4
|
||||
throw newIOException("Cannot bind to URL ["+jndiUrl+"]: "
|
||||
+ e, e);
|
||||
}
|
||||
} else {
|
||||
// if jndiURL is null, we must encode the stub into the URL.
|
||||
if (tracing) logger.trace("start", "Encoding URL");
|
||||
|
||||
encodeStubInAddress(objref, attributes);
|
||||
|
||||
if (tracing) logger.trace("start", "Encoded URL: " + this.address);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
try {
|
||||
rmiServer.close();
|
||||
} catch (Exception x) {
|
||||
// OK: we are already throwing another exception
|
||||
}
|
||||
if (e instanceof RuntimeException)
|
||||
throw (RuntimeException) e;
|
||||
else if (e instanceof IOException)
|
||||
throw (IOException) e;
|
||||
else
|
||||
throw newIOException("Got unexpected exception while " +
|
||||
"starting the connector server: "
|
||||
+ e, e);
|
||||
}
|
||||
|
||||
rmiServerImpl = rmiServer;
|
||||
|
||||
synchronized(openedServers) {
|
||||
openedServers.add(this);
|
||||
}
|
||||
|
||||
state = STARTED;
|
||||
|
||||
if (tracing) {
|
||||
logger.trace("start", "Connector Server Address = " + address);
|
||||
logger.trace("start", "started.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Deactivates the connector server, that is, stops listening for
|
||||
* client connections. Calling this method will also close all
|
||||
* client connections that were made by this server. After this
|
||||
* method returns, whether normally or with an exception, the
|
||||
* connector server will not create any new client
|
||||
* connections.</p>
|
||||
*
|
||||
* <p>Once a connector server has been stopped, it cannot be started
|
||||
* again.</p>
|
||||
*
|
||||
* <p>Calling this method when the connector server has already
|
||||
* been stopped has no effect. Calling this method when the
|
||||
* connector server has not yet been started will disable the
|
||||
* connector server object permanently.</p>
|
||||
*
|
||||
* <p>If closing a client connection produces an exception, that
|
||||
* exception is not thrown from this method. A {@link
|
||||
* JMXConnectionNotification} is emitted from this MBean with the
|
||||
* connection ID of the connection that could not be closed.</p>
|
||||
*
|
||||
* <p>Closing a connector server is a potentially slow operation.
|
||||
* For example, if a client machine with an open connection has
|
||||
* crashed, the close operation might have to wait for a network
|
||||
* protocol timeout. Callers that do not want to block in a close
|
||||
* operation should do it in a separate thread.</p>
|
||||
*
|
||||
* <p>This method calls the method {@link RMIServerImpl#close()
|
||||
* close} on the connector server's <code>RMIServerImpl</code>
|
||||
* object.</p>
|
||||
*
|
||||
* <p>If the <code>RMIServerImpl</code> was bound to a JNDI
|
||||
* directory by the {@link #start() start} method, it is unbound
|
||||
* from the directory by this method.</p>
|
||||
*
|
||||
* @exception IOException if the server cannot be closed cleanly,
|
||||
* or if the <code>RMIServerImpl</code> cannot be unbound from the
|
||||
* directory. When this exception is thrown, the server has
|
||||
* already attempted to close all client connections, if
|
||||
* appropriate; to call {@link RMIServerImpl#close()}; and to
|
||||
* unbind the <code>RMIServerImpl</code> from its directory, if
|
||||
* appropriate. All client connections are closed except possibly
|
||||
* those that generated exceptions when the server attempted to
|
||||
* close them.
|
||||
*/
|
||||
public void stop() throws IOException {
|
||||
final boolean tracing = logger.traceOn();
|
||||
|
||||
synchronized (this) {
|
||||
if (state == STOPPED) {
|
||||
if (tracing) logger.trace("stop","already stopped.");
|
||||
return;
|
||||
} else if (state == CREATED) {
|
||||
if (tracing) logger.trace("stop","not started yet.");
|
||||
}
|
||||
|
||||
if (tracing) logger.trace("stop", "stopping.");
|
||||
state = STOPPED;
|
||||
}
|
||||
|
||||
synchronized(openedServers) {
|
||||
openedServers.remove(this);
|
||||
}
|
||||
|
||||
IOException exception = null;
|
||||
|
||||
// rmiServerImpl can be null if stop() called without start()
|
||||
if (rmiServerImpl != null) {
|
||||
try {
|
||||
if (tracing) logger.trace("stop", "closing RMI server.");
|
||||
rmiServerImpl.close();
|
||||
} catch (IOException e) {
|
||||
if (tracing) logger.trace("stop", "failed to close RMI server: " + e);
|
||||
if (logger.debugOn()) logger.debug("stop",e);
|
||||
exception = e;
|
||||
}
|
||||
}
|
||||
|
||||
if (boundJndiUrl != null) {
|
||||
try {
|
||||
if (tracing)
|
||||
logger.trace("stop",
|
||||
"unbind from external directory: " + boundJndiUrl);
|
||||
|
||||
final Hashtable<?, ?> usemap = EnvHelp.mapToHashtable(attributes);
|
||||
|
||||
InitialContext ctx =
|
||||
new InitialContext(usemap);
|
||||
|
||||
ctx.unbind(boundJndiUrl);
|
||||
|
||||
ctx.close();
|
||||
} catch (NamingException e) {
|
||||
if (tracing) logger.trace("stop", "failed to unbind RMI server: "+e);
|
||||
if (logger.debugOn()) logger.debug("stop",e);
|
||||
// fit e in as the nested exception if we are on 1.4
|
||||
if (exception == null)
|
||||
exception = newIOException("Cannot bind to URL: " + e, e);
|
||||
}
|
||||
}
|
||||
|
||||
if (exception != null) throw exception;
|
||||
|
||||
if (tracing) logger.trace("stop", "stopped");
|
||||
}
|
||||
|
||||
public synchronized boolean isActive() {
|
||||
return (state == STARTED);
|
||||
}
|
||||
|
||||
public JMXServiceURL getAddress() {
|
||||
if (!isActive())
|
||||
return null;
|
||||
return address;
|
||||
}
|
||||
|
||||
public Map<String,?> getAttributes() {
|
||||
Map<String, ?> map = EnvHelp.filterAttributes(attributes);
|
||||
return Collections.unmodifiableMap(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized
|
||||
void setMBeanServerForwarder(MBeanServerForwarder mbsf) {
|
||||
super.setMBeanServerForwarder(mbsf);
|
||||
if (rmiServerImpl != null)
|
||||
rmiServerImpl.setMBeanServer(getMBeanServer());
|
||||
}
|
||||
|
||||
/* We repeat the definitions of connection{Opened,Closed,Failed}
|
||||
here so that they are accessible to other classes in this package
|
||||
even though they have protected access. */
|
||||
|
||||
@Override
|
||||
protected void connectionOpened(String connectionId, String message,
|
||||
Object userData) {
|
||||
super.connectionOpened(connectionId, message, userData);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void connectionClosed(String connectionId, String message,
|
||||
Object userData) {
|
||||
super.connectionClosed(connectionId, message, userData);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void connectionFailed(String connectionId, String message,
|
||||
Object userData) {
|
||||
super.connectionFailed(connectionId, message, userData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Bind a stub to a registry.
|
||||
* @param jndiUrl URL of the stub in the registry, extracted
|
||||
* from the <code>JMXServiceURL</code>.
|
||||
* @param attributes A Hashtable containing environment parameters,
|
||||
* built from the Map specified at this object creation.
|
||||
* @param rmiServer The object to bind in the registry
|
||||
* @param rebind true if the object must be rebound.
|
||||
**/
|
||||
void bind(String jndiUrl, Hashtable<?, ?> attributes,
|
||||
RMIServer rmiServer, boolean rebind)
|
||||
throws NamingException, MalformedURLException {
|
||||
// if jndiURL is not null, we nust bind the stub to a
|
||||
// directory.
|
||||
InitialContext ctx =
|
||||
new InitialContext(attributes);
|
||||
|
||||
if (rebind)
|
||||
ctx.rebind(jndiUrl, rmiServer);
|
||||
else
|
||||
ctx.bind(jndiUrl, rmiServer);
|
||||
ctx.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new RMIServerImpl.
|
||||
**/
|
||||
RMIServerImpl newServer() throws IOException {
|
||||
final boolean iiop = isIiopURL(address,true);
|
||||
final int port;
|
||||
if (address == null)
|
||||
port = 0;
|
||||
else
|
||||
port = address.getPort();
|
||||
if (iiop)
|
||||
return newIIOPServer(attributes);
|
||||
else
|
||||
return newJRMPServer(attributes, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode a stub into the JMXServiceURL.
|
||||
* @param rmiServer The stub object to encode in the URL
|
||||
* @param attributes A Map containing environment parameters,
|
||||
* built from the Map specified at this object creation.
|
||||
**/
|
||||
private void encodeStubInAddress(
|
||||
RMIServer rmiServer, Map<String, ?> attributes)
|
||||
throws IOException {
|
||||
|
||||
final String protocol, host;
|
||||
final int port;
|
||||
|
||||
if (address == null) {
|
||||
if (IIOPHelper.isStub(rmiServer))
|
||||
protocol = "iiop";
|
||||
else
|
||||
protocol = "rmi";
|
||||
host = null; // will default to local host name
|
||||
port = 0;
|
||||
} else {
|
||||
protocol = address.getProtocol();
|
||||
host = (address.getHost().equals("")) ? null : address.getHost();
|
||||
port = address.getPort();
|
||||
}
|
||||
|
||||
final String urlPath = encodeStub(rmiServer, attributes);
|
||||
|
||||
address = new JMXServiceURL(protocol, host, port, urlPath);
|
||||
}
|
||||
|
||||
static boolean isIiopURL(JMXServiceURL directoryURL, boolean strict)
|
||||
throws MalformedURLException {
|
||||
String protocol = directoryURL.getProtocol();
|
||||
if (protocol.equals("rmi"))
|
||||
return false;
|
||||
else if (protocol.equals("iiop"))
|
||||
return true;
|
||||
else if (strict) {
|
||||
|
||||
throw new MalformedURLException("URL must have protocol " +
|
||||
"\"rmi\" or \"iiop\": \"" +
|
||||
protocol + "\"");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the IOR of the given rmiServer.
|
||||
**/
|
||||
static String encodeStub(
|
||||
RMIServer rmiServer, Map<String, ?> env) throws IOException {
|
||||
if (IIOPHelper.isStub(rmiServer))
|
||||
return "/ior/" + encodeIIOPStub(rmiServer, env);
|
||||
else
|
||||
return "/stub/" + encodeJRMPStub(rmiServer, env);
|
||||
}
|
||||
|
||||
static String encodeJRMPStub(
|
||||
RMIServer rmiServer, Map<String, ?> env)
|
||||
throws IOException {
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oout = new ObjectOutputStream(bout);
|
||||
oout.writeObject(rmiServer);
|
||||
oout.close();
|
||||
byte[] bytes = bout.toByteArray();
|
||||
return byteArrayToBase64(bytes);
|
||||
}
|
||||
|
||||
static String encodeIIOPStub(
|
||||
RMIServer rmiServer, Map<String, ?> env)
|
||||
throws IOException {
|
||||
try {
|
||||
Object orb = IIOPHelper.getOrb(rmiServer);
|
||||
return IIOPHelper.objectToString(orb, rmiServer);
|
||||
} catch (RuntimeException x) {
|
||||
throw newIOException(x.getMessage(), x);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Object that we will bind to the registry.
|
||||
* This object is a stub connected to our RMIServerImpl.
|
||||
**/
|
||||
private static RMIServer objectToBind(
|
||||
RMIServerImpl rmiServer, Map<String, ?> env)
|
||||
throws IOException {
|
||||
return RMIConnector.
|
||||
connectStub((RMIServer)rmiServer.toStub(),env);
|
||||
}
|
||||
|
||||
private static RMIServerImpl newJRMPServer(Map<String, ?> env, int port)
|
||||
throws IOException {
|
||||
RMIClientSocketFactory csf = (RMIClientSocketFactory)
|
||||
env.get(RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE);
|
||||
RMIServerSocketFactory ssf = (RMIServerSocketFactory)
|
||||
env.get(RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE);
|
||||
return new RMIJRMPServerImpl(port, csf, ssf, env);
|
||||
}
|
||||
|
||||
private static RMIServerImpl newIIOPServer(Map<String, ?> env)
|
||||
throws IOException {
|
||||
return new RMIIIOPServerImpl(env);
|
||||
}
|
||||
|
||||
private static String byteArrayToBase64(byte[] a) {
|
||||
int aLen = a.length;
|
||||
int numFullGroups = aLen/3;
|
||||
int numBytesInPartialGroup = aLen - 3*numFullGroups;
|
||||
int resultLen = 4*((aLen + 2)/3);
|
||||
final StringBuilder result = new StringBuilder(resultLen);
|
||||
|
||||
// Translate all full groups from byte array elements to Base64
|
||||
int inCursor = 0;
|
||||
for (int i=0; i<numFullGroups; i++) {
|
||||
int byte0 = a[inCursor++] & 0xff;
|
||||
int byte1 = a[inCursor++] & 0xff;
|
||||
int byte2 = a[inCursor++] & 0xff;
|
||||
result.append(intToAlpha[byte0 >> 2]);
|
||||
result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
|
||||
result.append(intToAlpha[(byte1 << 2)&0x3f | (byte2 >> 6)]);
|
||||
result.append(intToAlpha[byte2 & 0x3f]);
|
||||
}
|
||||
|
||||
// Translate partial group if present
|
||||
if (numBytesInPartialGroup != 0) {
|
||||
int byte0 = a[inCursor++] & 0xff;
|
||||
result.append(intToAlpha[byte0 >> 2]);
|
||||
if (numBytesInPartialGroup == 1) {
|
||||
result.append(intToAlpha[(byte0 << 4) & 0x3f]);
|
||||
result.append("==");
|
||||
} else {
|
||||
// assert numBytesInPartialGroup == 2;
|
||||
int byte1 = a[inCursor++] & 0xff;
|
||||
result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
|
||||
result.append(intToAlpha[(byte1 << 2)&0x3f]);
|
||||
result.append('=');
|
||||
}
|
||||
}
|
||||
// assert inCursor == a.length;
|
||||
// assert result.length() == resultLen;
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This array is a lookup table that translates 6-bit positive integer
|
||||
* index values into their "Base64 Alphabet" equivalents as specified
|
||||
* in Table 1 of RFC 2045.
|
||||
*/
|
||||
private static final char intToAlpha[] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
|
||||
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
|
||||
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct a new IOException with a nested exception.
|
||||
* The nested exception is set only if JDK {@literal >= 1.4}
|
||||
*/
|
||||
private static IOException newIOException(String message,
|
||||
Throwable cause) {
|
||||
final IOException x = new IOException(message);
|
||||
return EnvHelp.initCause(x,cause);
|
||||
}
|
||||
|
||||
|
||||
// Private variables
|
||||
// -----------------
|
||||
|
||||
private static ClassLogger logger =
|
||||
new ClassLogger("javax.management.remote.rmi", "RMIConnectorServer");
|
||||
|
||||
private JMXServiceURL address;
|
||||
private RMIServerImpl rmiServerImpl;
|
||||
private final Map<String, ?> attributes;
|
||||
private ClassLoader defaultClassLoader = null;
|
||||
|
||||
private String boundJndiUrl;
|
||||
|
||||
// state
|
||||
private static final int CREATED = 0;
|
||||
private static final int STARTED = 1;
|
||||
private static final int STOPPED = 2;
|
||||
|
||||
private int state = CREATED;
|
||||
private final static Set<RMIConnectorServer> openedServers =
|
||||
new HashSet<RMIConnectorServer>();
|
||||
}
|
||||
164
jdkSrc/jdk8/javax/management/remote/rmi/RMIIIOPServerImpl.java
Normal file
164
jdkSrc/jdk8/javax/management/remote/rmi/RMIIIOPServerImpl.java
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2007, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.management.remote.rmi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.rmi.Remote;
|
||||
import java.security.AccessControlContext;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedActionException;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.util.Map;
|
||||
import java.util.Collections;
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
import com.sun.jmx.remote.internal.IIOPHelper;
|
||||
|
||||
/**
|
||||
* <p>An {@link RMIServerImpl} that is exported through IIOP and that
|
||||
* creates client connections as RMI objects exported through IIOP.
|
||||
* User code does not usually reference this class directly.</p>
|
||||
*
|
||||
* @see RMIServerImpl
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class RMIIIOPServerImpl extends RMIServerImpl {
|
||||
/**
|
||||
* <p>Creates a new {@link RMIServerImpl}.</p>
|
||||
*
|
||||
* @param env the environment containing attributes for the new
|
||||
* <code>RMIServerImpl</code>. Can be null, which is equivalent
|
||||
* to an empty Map.
|
||||
*
|
||||
* @exception IOException if the RMI object cannot be created.
|
||||
*/
|
||||
public RMIIIOPServerImpl(Map<String,?> env)
|
||||
throws IOException {
|
||||
super(env);
|
||||
|
||||
this.env = (env == null) ? Collections.<String, Object>emptyMap() : env;
|
||||
|
||||
callerACC = AccessController.getContext();
|
||||
}
|
||||
|
||||
protected void export() throws IOException {
|
||||
IIOPHelper.exportObject(this);
|
||||
}
|
||||
|
||||
protected String getProtocol() {
|
||||
return "iiop";
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns an IIOP stub.</p>
|
||||
* The stub might not yet be connected to the ORB. The stub will
|
||||
* be serializable only if it is connected to the ORB.
|
||||
* @return an IIOP stub.
|
||||
* @exception IOException if the stub cannot be created - e.g the
|
||||
* RMIIIOPServerImpl has not been exported yet.
|
||||
**/
|
||||
public Remote toStub() throws IOException {
|
||||
// javax.rmi.CORBA.Stub stub =
|
||||
// (javax.rmi.CORBA.Stub) PortableRemoteObject.toStub(this);
|
||||
final Remote stub = IIOPHelper.toStub(this);
|
||||
// java.lang.System.out.println("NON CONNECTED STUB " + stub);
|
||||
// org.omg.CORBA.ORB orb =
|
||||
// org.omg.CORBA.ORB.init((String[])null, (Properties)null);
|
||||
// stub.connect(orb);
|
||||
// java.lang.System.out.println("CONNECTED STUB " + stub);
|
||||
return stub;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a new client connection as an RMI object exported
|
||||
* through IIOP.
|
||||
*
|
||||
* @param connectionId the ID of the new connection. Every
|
||||
* connection opened by this connector server will have a
|
||||
* different ID. The behavior is unspecified if this parameter is
|
||||
* null.
|
||||
*
|
||||
* @param subject the authenticated subject. Can be null.
|
||||
*
|
||||
* @return the newly-created <code>RMIConnection</code>.
|
||||
*
|
||||
* @exception IOException if the new client object cannot be
|
||||
* created or exported.
|
||||
*/
|
||||
protected RMIConnection makeClient(String connectionId, Subject subject)
|
||||
throws IOException {
|
||||
|
||||
if (connectionId == null)
|
||||
throw new NullPointerException("Null connectionId");
|
||||
|
||||
RMIConnection client =
|
||||
new RMIConnectionImpl(this, connectionId, getDefaultClassLoader(),
|
||||
subject, env);
|
||||
IIOPHelper.exportObject(client);
|
||||
return client;
|
||||
}
|
||||
|
||||
protected void closeClient(RMIConnection client) throws IOException {
|
||||
IIOPHelper.unexportObject(client);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Called by {@link #close()} to close the connector server by
|
||||
* unexporting this object. After returning from this method, the
|
||||
* connector server must not accept any new connections.</p>
|
||||
*
|
||||
* @exception IOException if the attempt to close the connector
|
||||
* server failed.
|
||||
*/
|
||||
protected void closeServer() throws IOException {
|
||||
IIOPHelper.unexportObject(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
RMIConnection doNewClient(final Object credentials) throws IOException {
|
||||
if (callerACC == null) {
|
||||
throw new SecurityException("AccessControlContext cannot be null");
|
||||
}
|
||||
try {
|
||||
return AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<RMIConnection>() {
|
||||
public RMIConnection run() throws IOException {
|
||||
return superDoNewClient(credentials);
|
||||
}
|
||||
}, callerACC);
|
||||
} catch (PrivilegedActionException pae) {
|
||||
throw (IOException) pae.getCause();
|
||||
}
|
||||
}
|
||||
|
||||
RMIConnection superDoNewClient(Object credentials) throws IOException {
|
||||
return super.doNewClient(credentials);
|
||||
}
|
||||
|
||||
private final Map<String, ?> env;
|
||||
private final AccessControlContext callerACC;
|
||||
}
|
||||
278
jdkSrc/jdk8/javax/management/remote/rmi/RMIJRMPServerImpl.java
Normal file
278
jdkSrc/jdk8/javax/management/remote/rmi/RMIJRMPServerImpl.java
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2016, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.management.remote.rmi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.rmi.NoSuchObjectException;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.server.RMIClientSocketFactory;
|
||||
import java.rmi.server.RMIServerSocketFactory;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
import java.rmi.server.RemoteObject;
|
||||
import java.util.Map;
|
||||
import java.util.Collections;
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
import com.sun.jmx.remote.internal.RMIExporter;
|
||||
import com.sun.jmx.remote.util.EnvHelp;
|
||||
import java.io.ObjectStreamClass;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import sun.reflect.misc.ReflectUtil;
|
||||
import sun.rmi.server.DeserializationChecker;
|
||||
import sun.rmi.server.UnicastServerRef;
|
||||
import sun.rmi.server.UnicastServerRef2;
|
||||
|
||||
/**
|
||||
* <p>An {@link RMIServer} object that is exported through JRMP and that
|
||||
* creates client connections as RMI objects exported through JRMP.
|
||||
* User code does not usually reference this class directly.</p>
|
||||
*
|
||||
* @see RMIServerImpl
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public class RMIJRMPServerImpl extends RMIServerImpl {
|
||||
|
||||
private final ExportedWrapper exportedWrapper;
|
||||
|
||||
/**
|
||||
* <p>Creates a new {@link RMIServer} object that will be exported
|
||||
* on the given port using the given socket factories.</p>
|
||||
*
|
||||
* @param port the port on which this object and the {@link
|
||||
* RMIConnectionImpl} objects it creates will be exported. Can be
|
||||
* zero, to indicate any available port.
|
||||
*
|
||||
* @param csf the client socket factory for the created RMI
|
||||
* objects. Can be null.
|
||||
*
|
||||
* @param ssf the server socket factory for the created RMI
|
||||
* objects. Can be null.
|
||||
*
|
||||
* @param env the environment map. Can be null.
|
||||
*
|
||||
* @exception IOException if the {@link RMIServer} object
|
||||
* cannot be created.
|
||||
*
|
||||
* @exception IllegalArgumentException if <code>port</code> is
|
||||
* negative.
|
||||
*/
|
||||
public RMIJRMPServerImpl(int port,
|
||||
RMIClientSocketFactory csf,
|
||||
RMIServerSocketFactory ssf,
|
||||
Map<String,?> env)
|
||||
throws IOException {
|
||||
|
||||
super(env);
|
||||
|
||||
if (port < 0)
|
||||
throw new IllegalArgumentException("Negative port: " + port);
|
||||
|
||||
this.port = port;
|
||||
this.csf = csf;
|
||||
this.ssf = ssf;
|
||||
this.env = (env == null) ? Collections.<String, Object>emptyMap() : env;
|
||||
|
||||
String[] credentialsTypes
|
||||
= (String[]) this.env.get(EnvHelp.CREDENTIAL_TYPES);
|
||||
List<String> types = null;
|
||||
if (credentialsTypes != null) {
|
||||
types = new ArrayList<>();
|
||||
for (String type : credentialsTypes) {
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("A credential type is null.");
|
||||
}
|
||||
ReflectUtil.checkPackageAccess(type);
|
||||
types.add(type);
|
||||
}
|
||||
}
|
||||
exportedWrapper = types != null ?
|
||||
new ExportedWrapper(this, types) :
|
||||
null;
|
||||
}
|
||||
|
||||
protected void export() throws IOException {
|
||||
if (exportedWrapper != null) {
|
||||
export(exportedWrapper);
|
||||
} else {
|
||||
export(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void export(Remote obj) throws RemoteException {
|
||||
final RMIExporter exporter =
|
||||
(RMIExporter) env.get(RMIExporter.EXPORTER_ATTRIBUTE);
|
||||
final boolean daemon = EnvHelp.isServerDaemon(env);
|
||||
|
||||
if (daemon && exporter != null) {
|
||||
throw new IllegalArgumentException("If "+EnvHelp.JMX_SERVER_DAEMON+
|
||||
" is specified as true, "+RMIExporter.EXPORTER_ATTRIBUTE+
|
||||
" cannot be used to specify an exporter!");
|
||||
}
|
||||
|
||||
if (daemon) {
|
||||
if (csf == null && ssf == null) {
|
||||
new UnicastServerRef(port).exportObject(obj, null, true);
|
||||
} else {
|
||||
new UnicastServerRef2(port, csf, ssf).exportObject(obj, null, true);
|
||||
}
|
||||
} else if (exporter != null) {
|
||||
exporter.exportObject(obj, port, csf, ssf);
|
||||
} else {
|
||||
UnicastRemoteObject.exportObject(obj, port, csf, ssf);
|
||||
}
|
||||
}
|
||||
|
||||
private void unexport(Remote obj, boolean force)
|
||||
throws NoSuchObjectException {
|
||||
RMIExporter exporter =
|
||||
(RMIExporter) env.get(RMIExporter.EXPORTER_ATTRIBUTE);
|
||||
if (exporter == null)
|
||||
UnicastRemoteObject.unexportObject(obj, force);
|
||||
else
|
||||
exporter.unexportObject(obj, force);
|
||||
}
|
||||
|
||||
protected String getProtocol() {
|
||||
return "rmi";
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Returns a serializable stub for this {@link RMIServer} object.</p>
|
||||
*
|
||||
* @return a serializable stub.
|
||||
*
|
||||
* @exception IOException if the stub cannot be obtained - e.g the
|
||||
* RMIJRMPServerImpl has not been exported yet.
|
||||
*/
|
||||
public Remote toStub() throws IOException {
|
||||
if (exportedWrapper != null) {
|
||||
return RemoteObject.toStub(exportedWrapper);
|
||||
} else {
|
||||
return RemoteObject.toStub(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a new client connection as an RMI object exported
|
||||
* through JRMP. The port and socket factories for the new
|
||||
* {@link RMIConnection} object are the ones supplied
|
||||
* to the <code>RMIJRMPServerImpl</code> constructor.</p>
|
||||
*
|
||||
* @param connectionId the ID of the new connection. Every
|
||||
* connection opened by this connector server will have a
|
||||
* different id. The behavior is unspecified if this parameter is
|
||||
* null.
|
||||
*
|
||||
* @param subject the authenticated subject. Can be null.
|
||||
*
|
||||
* @return the newly-created <code>RMIConnection</code>.
|
||||
*
|
||||
* @exception IOException if the new {@link RMIConnection}
|
||||
* object cannot be created or exported.
|
||||
*/
|
||||
protected RMIConnection makeClient(String connectionId, Subject subject)
|
||||
throws IOException {
|
||||
|
||||
if (connectionId == null)
|
||||
throw new NullPointerException("Null connectionId");
|
||||
|
||||
RMIConnection client =
|
||||
new RMIConnectionImpl(this, connectionId, getDefaultClassLoader(),
|
||||
subject, env);
|
||||
export(client);
|
||||
return client;
|
||||
}
|
||||
|
||||
protected void closeClient(RMIConnection client) throws IOException {
|
||||
unexport(client, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Called by {@link #close()} to close the connector server by
|
||||
* unexporting this object. After returning from this method, the
|
||||
* connector server must not accept any new connections.</p>
|
||||
*
|
||||
* @exception IOException if the attempt to close the connector
|
||||
* server failed.
|
||||
*/
|
||||
protected void closeServer() throws IOException {
|
||||
if (exportedWrapper != null) {
|
||||
unexport(exportedWrapper, true);
|
||||
} else {
|
||||
unexport(this, true);
|
||||
}
|
||||
}
|
||||
|
||||
private final int port;
|
||||
private final RMIClientSocketFactory csf;
|
||||
private final RMIServerSocketFactory ssf;
|
||||
private final Map<String, ?> env;
|
||||
|
||||
private static class ExportedWrapper implements RMIServer, DeserializationChecker {
|
||||
private final RMIServer impl;
|
||||
private final List<String> allowedTypes;
|
||||
private ExportedWrapper(RMIServer impl, List<String> credentialsTypes) {
|
||||
this.impl = impl;
|
||||
allowedTypes = credentialsTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() throws RemoteException {
|
||||
return impl.getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RMIConnection newClient(Object credentials) throws IOException {
|
||||
return impl.newClient(credentials);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check(Method method, ObjectStreamClass descriptor,
|
||||
int paramIndex, int callID) {
|
||||
|
||||
String type = descriptor.getName();
|
||||
if (!allowedTypes.contains(type)) {
|
||||
throw new ClassCastException("Unsupported type: " + type);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkProxyClass(Method method, String[] ifaces,
|
||||
int paramIndex, int callID) {
|
||||
if (ifaces != null && ifaces.length > 0) {
|
||||
for (String iface : ifaces) {
|
||||
if (!allowedTypes.contains(iface)) {
|
||||
throw new ClassCastException("Unsupported type: " + iface);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
91
jdkSrc/jdk8/javax/management/remote/rmi/RMIServer.java
Normal file
91
jdkSrc/jdk8/javax/management/remote/rmi/RMIServer.java
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2007, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.management.remote.rmi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
|
||||
/**
|
||||
* <p>RMI object used to establish connections to an RMI connector.
|
||||
* There is one Remote object implementing this interface for each RMI
|
||||
* connector.</p>
|
||||
*
|
||||
* <p>User code does not usually refer to this interface. It is
|
||||
* specified as part of the public API so that different
|
||||
* implementations of that API will interoperate.</p>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public interface RMIServer extends Remote {
|
||||
/**
|
||||
* <p>The version of the RMI Connector Protocol understood by this
|
||||
* connector server. This is a string with the following format:</p>
|
||||
*
|
||||
* <pre>
|
||||
* <em>protocol-version</em> <em>implementation-name</em>
|
||||
* </pre>
|
||||
*
|
||||
* <p>The <code><em>protocol-version</em></code> is a series of
|
||||
* two or more non-negative integers separated by periods
|
||||
* (<code>.</code>). An implementation of the version described
|
||||
* by this documentation must use the string <code>1.0</code>
|
||||
* here.</p>
|
||||
*
|
||||
* <p>After the protocol version there must be a space, followed
|
||||
* by the implementation name. The format of the implementation
|
||||
* name is unspecified. It is recommended that it include an
|
||||
* implementation version number. An implementation can use an
|
||||
* empty string as its implementation name, for example for
|
||||
* security reasons.</p>
|
||||
*
|
||||
* @return a string with the format described here.
|
||||
*
|
||||
* @exception RemoteException if there is a communication
|
||||
* exception during the remote method call.
|
||||
*/
|
||||
public String getVersion() throws RemoteException;
|
||||
|
||||
/**
|
||||
* <p>Makes a new connection through this RMI connector. Each
|
||||
* remote client calls this method to obtain a new RMI object
|
||||
* representing its connection.</p>
|
||||
*
|
||||
* @param credentials this object specifies the user-defined credentials
|
||||
* to be passed in to the server in order to authenticate the user before
|
||||
* creating the <code>RMIConnection</code>. Can be null.
|
||||
*
|
||||
* @return the newly-created connection object.
|
||||
*
|
||||
* @exception IOException if the new client object cannot be
|
||||
* created or exported, or if there is a communication exception
|
||||
* during the remote method call.
|
||||
*
|
||||
* @exception SecurityException if the given credentials do not
|
||||
* allow the server to authenticate the caller successfully.
|
||||
*/
|
||||
public RMIConnection newClient(Object credentials) throws IOException;
|
||||
}
|
||||
551
jdkSrc/jdk8/javax/management/remote/rmi/RMIServerImpl.java
Normal file
551
jdkSrc/jdk8/javax/management/remote/rmi/RMIServerImpl.java
Normal file
@@ -0,0 +1,551 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.management.remote.rmi;
|
||||
|
||||
import com.sun.jmx.remote.internal.ArrayNotificationBuffer;
|
||||
import com.sun.jmx.remote.internal.NotificationBuffer;
|
||||
import com.sun.jmx.remote.security.JMXPluggableAuthenticator;
|
||||
import com.sun.jmx.remote.util.ClassLogger;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.server.RemoteServer;
|
||||
import java.rmi.server.ServerNotActiveException;
|
||||
import java.security.Principal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.remote.JMXAuthenticator;
|
||||
import javax.management.remote.JMXConnectorServer;
|
||||
import javax.security.auth.Subject;
|
||||
|
||||
/**
|
||||
* <p>An RMI object representing a connector server. Remote clients
|
||||
* can make connections using the {@link #newClient(Object)} method. This
|
||||
* method returns an RMI object representing the connection.</p>
|
||||
*
|
||||
* <p>User code does not usually reference this class directly.
|
||||
* RMI connection servers are usually created with the class {@link
|
||||
* RMIConnectorServer}. Remote clients usually create connections
|
||||
* either with {@link javax.management.remote.JMXConnectorFactory}
|
||||
* or by instantiating {@link RMIConnector}.</p>
|
||||
*
|
||||
* <p>This is an abstract class. Concrete subclasses define the
|
||||
* details of the client connection objects, such as whether they use
|
||||
* JRMP or IIOP.</p>
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public abstract class RMIServerImpl implements Closeable, RMIServer {
|
||||
/**
|
||||
* <p>Constructs a new <code>RMIServerImpl</code>.</p>
|
||||
*
|
||||
* @param env the environment containing attributes for the new
|
||||
* <code>RMIServerImpl</code>. Can be null, which is equivalent
|
||||
* to an empty Map.
|
||||
*/
|
||||
public RMIServerImpl(Map<String,?> env) {
|
||||
this.env = (env == null) ? Collections.<String,Object>emptyMap() : env;
|
||||
}
|
||||
|
||||
void setRMIConnectorServer(RMIConnectorServer connServer)
|
||||
throws IOException {
|
||||
this.connServer = connServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Exports this RMI object.</p>
|
||||
*
|
||||
* @exception IOException if this RMI object cannot be exported.
|
||||
*/
|
||||
protected abstract void export() throws IOException;
|
||||
|
||||
/**
|
||||
* Returns a remotable stub for this server object.
|
||||
* @return a remotable stub.
|
||||
* @exception IOException if the stub cannot be obtained - e.g the
|
||||
* RMIServerImpl has not been exported yet.
|
||||
**/
|
||||
public abstract Remote toStub() throws IOException;
|
||||
|
||||
/**
|
||||
* <p>Sets the default <code>ClassLoader</code> for this connector
|
||||
* server. New client connections will use this classloader.
|
||||
* Existing client connections are unaffected.</p>
|
||||
*
|
||||
* @param cl the new <code>ClassLoader</code> to be used by this
|
||||
* connector server.
|
||||
*
|
||||
* @see #getDefaultClassLoader
|
||||
*/
|
||||
public synchronized void setDefaultClassLoader(ClassLoader cl) {
|
||||
this.cl = cl;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Gets the default <code>ClassLoader</code> used by this connector
|
||||
* server.</p>
|
||||
*
|
||||
* @return the default <code>ClassLoader</code> used by this
|
||||
* connector server.
|
||||
*
|
||||
* @see #setDefaultClassLoader
|
||||
*/
|
||||
public synchronized ClassLoader getDefaultClassLoader() {
|
||||
return cl;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Sets the <code>MBeanServer</code> to which this connector
|
||||
* server is attached. New client connections will interact
|
||||
* with this <code>MBeanServer</code>. Existing client connections are
|
||||
* unaffected.</p>
|
||||
*
|
||||
* @param mbs the new <code>MBeanServer</code>. Can be null, but
|
||||
* new client connections will be refused as long as it is.
|
||||
*
|
||||
* @see #getMBeanServer
|
||||
*/
|
||||
public synchronized void setMBeanServer(MBeanServer mbs) {
|
||||
this.mbeanServer = mbs;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>The <code>MBeanServer</code> to which this connector server
|
||||
* is attached. This is the last value passed to {@link
|
||||
* #setMBeanServer} on this object, or null if that method has
|
||||
* never been called.</p>
|
||||
*
|
||||
* @return the <code>MBeanServer</code> to which this connector
|
||||
* is attached.
|
||||
*
|
||||
* @see #setMBeanServer
|
||||
*/
|
||||
public synchronized MBeanServer getMBeanServer() {
|
||||
return mbeanServer;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
// Expected format is: "protocol-version implementation-name"
|
||||
try {
|
||||
return "1.0 java_runtime_" +
|
||||
System.getProperty("java.runtime.version");
|
||||
} catch (SecurityException e) {
|
||||
return "1.0 ";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a new client connection. This method calls {@link
|
||||
* #makeClient makeClient} and adds the returned client connection
|
||||
* object to an internal list. When this
|
||||
* <code>RMIServerImpl</code> is shut down via its {@link
|
||||
* #close()} method, the {@link RMIConnection#close() close()}
|
||||
* method of each object remaining in the list is called.</p>
|
||||
*
|
||||
* <p>The fact that a client connection object is in this internal
|
||||
* list does not prevent it from being garbage collected.</p>
|
||||
*
|
||||
* @param credentials this object specifies the user-defined
|
||||
* credentials to be passed in to the server in order to
|
||||
* authenticate the caller before creating the
|
||||
* <code>RMIConnection</code>. Can be null.
|
||||
*
|
||||
* @return the newly-created <code>RMIConnection</code>. This is
|
||||
* usually the object created by <code>makeClient</code>, though
|
||||
* an implementation may choose to wrap that object in another
|
||||
* object implementing <code>RMIConnection</code>.
|
||||
*
|
||||
* @exception IOException if the new client object cannot be
|
||||
* created or exported.
|
||||
*
|
||||
* @exception SecurityException if the given credentials do not allow
|
||||
* the server to authenticate the user successfully.
|
||||
*
|
||||
* @exception IllegalStateException if {@link #getMBeanServer()}
|
||||
* is null.
|
||||
*/
|
||||
public RMIConnection newClient(Object credentials) throws IOException {
|
||||
return doNewClient(credentials);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method could be overridden by subclasses defined in this package
|
||||
* to perform additional operations specific to the underlying transport
|
||||
* before creating the new client connection.
|
||||
*/
|
||||
RMIConnection doNewClient(Object credentials) throws IOException {
|
||||
final boolean tracing = logger.traceOn();
|
||||
|
||||
if (tracing) logger.trace("newClient","making new client");
|
||||
|
||||
if (getMBeanServer() == null)
|
||||
throw new IllegalStateException("Not attached to an MBean server");
|
||||
|
||||
Subject subject = null;
|
||||
JMXAuthenticator authenticator =
|
||||
(JMXAuthenticator) env.get(JMXConnectorServer.AUTHENTICATOR);
|
||||
if (authenticator == null) {
|
||||
/*
|
||||
* Create the JAAS-based authenticator only if authentication
|
||||
* has been enabled
|
||||
*/
|
||||
if (env.get("jmx.remote.x.password.file") != null ||
|
||||
env.get("jmx.remote.x.login.config") != null) {
|
||||
authenticator = new JMXPluggableAuthenticator(env);
|
||||
}
|
||||
}
|
||||
if (authenticator != null) {
|
||||
if (tracing) logger.trace("newClient","got authenticator: " +
|
||||
authenticator.getClass().getName());
|
||||
try {
|
||||
subject = authenticator.authenticate(credentials);
|
||||
} catch (SecurityException e) {
|
||||
logger.trace("newClient", "Authentication failed: " + e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (tracing) {
|
||||
if (subject != null)
|
||||
logger.trace("newClient","subject is not null");
|
||||
else logger.trace("newClient","no subject");
|
||||
}
|
||||
|
||||
final String connectionId = makeConnectionId(getProtocol(), subject);
|
||||
|
||||
if (tracing)
|
||||
logger.trace("newClient","making new connection: " + connectionId);
|
||||
|
||||
RMIConnection client = makeClient(connectionId, subject);
|
||||
|
||||
dropDeadReferences();
|
||||
WeakReference<RMIConnection> wr = new WeakReference<RMIConnection>(client);
|
||||
synchronized (clientList) {
|
||||
clientList.add(wr);
|
||||
}
|
||||
|
||||
connServer.connectionOpened(connectionId, "Connection opened", null);
|
||||
|
||||
synchronized (clientList) {
|
||||
if (!clientList.contains(wr)) {
|
||||
// can be removed only by a JMXConnectionNotification listener
|
||||
throw new IOException("The connection is refused.");
|
||||
}
|
||||
}
|
||||
|
||||
if (tracing)
|
||||
logger.trace("newClient","new connection done: " + connectionId );
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Creates a new client connection. This method is called by
|
||||
* the public method {@link #newClient(Object)}.</p>
|
||||
*
|
||||
* @param connectionId the ID of the new connection. Every
|
||||
* connection opened by this connector server will have a
|
||||
* different ID. The behavior is unspecified if this parameter is
|
||||
* null.
|
||||
*
|
||||
* @param subject the authenticated subject. Can be null.
|
||||
*
|
||||
* @return the newly-created <code>RMIConnection</code>.
|
||||
*
|
||||
* @exception IOException if the new client object cannot be
|
||||
* created or exported.
|
||||
*/
|
||||
protected abstract RMIConnection makeClient(String connectionId,
|
||||
Subject subject)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* <p>Closes a client connection made by {@link #makeClient makeClient}.
|
||||
*
|
||||
* @param client a connection previously returned by
|
||||
* <code>makeClient</code> on which the <code>closeClient</code>
|
||||
* method has not previously been called. The behavior is
|
||||
* unspecified if these conditions are violated, including the
|
||||
* case where <code>client</code> is null.
|
||||
*
|
||||
* @exception IOException if the client connection cannot be
|
||||
* closed.
|
||||
*/
|
||||
protected abstract void closeClient(RMIConnection client)
|
||||
throws IOException;
|
||||
|
||||
/**
|
||||
* <p>Returns the protocol string for this object. The string is
|
||||
* <code>rmi</code> for RMI/JRMP and <code>iiop</code> for RMI/IIOP.
|
||||
*
|
||||
* @return the protocol string for this object.
|
||||
*/
|
||||
protected abstract String getProtocol();
|
||||
|
||||
/**
|
||||
* <p>Method called when a client connection created by {@link
|
||||
* #makeClient makeClient} is closed. A subclass that defines
|
||||
* <code>makeClient</code> must arrange for this method to be
|
||||
* called when the resultant object's {@link RMIConnection#close()
|
||||
* close} method is called. This enables it to be removed from
|
||||
* the <code>RMIServerImpl</code>'s list of connections. It is
|
||||
* not an error for <code>client</code> not to be in that
|
||||
* list.</p>
|
||||
*
|
||||
* <p>After removing <code>client</code> from the list of
|
||||
* connections, this method calls {@link #closeClient
|
||||
* closeClient(client)}.</p>
|
||||
*
|
||||
* @param client the client connection that has been closed.
|
||||
*
|
||||
* @exception IOException if {@link #closeClient} throws this
|
||||
* exception.
|
||||
*
|
||||
* @exception NullPointerException if <code>client</code> is null.
|
||||
*/
|
||||
protected void clientClosed(RMIConnection client) throws IOException {
|
||||
final boolean debug = logger.debugOn();
|
||||
|
||||
if (debug) logger.trace("clientClosed","client="+client);
|
||||
|
||||
if (client == null)
|
||||
throw new NullPointerException("Null client");
|
||||
|
||||
synchronized (clientList) {
|
||||
dropDeadReferences();
|
||||
for (Iterator<WeakReference<RMIConnection>> it = clientList.iterator();
|
||||
it.hasNext(); ) {
|
||||
WeakReference<RMIConnection> wr = it.next();
|
||||
if (wr.get() == client) {
|
||||
it.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* It is not a bug for this loop not to find the client. In
|
||||
our close() method, we remove a client from the list before
|
||||
calling its close() method. */
|
||||
}
|
||||
|
||||
if (debug) logger.trace("clientClosed", "closing client.");
|
||||
closeClient(client);
|
||||
|
||||
if (debug) logger.trace("clientClosed", "sending notif");
|
||||
connServer.connectionClosed(client.getConnectionId(),
|
||||
"Client connection closed", null);
|
||||
|
||||
if (debug) logger.trace("clientClosed","done");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Closes this connection server. This method first calls the
|
||||
* {@link #closeServer()} method so that no new client connections
|
||||
* will be accepted. Then, for each remaining {@link
|
||||
* RMIConnection} object returned by {@link #makeClient
|
||||
* makeClient}, its {@link RMIConnection#close() close} method is
|
||||
* called.</p>
|
||||
*
|
||||
* <p>The behavior when this method is called more than once is
|
||||
* unspecified.</p>
|
||||
*
|
||||
* <p>If {@link #closeServer()} throws an
|
||||
* <code>IOException</code>, the individual connections are
|
||||
* nevertheless closed, and then the <code>IOException</code> is
|
||||
* thrown from this method.</p>
|
||||
*
|
||||
* <p>If {@link #closeServer()} returns normally but one or more
|
||||
* of the individual connections throws an
|
||||
* <code>IOException</code>, then, after closing all the
|
||||
* connections, one of those <code>IOException</code>s is thrown
|
||||
* from this method. If more than one connection throws an
|
||||
* <code>IOException</code>, it is unspecified which one is thrown
|
||||
* from this method.</p>
|
||||
*
|
||||
* @exception IOException if {@link #closeServer()} or one of the
|
||||
* {@link RMIConnection#close()} calls threw
|
||||
* <code>IOException</code>.
|
||||
*/
|
||||
public synchronized void close() throws IOException {
|
||||
final boolean tracing = logger.traceOn();
|
||||
final boolean debug = logger.debugOn();
|
||||
|
||||
if (tracing) logger.trace("close","closing");
|
||||
|
||||
IOException ioException = null;
|
||||
try {
|
||||
if (debug) logger.debug("close","closing Server");
|
||||
closeServer();
|
||||
} catch (IOException e) {
|
||||
if (tracing) logger.trace("close","Failed to close server: " + e);
|
||||
if (debug) logger.debug("close",e);
|
||||
ioException = e;
|
||||
}
|
||||
|
||||
if (debug) logger.debug("close","closing Clients");
|
||||
// Loop to close all clients
|
||||
while (true) {
|
||||
synchronized (clientList) {
|
||||
if (debug) logger.debug("close","droping dead references");
|
||||
dropDeadReferences();
|
||||
|
||||
if (debug) logger.debug("close","client count: "+clientList.size());
|
||||
if (clientList.size() == 0)
|
||||
break;
|
||||
/* Loop until we find a non-null client. Because we called
|
||||
dropDeadReferences(), this will usually be the first
|
||||
element of the list, but a garbage collection could have
|
||||
happened in between. */
|
||||
for (Iterator<WeakReference<RMIConnection>> it = clientList.iterator();
|
||||
it.hasNext(); ) {
|
||||
WeakReference<RMIConnection> wr = it.next();
|
||||
RMIConnection client = wr.get();
|
||||
it.remove();
|
||||
if (client != null) {
|
||||
try {
|
||||
client.close();
|
||||
} catch (IOException e) {
|
||||
if (tracing)
|
||||
logger.trace("close","Failed to close client: " + e);
|
||||
if (debug) logger.debug("close",e);
|
||||
if (ioException == null)
|
||||
ioException = e;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(notifBuffer != null)
|
||||
notifBuffer.dispose();
|
||||
|
||||
if (ioException != null) {
|
||||
if (tracing) logger.trace("close","close failed.");
|
||||
throw ioException;
|
||||
}
|
||||
|
||||
if (tracing) logger.trace("close","closed.");
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Called by {@link #close()} to close the connector server.
|
||||
* After returning from this method, the connector server must
|
||||
* not accept any new connections.</p>
|
||||
*
|
||||
* @exception IOException if the attempt to close the connector
|
||||
* server failed.
|
||||
*/
|
||||
protected abstract void closeServer() throws IOException;
|
||||
|
||||
private static synchronized String makeConnectionId(String protocol,
|
||||
Subject subject) {
|
||||
connectionIdNumber++;
|
||||
|
||||
String clientHost = "";
|
||||
try {
|
||||
clientHost = RemoteServer.getClientHost();
|
||||
/*
|
||||
* According to the rules specified in the javax.management.remote
|
||||
* package description, a numeric IPv6 address (detected by the
|
||||
* presence of otherwise forbidden ":" character) forming a part
|
||||
* of the connection id must be enclosed in square brackets.
|
||||
*/
|
||||
if (clientHost.contains(":")) {
|
||||
clientHost = "[" + clientHost + "]";
|
||||
}
|
||||
} catch (ServerNotActiveException e) {
|
||||
logger.trace("makeConnectionId", "getClientHost", e);
|
||||
}
|
||||
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
buf.append(protocol).append(":");
|
||||
if (clientHost.length() > 0)
|
||||
buf.append("//").append(clientHost);
|
||||
buf.append(" ");
|
||||
if (subject != null) {
|
||||
Set<Principal> principals = subject.getPrincipals();
|
||||
String sep = "";
|
||||
for (Iterator<Principal> it = principals.iterator(); it.hasNext(); ) {
|
||||
Principal p = it.next();
|
||||
String name = p.getName().replace(' ', '_').replace(';', ':');
|
||||
buf.append(sep).append(name);
|
||||
sep = ";";
|
||||
}
|
||||
}
|
||||
buf.append(" ").append(connectionIdNumber);
|
||||
if (logger.traceOn())
|
||||
logger.trace("newConnectionId","connectionId="+buf);
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private void dropDeadReferences() {
|
||||
synchronized (clientList) {
|
||||
for (Iterator<WeakReference<RMIConnection>> it = clientList.iterator();
|
||||
it.hasNext(); ) {
|
||||
WeakReference<RMIConnection> wr = it.next();
|
||||
if (wr.get() == null)
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
synchronized NotificationBuffer getNotifBuffer() {
|
||||
//Notification buffer is lazily created when the first client connects
|
||||
if(notifBuffer == null)
|
||||
notifBuffer =
|
||||
ArrayNotificationBuffer.getNotificationBuffer(mbeanServer,
|
||||
env);
|
||||
return notifBuffer;
|
||||
}
|
||||
|
||||
private static final ClassLogger logger =
|
||||
new ClassLogger("javax.management.remote.rmi", "RMIServerImpl");
|
||||
|
||||
/** List of WeakReference values. Each one references an
|
||||
RMIConnection created by this object, or null if the
|
||||
RMIConnection has been garbage-collected. */
|
||||
private final List<WeakReference<RMIConnection>> clientList =
|
||||
new ArrayList<WeakReference<RMIConnection>>();
|
||||
|
||||
private ClassLoader cl;
|
||||
|
||||
private MBeanServer mbeanServer;
|
||||
|
||||
private final Map<String, ?> env;
|
||||
|
||||
private RMIConnectorServer connServer;
|
||||
|
||||
private static int connectionIdNumber;
|
||||
|
||||
private NotificationBuffer notifBuffer;
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
package javax.management.remote.rmi;
|
||||
|
||||
public final class RMIServerImpl_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements javax.management.remote.rmi.RMIServer
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static java.lang.reflect.Method $method_getVersion_0;
|
||||
private static java.lang.reflect.Method $method_newClient_1;
|
||||
|
||||
static {
|
||||
try {
|
||||
$method_getVersion_0 = javax.management.remote.rmi.RMIServer.class.getMethod("getVersion", new java.lang.Class[] {});
|
||||
$method_newClient_1 = javax.management.remote.rmi.RMIServer.class.getMethod("newClient", new java.lang.Class[] {java.lang.Object.class});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
throw new java.lang.NoSuchMethodError(
|
||||
"stub class initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public RMIServerImpl_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of getVersion()
|
||||
public java.lang.String getVersion()
|
||||
throws java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_getVersion_0, null, -8081107751519807347L);
|
||||
return ((java.lang.String) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of newClient(Object)
|
||||
public javax.management.remote.rmi.RMIConnection newClient(java.lang.Object $param_Object_1)
|
||||
throws java.io.IOException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_newClient_1, new java.lang.Object[] {$param_Object_1}, -1089742558549201240L);
|
||||
return ((javax.management.remote.rmi.RMIConnection) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user