mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-06 22:20:47 +00:00
Merge
This commit is contained in:
commit
4138ab60c8
@ -27,7 +27,6 @@ package com.sun.jmx.event;
|
||||
|
||||
import com.sun.jmx.remote.util.ClassLogger;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.FutureTask;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -115,6 +114,7 @@ public class LeaseManager {
|
||||
scheduled = null;
|
||||
}
|
||||
callback.run();
|
||||
executor.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,6 +131,13 @@ public class LeaseManager {
|
||||
logger.trace("stop", "canceling lease");
|
||||
scheduled.cancel(false);
|
||||
scheduled = null;
|
||||
try {
|
||||
executor.shutdown();
|
||||
} catch (SecurityException e) {
|
||||
// OK: caller doesn't have RuntimePermission("modifyThread")
|
||||
// which is unlikely in reality but triggers a test failure otherwise
|
||||
logger.trace("stop", "exception from executor.shutdown", e);
|
||||
}
|
||||
}
|
||||
|
||||
private final Runnable callback;
|
||||
@ -138,7 +145,7 @@ public class LeaseManager {
|
||||
|
||||
private final ScheduledExecutorService executor
|
||||
= Executors.newScheduledThreadPool(1,
|
||||
new DaemonThreadFactory("LeaseManager"));
|
||||
new DaemonThreadFactory("JMX LeaseManager %d"));
|
||||
|
||||
private static final ClassLogger logger =
|
||||
new ClassLogger("javax.management.event", "LeaseManager");
|
||||
|
||||
@ -95,7 +95,9 @@ public abstract class RepeatedSingletonJob implements Runnable {
|
||||
executor.execute(this);
|
||||
} catch (RejectedExecutionException e) {
|
||||
logger.warning(
|
||||
"setEventReceiver", "Executor threw exception", e);
|
||||
"execute",
|
||||
"Executor threw exception (" + this.getClass().getName() + ")",
|
||||
e);
|
||||
throw new RejectedExecutionException(
|
||||
"Executor.execute threw exception -" +
|
||||
"should not be possible", e);
|
||||
|
||||
@ -613,8 +613,7 @@ public class DefaultMBeanServerInterceptor
|
||||
List<String> result = new ArrayList<String>(domains.length);
|
||||
for (int i = 0; i < domains.length; i++) {
|
||||
try {
|
||||
ObjectName dom =
|
||||
Util.newObjectName(domains[i] + ":x=x");
|
||||
ObjectName dom = ObjectName.valueOf(domains[i] + ":x=x");
|
||||
checkMBeanPermission(mbeanServerName, (String) null, null, dom, "getDomains");
|
||||
result.add(domains[i]);
|
||||
} catch (SecurityException e) {
|
||||
@ -1170,7 +1169,7 @@ public class DefaultMBeanServerInterceptor
|
||||
if one is supplied where it shouldn't be). */
|
||||
final String completeName = domain + name;
|
||||
|
||||
return Util.newObjectName(completeName);
|
||||
return ObjectName.valueOf(completeName);
|
||||
}
|
||||
|
||||
public String getDefaultDomain() {
|
||||
@ -2021,7 +2020,7 @@ public class DefaultMBeanServerInterceptor
|
||||
private void addJMXNamespace(JMXNamespace namespace,
|
||||
final ObjectName logicalName,
|
||||
final Queue<Runnable> postQueue) {
|
||||
dispatcher.addNamespace(logicalName, namespace, postQueue);
|
||||
dispatcher.addInterceptorFor(logicalName, namespace, postQueue);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2035,7 +2034,7 @@ public class DefaultMBeanServerInterceptor
|
||||
private void removeJMXNamespace(JMXNamespace namespace,
|
||||
final ObjectName logicalName,
|
||||
final Queue<Runnable> postQueue) {
|
||||
dispatcher.removeNamespace(logicalName, namespace, postQueue);
|
||||
dispatcher.removeInterceptorFor(logicalName, namespace, postQueue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -194,7 +194,7 @@ public abstract class DispatchInterceptor
|
||||
// found in the handlerMap. Note: there doesn't need to be an interceptor
|
||||
// for that key in the Map.
|
||||
//
|
||||
public abstract String getHandlerKey(ObjectName name);
|
||||
abstract String getHandlerKey(ObjectName name);
|
||||
|
||||
// Returns an interceptor for that name, or null if there's no interceptor
|
||||
// for that name.
|
||||
@ -277,7 +277,7 @@ public abstract class DispatchInterceptor
|
||||
// of JMXNamespace (or a subclass of it) is registered as an MBean.
|
||||
// This method is usually invoked from within the repository lock,
|
||||
// hence the necessity of the postRegisterQueue.
|
||||
public void addNamespace(ObjectName name, N jmxNamespace,
|
||||
public void addInterceptorFor(ObjectName name, N jmxNamespace,
|
||||
Queue<Runnable> postRegisterQueue) {
|
||||
final String key = getHandlerKey(name);
|
||||
validateHandlerNameFor(key,name);
|
||||
@ -298,7 +298,7 @@ public abstract class DispatchInterceptor
|
||||
// of JMXNamespace (or a subclass of it) is deregistered.
|
||||
// This method is usually invoked from within the repository lock,
|
||||
// hence the necessity of the postDeregisterQueue.
|
||||
public void removeNamespace(ObjectName name, N jmxNamespace,
|
||||
public void removeInterceptorFor(ObjectName name, N jmxNamespace,
|
||||
Queue<Runnable> postDeregisterQueue) {
|
||||
final String key = getHandlerKey(name);
|
||||
final T ns;
|
||||
@ -330,7 +330,7 @@ public abstract class DispatchInterceptor
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public ObjectInstance createMBean(String className, ObjectName name)
|
||||
public final ObjectInstance createMBean(String className, ObjectName name)
|
||||
throws ReflectionException, InstanceAlreadyExistsException,
|
||||
MBeanRegistrationException, MBeanException,
|
||||
NotCompliantMBeanException {
|
||||
@ -338,7 +338,7 @@ public abstract class DispatchInterceptor
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public ObjectInstance createMBean(String className, ObjectName name,
|
||||
public final ObjectInstance createMBean(String className, ObjectName name,
|
||||
ObjectName loaderName)
|
||||
throws ReflectionException, InstanceAlreadyExistsException,
|
||||
MBeanRegistrationException, MBeanException,
|
||||
@ -347,7 +347,7 @@ public abstract class DispatchInterceptor
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public ObjectInstance createMBean(String className, ObjectName name,
|
||||
public final ObjectInstance createMBean(String className, ObjectName name,
|
||||
Object params[], String signature[])
|
||||
throws ReflectionException, InstanceAlreadyExistsException,
|
||||
MBeanRegistrationException, MBeanException,
|
||||
@ -357,7 +357,7 @@ public abstract class DispatchInterceptor
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public ObjectInstance createMBean(String className, ObjectName name,
|
||||
public final ObjectInstance createMBean(String className, ObjectName name,
|
||||
ObjectName loaderName, Object params[],
|
||||
String signature[])
|
||||
throws ReflectionException, InstanceAlreadyExistsException,
|
||||
@ -368,42 +368,43 @@ public abstract class DispatchInterceptor
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public ObjectInstance registerMBean(Object object, ObjectName name)
|
||||
public final ObjectInstance registerMBean(Object object, ObjectName name)
|
||||
throws InstanceAlreadyExistsException, MBeanRegistrationException,
|
||||
NotCompliantMBeanException {
|
||||
return getInterceptorForCreate(name).registerMBean(object,name);
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public void unregisterMBean(ObjectName name)
|
||||
public final void unregisterMBean(ObjectName name)
|
||||
throws InstanceNotFoundException, MBeanRegistrationException {
|
||||
getInterceptorForInstance(name).unregisterMBean(name);
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public ObjectInstance getObjectInstance(ObjectName name)
|
||||
public final ObjectInstance getObjectInstance(ObjectName name)
|
||||
throws InstanceNotFoundException {
|
||||
return getInterceptorForInstance(name).getObjectInstance(name);
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
|
||||
final QueryInterceptor mbs =
|
||||
public final Set<ObjectInstance> queryMBeans(ObjectName name,
|
||||
QueryExp query) {
|
||||
final QueryInterceptor queryInvoker =
|
||||
getInterceptorForQuery(name);
|
||||
if (mbs == null) return Collections.emptySet();
|
||||
else return mbs.queryMBeans(name,query);
|
||||
if (queryInvoker == null) return Collections.emptySet();
|
||||
else return queryInvoker.queryMBeans(name,query);
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
|
||||
final QueryInterceptor mbs =
|
||||
public final Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
|
||||
final QueryInterceptor queryInvoker =
|
||||
getInterceptorForQuery(name);
|
||||
if (mbs == null) return Collections.emptySet();
|
||||
else return mbs.queryNames(name,query);
|
||||
if (queryInvoker == null) return Collections.emptySet();
|
||||
else return queryInvoker.queryNames(name,query);
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public boolean isRegistered(ObjectName name) {
|
||||
public final boolean isRegistered(ObjectName name) {
|
||||
final MBeanServer mbs = getInterceptorOrNullFor(name);
|
||||
if (mbs == null) return false;
|
||||
else return mbs.isRegistered(name);
|
||||
@ -415,20 +416,21 @@ public abstract class DispatchInterceptor
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public Object getAttribute(ObjectName name, String attribute)
|
||||
public final Object getAttribute(ObjectName name, String attribute)
|
||||
throws MBeanException, AttributeNotFoundException,
|
||||
InstanceNotFoundException, ReflectionException {
|
||||
return getInterceptorForInstance(name).getAttribute(name,attribute);
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public AttributeList getAttributes(ObjectName name, String[] attributes)
|
||||
public final AttributeList getAttributes(ObjectName name,
|
||||
String[] attributes)
|
||||
throws InstanceNotFoundException, ReflectionException {
|
||||
return getInterceptorForInstance(name).getAttributes(name,attributes);
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public void setAttribute(ObjectName name, Attribute attribute)
|
||||
public final void setAttribute(ObjectName name, Attribute attribute)
|
||||
throws InstanceNotFoundException, AttributeNotFoundException,
|
||||
InvalidAttributeValueException, MBeanException,
|
||||
ReflectionException {
|
||||
@ -436,14 +438,14 @@ public abstract class DispatchInterceptor
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public AttributeList setAttributes(ObjectName name,
|
||||
public final AttributeList setAttributes(ObjectName name,
|
||||
AttributeList attributes)
|
||||
throws InstanceNotFoundException, ReflectionException {
|
||||
return getInterceptorForInstance(name).setAttributes(name,attributes);
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public Object invoke(ObjectName name, String operationName,
|
||||
public final Object invoke(ObjectName name, String operationName,
|
||||
Object params[], String signature[])
|
||||
throws InstanceNotFoundException, MBeanException,
|
||||
ReflectionException {
|
||||
@ -463,63 +465,69 @@ public abstract class DispatchInterceptor
|
||||
public abstract String[] getDomains();
|
||||
|
||||
// From MBeanServer
|
||||
public void addNotificationListener(ObjectName name,
|
||||
public final void addNotificationListener(ObjectName name,
|
||||
NotificationListener listener,
|
||||
NotificationFilter filter,
|
||||
Object handback)
|
||||
throws InstanceNotFoundException {
|
||||
getInterceptorForInstance(name).addNotificationListener(name,listener,filter,
|
||||
getInterceptorForInstance(name).
|
||||
addNotificationListener(name,listener,filter,
|
||||
handback);
|
||||
}
|
||||
|
||||
|
||||
// From MBeanServer
|
||||
public void addNotificationListener(ObjectName name,
|
||||
public final void addNotificationListener(ObjectName name,
|
||||
ObjectName listener,
|
||||
NotificationFilter filter,
|
||||
Object handback)
|
||||
throws InstanceNotFoundException {
|
||||
getInterceptorForInstance(name).addNotificationListener(name,listener,filter,
|
||||
getInterceptorForInstance(name).
|
||||
addNotificationListener(name,listener,filter,
|
||||
handback);
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public void removeNotificationListener(ObjectName name,
|
||||
public final void removeNotificationListener(ObjectName name,
|
||||
ObjectName listener)
|
||||
throws InstanceNotFoundException, ListenerNotFoundException {
|
||||
getInterceptorForInstance(name).removeNotificationListener(name,listener);
|
||||
getInterceptorForInstance(name).
|
||||
removeNotificationListener(name,listener);
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public void removeNotificationListener(ObjectName name,
|
||||
public final void removeNotificationListener(ObjectName name,
|
||||
ObjectName listener,
|
||||
NotificationFilter filter,
|
||||
Object handback)
|
||||
throws InstanceNotFoundException, ListenerNotFoundException {
|
||||
getInterceptorForInstance(name).removeNotificationListener(name,listener,filter,
|
||||
getInterceptorForInstance(name).
|
||||
removeNotificationListener(name,listener,filter,
|
||||
handback);
|
||||
}
|
||||
|
||||
|
||||
// From MBeanServer
|
||||
public void removeNotificationListener(ObjectName name,
|
||||
public final void removeNotificationListener(ObjectName name,
|
||||
NotificationListener listener)
|
||||
throws InstanceNotFoundException, ListenerNotFoundException {
|
||||
getInterceptorForInstance(name).removeNotificationListener(name,listener);
|
||||
getInterceptorForInstance(name).
|
||||
removeNotificationListener(name,listener);
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public void removeNotificationListener(ObjectName name,
|
||||
public final void removeNotificationListener(ObjectName name,
|
||||
NotificationListener listener,
|
||||
NotificationFilter filter,
|
||||
Object handback)
|
||||
throws InstanceNotFoundException, ListenerNotFoundException {
|
||||
getInterceptorForInstance(name).removeNotificationListener(name,listener,filter,
|
||||
getInterceptorForInstance(name).
|
||||
removeNotificationListener(name,listener,filter,
|
||||
handback);
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public MBeanInfo getMBeanInfo(ObjectName name)
|
||||
public final MBeanInfo getMBeanInfo(ObjectName name)
|
||||
throws InstanceNotFoundException, IntrospectionException,
|
||||
ReflectionException {
|
||||
return getInterceptorForInstance(name).getMBeanInfo(name);
|
||||
@ -527,21 +535,23 @@ public abstract class DispatchInterceptor
|
||||
|
||||
|
||||
// From MBeanServer
|
||||
public boolean isInstanceOf(ObjectName name, String className)
|
||||
public final boolean isInstanceOf(ObjectName name, String className)
|
||||
throws InstanceNotFoundException {
|
||||
return getInterceptorForInstance(name).isInstanceOf(name,className);
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public ClassLoader getClassLoaderFor(ObjectName mbeanName)
|
||||
public final ClassLoader getClassLoaderFor(ObjectName mbeanName)
|
||||
throws InstanceNotFoundException {
|
||||
return getInterceptorForInstance(mbeanName).getClassLoaderFor(mbeanName);
|
||||
return getInterceptorForInstance(mbeanName).
|
||||
getClassLoaderFor(mbeanName);
|
||||
}
|
||||
|
||||
// From MBeanServer
|
||||
public ClassLoader getClassLoader(ObjectName loaderName)
|
||||
public final ClassLoader getClassLoader(ObjectName loaderName)
|
||||
throws InstanceNotFoundException {
|
||||
return getInterceptorForInstance(loaderName).getClassLoader(loaderName);
|
||||
return getInterceptorForInstance(loaderName).
|
||||
getClassLoader(loaderName);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -75,7 +75,7 @@ class DomainDispatchInterceptor
|
||||
|
||||
private final DomainDispatchInterceptor parent;
|
||||
AggregatingQueryInterceptor(DomainDispatchInterceptor dispatcher) {
|
||||
super(dispatcher.localNamespace);
|
||||
super(dispatcher.nextInterceptor);
|
||||
parent = dispatcher;
|
||||
}
|
||||
|
||||
@ -91,9 +91,8 @@ class DomainDispatchInterceptor
|
||||
// Add all matching MBeans from local namespace.
|
||||
final Set<T> res = Util.cloneSet(local);
|
||||
|
||||
final boolean all = (pattern == null ||
|
||||
pattern.getDomain().equals("*"));
|
||||
if (pattern == null) pattern = ObjectName.WILDCARD;
|
||||
final boolean all = pattern.getDomain().equals("*");
|
||||
|
||||
final String domain = pattern.getDomain();
|
||||
|
||||
@ -142,7 +141,7 @@ class DomainDispatchInterceptor
|
||||
}
|
||||
}
|
||||
|
||||
private final DefaultMBeanServerInterceptor localNamespace;
|
||||
private final DefaultMBeanServerInterceptor nextInterceptor;
|
||||
private final String mbeanServerName;
|
||||
private final MBeanServerDelegate delegate;
|
||||
|
||||
@ -165,7 +164,7 @@ class DomainDispatchInterceptor
|
||||
MBeanInstantiator instantiator,
|
||||
Repository repository,
|
||||
NamespaceDispatchInterceptor namespaces) {
|
||||
localNamespace = new DefaultMBeanServerInterceptor(outer,
|
||||
nextInterceptor = new DefaultMBeanServerInterceptor(outer,
|
||||
delegate, instantiator,repository,namespaces);
|
||||
mbeanServerName = Util.getMBeanServerSecurityName(delegate);
|
||||
this.delegate = delegate;
|
||||
@ -182,7 +181,7 @@ class DomainDispatchInterceptor
|
||||
@Override
|
||||
void validateHandlerNameFor(String key, ObjectName name) {
|
||||
super.validateHandlerNameFor(key,name);
|
||||
final String[] domains = localNamespace.getDomains();
|
||||
final String[] domains = nextInterceptor.getDomains();
|
||||
for (int i=0;i<domains.length;i++) {
|
||||
if (domains[i].equals(key))
|
||||
throw new IllegalArgumentException("domain "+key+
|
||||
@ -192,37 +191,72 @@ class DomainDispatchInterceptor
|
||||
|
||||
@Override
|
||||
final MBeanServer getInterceptorOrNullFor(ObjectName name) {
|
||||
if (name == null) return localNamespace;
|
||||
|
||||
if (name == null) return nextInterceptor;
|
||||
|
||||
final String domain = name.getDomain();
|
||||
if (domain.endsWith(NAMESPACE_SEPARATOR)) return localNamespace;
|
||||
if (domain.contains(NAMESPACE_SEPARATOR)) return null;
|
||||
final String localDomain = domain;
|
||||
if (isLocalHandlerNameFor(localDomain,name)) {
|
||||
if (domain.endsWith(NAMESPACE_SEPARATOR))
|
||||
return nextInterceptor; // This can be a namespace handler.
|
||||
if (domain.contains(NAMESPACE_SEPARATOR))
|
||||
return null; // shouldn't reach here.
|
||||
if (isLocalHandlerNameFor(domain,name)) {
|
||||
// This is the name of a JMXDomain MBean. Return nextInterceptor.
|
||||
LOG.finer("dispatching to local namespace");
|
||||
return localNamespace;
|
||||
return nextInterceptor;
|
||||
}
|
||||
final DomainInterceptor ns = getInterceptor(localDomain);
|
||||
|
||||
final DomainInterceptor ns = getInterceptor(domain);
|
||||
if (ns == null) {
|
||||
// no JMXDomain found for that domain - return nextInterceptor.
|
||||
if (LOG.isLoggable(Level.FINER)) {
|
||||
LOG.finer("dispatching to local namespace: " + localDomain);
|
||||
LOG.finer("dispatching to local namespace: " + domain);
|
||||
}
|
||||
return getNextInterceptor();
|
||||
}
|
||||
|
||||
if (LOG.isLoggable(Level.FINER)) {
|
||||
LOG.finer("dispatching to domain: " + localDomain);
|
||||
LOG.finer("dispatching to domain: " + domain);
|
||||
}
|
||||
return ns;
|
||||
}
|
||||
|
||||
// This method returns true if the given pattern must be evaluated against
|
||||
// several interceptors. This happens when either:
|
||||
//
|
||||
// a) the pattern can select several domains (it's null, or it's a
|
||||
// domain pattern)
|
||||
// or b) it's not a domain pattern, but it might select the name of a
|
||||
// JMXDomain MBean in charge of that domain. Since the JMXDomain
|
||||
// MBean is located in the nextInterceptor, the pattern might need
|
||||
// to be evaluated on two interceptors.
|
||||
//
|
||||
// 1. When this method returns false, the query is evaluated on a single
|
||||
// interceptor:
|
||||
// The interceptor for pattern.getDomain(), if there is one,
|
||||
// or the next interceptor, if there is none.
|
||||
//
|
||||
// 2. When this method returns true, we loop over all the domain
|
||||
// interceptors:
|
||||
// in the list, and if the domain pattern matches the interceptor domain
|
||||
// we evaluate the query on that interceptor and aggregate the results.
|
||||
// Eventually we also evaluate the pattern against the next interceptor.
|
||||
//
|
||||
// See getInterceptorForQuery below.
|
||||
//
|
||||
private boolean multipleQuery(ObjectName pattern) {
|
||||
// case a) above
|
||||
if (pattern == null) return true;
|
||||
if (pattern.isDomainPattern()) return true;
|
||||
|
||||
try {
|
||||
// case b) above.
|
||||
//
|
||||
// This is a bit of a hack. If there's any chance that a JMXDomain
|
||||
// MBean name is selected by the given pattern then we must include
|
||||
// the local namespace in our search.
|
||||
// Returning true will have this effect.
|
||||
//
|
||||
// Returning true will have this effect. see 2. above.
|
||||
//
|
||||
if (pattern.apply(ALL_DOMAINS.withDomain(pattern.getDomain())))
|
||||
return true;
|
||||
} catch (MalformedObjectNameException x) {
|
||||
@ -253,7 +287,7 @@ class DomainDispatchInterceptor
|
||||
// We don't have a virtual domain. Send to local domains.
|
||||
if (LOG.isLoggable(Level.FINER))
|
||||
LOG.finer("dispatching to local namespace: " + domain);
|
||||
return new QueryInterceptor(localNamespace);
|
||||
return new QueryInterceptor(nextInterceptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -288,7 +322,7 @@ class DomainDispatchInterceptor
|
||||
|
||||
@Override
|
||||
final DefaultMBeanServerInterceptor getNextInterceptor() {
|
||||
return localNamespace;
|
||||
return nextInterceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -298,11 +332,11 @@ class DomainDispatchInterceptor
|
||||
@Override
|
||||
public String[] getDomains() {
|
||||
// A JMXDomain is registered in its own domain.
|
||||
// Therefore, localNamespace.getDomains() contains all domains.
|
||||
// In addition, localNamespace will perform the necessary
|
||||
// Therefore, nextInterceptor.getDomains() contains all domains.
|
||||
// In addition, nextInterceptor will perform the necessary
|
||||
// MBeanPermission checks for getDomains().
|
||||
//
|
||||
return localNamespace.getDomains();
|
||||
return nextInterceptor.getDomains();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -310,13 +344,13 @@ class DomainDispatchInterceptor
|
||||
*/
|
||||
@Override
|
||||
public Integer getMBeanCount() {
|
||||
int count = getNextInterceptor().getMBeanCount().intValue();
|
||||
int count = getNextInterceptor().getMBeanCount();
|
||||
final String[] keys = getKeys();
|
||||
for (String key:keys) {
|
||||
final MBeanServer mbs = getInterceptor(key);
|
||||
if (mbs == null) continue;
|
||||
count += mbs.getMBeanCount().intValue();
|
||||
count += mbs.getMBeanCount();
|
||||
}
|
||||
return Integer.valueOf(count);
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,7 +61,7 @@ public class NamespaceDispatchInterceptor
|
||||
private static final int NAMESPACE_SEPARATOR_LENGTH =
|
||||
NAMESPACE_SEPARATOR.length();
|
||||
|
||||
private final DomainDispatchInterceptor localNamespace;
|
||||
private final DomainDispatchInterceptor nextInterceptor;
|
||||
private final String serverName;
|
||||
|
||||
/**
|
||||
@ -84,7 +84,7 @@ public class NamespaceDispatchInterceptor
|
||||
MBeanServerDelegate delegate,
|
||||
MBeanInstantiator instantiator,
|
||||
Repository repository) {
|
||||
localNamespace = new DomainDispatchInterceptor(outer,delegate,
|
||||
nextInterceptor = new DomainDispatchInterceptor(outer,delegate,
|
||||
instantiator,repository,this);
|
||||
serverName = Util.getMBeanServerSecurityName(delegate);
|
||||
}
|
||||
@ -94,21 +94,21 @@ public class NamespaceDispatchInterceptor
|
||||
* Get first name space in ObjectName path. Ignore leading namespace
|
||||
* separators.
|
||||
**/
|
||||
public static String getFirstNamespace(ObjectName name) {
|
||||
static String getFirstNamespace(ObjectName name) {
|
||||
if (name == null) return "";
|
||||
final String domain = name.getDomain();
|
||||
if (domain.equals("")) return "";
|
||||
|
||||
// skip leading separators
|
||||
int first = 0;
|
||||
int end = domain.indexOf(NAMESPACE_SEPARATOR,first);
|
||||
while (end == first) {
|
||||
first = end+NAMESPACE_SEPARATOR_LENGTH;
|
||||
end = domain.indexOf(NAMESPACE_SEPARATOR,first);
|
||||
if (end == -1) break;
|
||||
}
|
||||
while (domain.startsWith(NAMESPACE_SEPARATOR,first))
|
||||
first += NAMESPACE_SEPARATOR_LENGTH;
|
||||
|
||||
if (end == -1) return "";
|
||||
// go to next separator
|
||||
final int end = domain.indexOf(NAMESPACE_SEPARATOR,first);
|
||||
if (end == -1) return ""; // no namespace
|
||||
|
||||
// This is the first element in the namespace path.
|
||||
final String namespace = domain.substring(first,end);
|
||||
|
||||
return namespace;
|
||||
@ -143,7 +143,7 @@ public class NamespaceDispatchInterceptor
|
||||
if (namespace.equals("") || isLocalHandlerNameFor(namespace,name) ||
|
||||
name.getDomain().equals(namespace+NAMESPACE_SEPARATOR)) {
|
||||
LOG.finer("dispatching to local name space");
|
||||
return localNamespace;
|
||||
return nextInterceptor;
|
||||
}
|
||||
final NamespaceInterceptor ns = getInterceptor(namespace);
|
||||
if (LOG.isLoggable(Level.FINER)) {
|
||||
@ -162,7 +162,7 @@ public class NamespaceDispatchInterceptor
|
||||
if (namespace.equals("") || isLocalHandlerNameFor(namespace,pattern) ||
|
||||
pattern.getDomain().equals(namespace+NAMESPACE_SEPARATOR)) {
|
||||
LOG.finer("dispatching to local name space");
|
||||
return new QueryInterceptor(localNamespace);
|
||||
return new QueryInterceptor(nextInterceptor);
|
||||
}
|
||||
final NamespaceInterceptor ns = getInterceptor(namespace);
|
||||
if (LOG.isLoggable(Level.FINER)) {
|
||||
@ -202,7 +202,7 @@ public class NamespaceDispatchInterceptor
|
||||
|
||||
@Override
|
||||
final DomainDispatchInterceptor getNextInterceptor() {
|
||||
return localNamespace;
|
||||
return nextInterceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -211,25 +211,25 @@ public class NamespaceDispatchInterceptor
|
||||
*/
|
||||
@Override
|
||||
public String[] getDomains() {
|
||||
return localNamespace.getDomains();
|
||||
return nextInterceptor.getDomains();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addNamespace(ObjectName name, JMXNamespace handler,
|
||||
public void addInterceptorFor(ObjectName name, JMXNamespace handler,
|
||||
Queue<Runnable> postRegisterQueue) {
|
||||
if (handler instanceof JMXDomain)
|
||||
localNamespace.addNamespace(name,
|
||||
nextInterceptor.addInterceptorFor(name,
|
||||
(JMXDomain)handler,postRegisterQueue);
|
||||
else super.addNamespace(name,handler,postRegisterQueue);
|
||||
else super.addInterceptorFor(name,handler,postRegisterQueue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeNamespace(ObjectName name, JMXNamespace handler,
|
||||
public void removeInterceptorFor(ObjectName name, JMXNamespace handler,
|
||||
Queue<Runnable> postDeregisterQueue) {
|
||||
if (handler instanceof JMXDomain)
|
||||
localNamespace.removeNamespace(name,(JMXDomain)handler,
|
||||
nextInterceptor.removeInterceptorFor(name,(JMXDomain)handler,
|
||||
postDeregisterQueue);
|
||||
else super.removeNamespace(name,handler,postDeregisterQueue);
|
||||
else super.removeInterceptorFor(name,handler,postDeregisterQueue);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1172,10 +1172,10 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
||||
final Class<ConstructorProperties> propertyNamesClass = ConstructorProperties.class;
|
||||
|
||||
Class targetClass = getTargetClass();
|
||||
Constructor[] constrs = targetClass.getConstructors();
|
||||
Constructor<?>[] constrs = targetClass.getConstructors();
|
||||
|
||||
// Applicable if and only if there are any annotated constructors
|
||||
List<Constructor> annotatedConstrList = newList();
|
||||
List<Constructor<?>> annotatedConstrList = newList();
|
||||
for (Constructor<?> constr : constrs) {
|
||||
if (Modifier.isPublic(constr.getModifiers())
|
||||
&& constr.getAnnotation(propertyNamesClass) != null)
|
||||
@ -1206,7 +1206,7 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
||||
// Also remember the set of properties in that constructor
|
||||
// so we can test unambiguity.
|
||||
Set<BitSet> getterIndexSets = newSet();
|
||||
for (Constructor constr : annotatedConstrList) {
|
||||
for (Constructor<?> constr : annotatedConstrList) {
|
||||
String[] propertyNames =
|
||||
constr.getAnnotation(propertyNamesClass).value();
|
||||
|
||||
@ -1363,10 +1363,10 @@ public class DefaultMXBeanMappingFactory extends MXBeanMappingFactory {
|
||||
}
|
||||
|
||||
private static class Constr {
|
||||
final Constructor constructor;
|
||||
final Constructor<?> constructor;
|
||||
final int[] paramIndexes;
|
||||
final BitSet presentParams;
|
||||
Constr(Constructor constructor, int[] paramIndexes,
|
||||
Constr(Constructor<?> constructor, int[] paramIndexes,
|
||||
BitSet presentParams) {
|
||||
this.constructor = constructor;
|
||||
this.paramIndexes = paramIndexes;
|
||||
|
||||
@ -623,7 +623,7 @@ abstract class MBeanIntrospector<M> {
|
||||
}
|
||||
|
||||
private static MBeanConstructorInfo[] findConstructors(Class<?> c) {
|
||||
Constructor[] cons = c.getConstructors();
|
||||
Constructor<?>[] cons = c.getConstructors();
|
||||
MBeanConstructorInfo[] mbc = new MBeanConstructorInfo[cons.length];
|
||||
for (int i = 0; i < cons.length; i++) {
|
||||
String descr = "Public constructor of the MBean";
|
||||
|
||||
@ -396,7 +396,7 @@ public class Repository {
|
||||
|
||||
// Set domain to default if domain is empty and not already set
|
||||
if (dom.length() == 0)
|
||||
name = Util.newObjectName(domain + name.toString());
|
||||
name = ObjectName.valueOf(domain + name.toString());
|
||||
|
||||
// Do we have default domain ?
|
||||
if (dom == domain) { // ES: OK (dom & domain are interned)
|
||||
|
||||
@ -57,7 +57,8 @@ import static javax.management.namespace.JMXNamespaces.NAMESPACE_SEPARATOR;
|
||||
public class Util {
|
||||
private final static int NAMESPACE_SEPARATOR_LENGTH =
|
||||
NAMESPACE_SEPARATOR.length();
|
||||
public final static String ILLEGAL_MBEANSERVER_NAME_CHARS=";:*?";
|
||||
public final static char[] ILLEGAL_MBEANSERVER_NAME_CHARS=";:*?".
|
||||
toCharArray();
|
||||
|
||||
|
||||
static <K, V> Map<K, V> newMap() {
|
||||
@ -109,14 +110,6 @@ public class Util {
|
||||
return new ArrayList<E>(c);
|
||||
}
|
||||
|
||||
public static ObjectName newObjectName(String s) {
|
||||
try {
|
||||
return new ObjectName(s);
|
||||
} catch (MalformedObjectNameException e) {
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/* This method can be used by code that is deliberately violating the
|
||||
* allowed checked casts. Rather than marking the whole method containing
|
||||
* the code with @SuppressWarnings, you can use a call to this method for
|
||||
@ -621,7 +614,7 @@ public class Util {
|
||||
* is {@code null}.
|
||||
* @throws IllegalArgumentException if mbeanServerName contains illegal
|
||||
* characters, or is empty, or is {@code "-"}.
|
||||
* Illegal characters are {@value #ILLEGAL_MBEANSERVER_NAME_CHARS}.
|
||||
* Illegal characters are {@link #ILLEGAL_MBEANSERVER_NAME_CHARS}.
|
||||
*/
|
||||
public static String checkServerName(String mbeanServerName) {
|
||||
if ("".equals(mbeanServerName))
|
||||
@ -632,7 +625,7 @@ public class Util {
|
||||
"\"-\" is not a valid MBean server name");
|
||||
if (isMBeanServerNameUndefined(mbeanServerName))
|
||||
return MBeanServerFactory.DEFAULT_MBEANSERVER_NAME;
|
||||
for (char c : ILLEGAL_MBEANSERVER_NAME_CHARS.toCharArray()) {
|
||||
for (char c : ILLEGAL_MBEANSERVER_NAME_CHARS) {
|
||||
if (mbeanServerName.indexOf(c) >= 0)
|
||||
throw new IllegalArgumentException(
|
||||
"invalid character in MBeanServer name: "+c);
|
||||
@ -662,15 +655,15 @@ public class Util {
|
||||
}
|
||||
|
||||
// Log the exception and its causes without logging the stack trace.
|
||||
// Use with care - it is usally preferable to log the whole stack trace!
|
||||
// Use with care - it is usually preferable to log the whole stack trace!
|
||||
// We don't want to log the whole stack trace here: logshort() is
|
||||
// called in those cases where the exception might not be abnormal.
|
||||
private static void logshort(String msg, Throwable t) {
|
||||
if (JmxProperties.MISC_LOGGER.isLoggable(Level.FINE)) {
|
||||
StringBuilder toprint = new StringBuilder(msg);
|
||||
toprint.append("\nCaused By: ").append(String.valueOf(t));
|
||||
while ((t=t.getCause())!=null)
|
||||
toprint.append("\nCaused By: ").append(String.valueOf(t));
|
||||
do {
|
||||
toprint.append("\nCaused By: ").append(String.valueOf(t));
|
||||
} while ((t=t.getCause())!=null);
|
||||
JmxProperties.MISC_LOGGER.fine(toprint.toString());
|
||||
}
|
||||
}
|
||||
|
||||
@ -85,7 +85,7 @@ public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
|
||||
|
||||
final ObjectName pattern;
|
||||
public PatternNotificationFilter(ObjectName pattern) {
|
||||
this.pattern = pattern;
|
||||
this.pattern = pattern==null?ObjectName.WILDCARD:pattern;
|
||||
}
|
||||
|
||||
public boolean isNotificationEnabled(Notification notification) {
|
||||
@ -93,7 +93,7 @@ public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
|
||||
return false;
|
||||
final MBeanServerNotification mbsn =
|
||||
(MBeanServerNotification) notification;
|
||||
if (pattern == null || pattern.apply(mbsn.getMBeanName()))
|
||||
if (pattern.apply(mbsn.getMBeanName()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@ -110,6 +110,7 @@ public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
|
||||
super(handler);
|
||||
this.domainName = domainName;
|
||||
this.serverName = serverName;
|
||||
ALL = ObjectName.valueOf(domainName+":*");
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -118,27 +119,27 @@ public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
|
||||
", domain="+this.domainName+")";
|
||||
}
|
||||
|
||||
public void connectDelegate(final MBeanServerDelegate delegate)
|
||||
final void connectDelegate(final MBeanServerDelegate delegate)
|
||||
throws InstanceNotFoundException {
|
||||
final NotificationFilter filter =
|
||||
new PatternNotificationFilter(getPatternFor(null));
|
||||
synchronized (this) {
|
||||
if (mbsListener == null)
|
||||
if (mbsListener == null) {
|
||||
mbsListener = new NotificationListener() {
|
||||
|
||||
public void handleNotification(Notification notification,
|
||||
Object handback) {
|
||||
if (filter.isNotificationEnabled(notification))
|
||||
delegate.sendNotification(notification);
|
||||
}
|
||||
};
|
||||
public void handleNotification(Notification notification,
|
||||
Object handback) {
|
||||
if (filter.isNotificationEnabled(notification))
|
||||
delegate.sendNotification(notification);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
getNamespace().
|
||||
getHandlerInterceptorMBean().
|
||||
addMBeanServerNotificationListener(mbsListener, filter);
|
||||
}
|
||||
|
||||
public void disconnectDelegate()
|
||||
final void disconnectDelegate()
|
||||
throws InstanceNotFoundException, ListenerNotFoundException {
|
||||
final NotificationListener l;
|
||||
synchronized (this) {
|
||||
@ -146,10 +147,10 @@ public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
|
||||
if (l == null) return;
|
||||
mbsListener = null;
|
||||
}
|
||||
getNamespace().removeMBeanServerNotificationListener(l);
|
||||
getHandlerInterceptorMBean().removeMBeanServerNotificationListener(l);
|
||||
}
|
||||
|
||||
public void addPostRegisterTask(Queue<Runnable> queue,
|
||||
public final void addPostRegisterTask(Queue<Runnable> queue,
|
||||
final MBeanServerDelegate delegate) {
|
||||
if (queue == null)
|
||||
throw new IllegalArgumentException("task queue must not be null");
|
||||
@ -158,14 +159,15 @@ public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
|
||||
try {
|
||||
connectDelegate(delegate);
|
||||
} catch (Exception x) {
|
||||
throw new UnsupportedOperationException("notification forwarding",x);
|
||||
throw new UnsupportedOperationException(
|
||||
"notification forwarding",x);
|
||||
}
|
||||
}
|
||||
};
|
||||
queue.add(task1);
|
||||
}
|
||||
|
||||
public void addPostDeregisterTask(Queue<Runnable> queue,
|
||||
public final void addPostDeregisterTask(Queue<Runnable> queue,
|
||||
final MBeanServerDelegate delegate) {
|
||||
if (queue == null)
|
||||
throw new IllegalArgumentException("task queue must not be null");
|
||||
@ -174,17 +176,18 @@ public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
|
||||
try {
|
||||
disconnectDelegate();
|
||||
} catch (Exception x) {
|
||||
throw new UnsupportedOperationException("notification forwarding",x);
|
||||
throw new UnsupportedOperationException(
|
||||
"notification forwarding",x);
|
||||
}
|
||||
}
|
||||
};
|
||||
queue.add(task1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws IllegalArgumentException if targetName.getDomain() is not
|
||||
* in the domain handled.
|
||||
**/
|
||||
// No name conversion for JMXDomains...
|
||||
// Throws IllegalArgumentException if targetName.getDomain() is not
|
||||
// in the domain handled.
|
||||
//
|
||||
@Override
|
||||
protected ObjectName toSource(ObjectName targetName) {
|
||||
if (targetName == null) return null;
|
||||
@ -198,6 +201,7 @@ public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
|
||||
return targetName;
|
||||
}
|
||||
|
||||
// No name conversion for JMXDomains...
|
||||
@Override
|
||||
protected ObjectName toTarget(ObjectName sourceName) {
|
||||
return sourceName;
|
||||
@ -255,16 +259,16 @@ public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
|
||||
if (LOG.isLoggable(Level.FINE))
|
||||
LOG.fine("Unexpected exception raised in queryNames: "+x);
|
||||
LOG.log(Level.FINEST,"Unexpected exception raised in queryNames",x);
|
||||
return Collections.emptySet();
|
||||
}
|
||||
// We reach here only when an exception was raised.
|
||||
//
|
||||
final Set<ObjectName> empty = Collections.emptySet();
|
||||
return empty;
|
||||
}
|
||||
|
||||
// Compute a new pattern which is a sub pattern of 'name' but only selects
|
||||
// the MBeans in domain 'domainName'
|
||||
// When we reach here, it has been verified that 'name' matches our domain
|
||||
// name (done by DomainDispatchInterceptor)
|
||||
private ObjectName getPatternFor(final ObjectName name) {
|
||||
try {
|
||||
if (ALL == null) ALL = ObjectName.getInstance(domainName + ":*");
|
||||
if (name == null) return ALL;
|
||||
if (name.getDomain().equals(domainName)) return name;
|
||||
return name.withDomain(domainName);
|
||||
@ -284,11 +288,8 @@ public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
|
||||
if (LOG.isLoggable(Level.FINE))
|
||||
LOG.fine("Unexpected exception raised in queryNames: "+x);
|
||||
LOG.log(Level.FINEST,"Unexpected exception raised in queryNames",x);
|
||||
return Collections.emptySet();
|
||||
}
|
||||
// We reach here only when an exception was raised.
|
||||
//
|
||||
final Set<ObjectInstance> empty = Collections.emptySet();
|
||||
return empty;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -306,7 +307,7 @@ public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
|
||||
// in the domain.
|
||||
@Override
|
||||
public Integer getMBeanCount() {
|
||||
return getNamespace().getMBeanCount();
|
||||
return getHandlerInterceptorMBean().getMBeanCount();
|
||||
}
|
||||
|
||||
private boolean checkOn() {
|
||||
@ -320,8 +321,8 @@ public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
|
||||
@Override
|
||||
void check(ObjectName routingName, String member, String action) {
|
||||
if (!checkOn()) return;
|
||||
final String act = (action==null)?"-":action.intern();
|
||||
if(act == "queryMBeans" || act == "queryNames") { // ES: OK
|
||||
final String act = (action==null)?"-":action;
|
||||
if("queryMBeans".equals(act) || "queryNames".equals(act)) {
|
||||
// This is tricky. check with 3 parameters is called
|
||||
// by queryNames/queryMBeans before performing the query.
|
||||
// At this point we must check with no class name.
|
||||
@ -355,16 +356,8 @@ public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
|
||||
if (!checkOn()) return;
|
||||
final MBeanPermission perm;
|
||||
|
||||
// action is most probably already an intern string.
|
||||
// string literals are intern strings.
|
||||
// we create a new intern string for 'action' - just to be on
|
||||
// the safe side...
|
||||
// We intern it in order to be able to use == rather than equals
|
||||
// below, because if we don't, and if action is not one of the
|
||||
// 4 literals below, we would have to do a full string comparison.
|
||||
//
|
||||
final String act = (action==null)?"-":action.intern();
|
||||
if (act == "getDomains") { // ES: OK
|
||||
final String act = (action==null)?"-":action;
|
||||
if ("getDomains".equals(act)) { // ES: OK
|
||||
perm = new MBeanPermission(serverName,"-",member,
|
||||
routingName,act);
|
||||
} else {
|
||||
@ -381,7 +374,7 @@ public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
|
||||
String getClassName(ObjectName routingName) {
|
||||
if (routingName == null || routingName.isPattern()) return "-";
|
||||
try {
|
||||
return getNamespace().getSourceServer().
|
||||
return getHandlerInterceptorMBean().getSourceServer().
|
||||
getObjectInstance(routingName).getClassName();
|
||||
} catch (InstanceNotFoundException ex) {
|
||||
LOG.finest("Can't get class name for "+routingName+
|
||||
@ -444,7 +437,7 @@ public class DomainInterceptor extends HandlerInterceptor<JMXDomain> {
|
||||
int count=0;
|
||||
for (int i=0;i<domains.length;i++) {
|
||||
try {
|
||||
check(Util.newObjectName(domains[i]+":x=x"),"-",
|
||||
check(ObjectName.valueOf(domains[i]+":x=x"),"-",
|
||||
"-","getDomains");
|
||||
} catch (SecurityException x) { // DLS: OK
|
||||
count++;
|
||||
|
||||
@ -63,8 +63,8 @@ import javax.management.namespace.JMXNamespace;
|
||||
/**
|
||||
* This interceptor wraps a JMXNamespace, and performs
|
||||
* {@code ObjectName} rewriting. {@code HandlerInterceptor} are
|
||||
* usually created and managed by a {@link NamespaceDispatcher} or
|
||||
* {@link DomainDispatcher}.
|
||||
* created and managed by a {@link NamespaceDispatchInterceptor} or a
|
||||
* {@link DomainDispatchInterceptor}.
|
||||
* <p><b>
|
||||
* This API is a Sun internal API and is subject to changes without notice.
|
||||
* </b></p>
|
||||
@ -90,6 +90,12 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
//
|
||||
// The {@code source} connection is a connection to the MBeanServer
|
||||
// that contains the actual MBeans.
|
||||
// In the case of cascading, that would be a connection to the sub
|
||||
// agent. Practically, this is JMXNamespace.getSourceServer();
|
||||
//
|
||||
@Override
|
||||
protected MBeanServer source() {
|
||||
return handler.getSourceServer();
|
||||
@ -105,7 +111,9 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
return source();
|
||||
}
|
||||
|
||||
T getNamespace() {
|
||||
// The namespace or domain handler - this either a JMXNamespace or a
|
||||
// a JMXDomain
|
||||
T getHandlerInterceptorMBean() {
|
||||
return handler;
|
||||
}
|
||||
|
||||
@ -122,12 +130,16 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
Util.newRuntimeIOException(x));
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public AttributeList getAttributes(ObjectName name, String[] attributes)
|
||||
throws InstanceNotFoundException, ReflectionException {
|
||||
try {
|
||||
return super.getAttributes(name, attributes);
|
||||
final String[] authorized =
|
||||
checkAttributes(name,attributes,"getAttribute");
|
||||
final AttributeList attrList =
|
||||
super.getAttributes(name,authorized);
|
||||
return attrList;
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"getAttributes",name,attributes);
|
||||
}
|
||||
@ -172,18 +184,19 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public void removeNotificationListener(ObjectName name, ObjectName listener)
|
||||
throws InstanceNotFoundException, ListenerNotFoundException {
|
||||
try {
|
||||
super.removeNotificationListener(name, listener);
|
||||
check(name,null,"removeNotificationListener");
|
||||
super.removeNotificationListener(name,listener);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"removeNotificationListener",name,listener);
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public String getDefaultDomain() {
|
||||
try {
|
||||
@ -193,17 +206,19 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public String[] getDomains() {
|
||||
try {
|
||||
return super.getDomains();
|
||||
check(null,null,"getDomains");
|
||||
final String[] domains = super.getDomains();
|
||||
return checkDomains(domains,"getDomains");
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"getDomains");
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public Integer getMBeanCount() {
|
||||
try {
|
||||
@ -213,64 +228,74 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public void setAttribute(ObjectName name, Attribute attribute)
|
||||
throws InstanceNotFoundException, AttributeNotFoundException,
|
||||
InvalidAttributeValueException, MBeanException,
|
||||
ReflectionException {
|
||||
try {
|
||||
super.setAttribute(name, attribute);
|
||||
check(name,
|
||||
(attribute==null?null:attribute.getName()),
|
||||
"setAttribute");
|
||||
super.setAttribute(name,attribute);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"setAttribute",name, attribute);
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
|
||||
if (name == null) name=ObjectName.WILDCARD;
|
||||
try {
|
||||
return super.queryNames(name, query);
|
||||
checkPattern(name,null,"queryNames");
|
||||
return super.queryNames(name,query);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"queryNames",name, query);
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public Set<ObjectInstance> queryMBeans(ObjectName name, QueryExp query) {
|
||||
if (name == null) name=ObjectName.WILDCARD;
|
||||
try {
|
||||
return super.queryMBeans(name, query);
|
||||
checkPattern(name,null,"queryMBeans");
|
||||
return super.queryMBeans(name,query);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"queryMBeans",name, query);
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public boolean isInstanceOf(ObjectName name, String className)
|
||||
throws InstanceNotFoundException {
|
||||
try {
|
||||
check(name, null, "isInstanceOf");
|
||||
return super.isInstanceOf(name, className);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"isInstanceOf",name, className);
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public ObjectInstance createMBean(String className, ObjectName name)
|
||||
throws ReflectionException, InstanceAlreadyExistsException,
|
||||
MBeanRegistrationException, MBeanException,
|
||||
NotCompliantMBeanException {
|
||||
try {
|
||||
checkCreate(name, className, "instantiate");
|
||||
checkCreate(name, className, "registerMBean");
|
||||
return super.createMBean(className, name);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"createMBean",className, name);
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public ObjectInstance createMBean(String className, ObjectName name,
|
||||
ObjectName loaderName)
|
||||
@ -278,30 +303,34 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
MBeanRegistrationException, MBeanException,
|
||||
NotCompliantMBeanException, InstanceNotFoundException {
|
||||
try {
|
||||
checkCreate(name, className, "instantiate");
|
||||
checkCreate(name, className, "registerMBean");
|
||||
return super.createMBean(className, name, loaderName);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"createMBean",className, name, loaderName);
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public Object getAttribute(ObjectName name, String attribute)
|
||||
throws MBeanException, AttributeNotFoundException,
|
||||
InstanceNotFoundException, ReflectionException {
|
||||
try {
|
||||
check(name, attribute, "getAttribute");
|
||||
return super.getAttribute(name, attribute);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"getAttribute",name, attribute);
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public void removeNotificationListener(ObjectName name, ObjectName listener,
|
||||
NotificationFilter filter, Object handback)
|
||||
throws InstanceNotFoundException, ListenerNotFoundException {
|
||||
try {
|
||||
check(name,null,"removeNotificationListener");
|
||||
super.removeNotificationListener(name, listener, filter, handback);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"removeNotificationListener",name,
|
||||
@ -309,13 +338,14 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public void removeNotificationListener(ObjectName name,
|
||||
NotificationListener listener, NotificationFilter filter,
|
||||
Object handback)
|
||||
throws InstanceNotFoundException, ListenerNotFoundException {
|
||||
try {
|
||||
check(name,null,"removeNotificationListener");
|
||||
super.removeNotificationListener(name, listener, filter, handback);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"removeNotificationListener",name,
|
||||
@ -323,12 +353,13 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public void removeNotificationListener(ObjectName name,
|
||||
NotificationListener listener)
|
||||
throws InstanceNotFoundException, ListenerNotFoundException {
|
||||
try {
|
||||
check(name,null,"removeNotificationListener");
|
||||
super.removeNotificationListener(name, listener);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"removeNotificationListener",name,
|
||||
@ -336,12 +367,13 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public void addNotificationListener(ObjectName name,
|
||||
NotificationListener listener, NotificationFilter filter,
|
||||
Object handback) throws InstanceNotFoundException {
|
||||
try {
|
||||
check(name,null,"addNotificationListener");
|
||||
super.addNotificationListener(name, listener, filter, handback);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"addNotificationListener",name,
|
||||
@ -349,12 +381,13 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public void addNotificationListener(ObjectName name, ObjectName listener,
|
||||
NotificationFilter filter, Object handback)
|
||||
throws InstanceNotFoundException {
|
||||
try {
|
||||
check(name,null,"addNotificationListener");
|
||||
super.addNotificationListener(name, listener, filter, handback);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"addNotificationListener",name,
|
||||
@ -362,7 +395,7 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public boolean isRegistered(ObjectName name) {
|
||||
try {
|
||||
@ -372,41 +405,44 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public void unregisterMBean(ObjectName name)
|
||||
throws InstanceNotFoundException, MBeanRegistrationException {
|
||||
try {
|
||||
check(name, null, "unregisterMBean");
|
||||
super.unregisterMBean(name);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"unregisterMBean",name);
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public MBeanInfo getMBeanInfo(ObjectName name)
|
||||
throws InstanceNotFoundException, IntrospectionException,
|
||||
ReflectionException {
|
||||
try {
|
||||
check(name, null, "getMBeanInfo");
|
||||
return super.getMBeanInfo(name);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"getMBeanInfo",name);
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public ObjectInstance getObjectInstance(ObjectName name)
|
||||
throws InstanceNotFoundException {
|
||||
try {
|
||||
check(name, null, "getObjectInstance");
|
||||
return super.getObjectInstance(name);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"getObjectInstance",name);
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public ObjectInstance createMBean(String className, ObjectName name,
|
||||
Object[] params, String[] signature)
|
||||
@ -414,6 +450,8 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
MBeanRegistrationException, MBeanException,
|
||||
NotCompliantMBeanException {
|
||||
try {
|
||||
checkCreate(name, className, "instantiate");
|
||||
checkCreate(name, className, "registerMBean");
|
||||
return super.createMBean(className, name, params, signature);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"createMBean",className, name,
|
||||
@ -421,7 +459,7 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public ObjectInstance createMBean(String className, ObjectName name,
|
||||
ObjectName loaderName, Object[] params, String[] signature)
|
||||
@ -429,6 +467,8 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
MBeanRegistrationException, MBeanException,
|
||||
NotCompliantMBeanException, InstanceNotFoundException {
|
||||
try {
|
||||
checkCreate(name, className, "instantiate");
|
||||
checkCreate(name, className, "registerMBean");
|
||||
return super.createMBean(className, name, loaderName, params,
|
||||
signature);
|
||||
} catch (IOException ex) {
|
||||
@ -437,23 +477,26 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public AttributeList setAttributes(ObjectName name,AttributeList attributes)
|
||||
throws InstanceNotFoundException, ReflectionException {
|
||||
try {
|
||||
return super.setAttributes(name, attributes);
|
||||
final AttributeList authorized =
|
||||
checkAttributes(name, attributes, "setAttribute");
|
||||
return super.setAttributes(name, authorized);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"setAttributes",name, attributes);
|
||||
}
|
||||
}
|
||||
|
||||
// From MBeanServer: catch & handles IOException
|
||||
// From MBeanServerConnection: catch & handles IOException
|
||||
@Override
|
||||
public Object invoke(ObjectName name, String operationName, Object[] params,
|
||||
String[] signature)
|
||||
throws InstanceNotFoundException, MBeanException, ReflectionException {
|
||||
try {
|
||||
check(name, operationName, "invoke");
|
||||
return super.invoke(name, operationName, params, signature);
|
||||
} catch (IOException ex) {
|
||||
throw handleIOException(ex,"invoke",name, operationName,
|
||||
@ -574,4 +617,118 @@ public abstract class HandlerInterceptor<T extends JMXNamespace>
|
||||
"Not supported in this namespace: "+namespace));
|
||||
}
|
||||
|
||||
/**
|
||||
* A result might be excluded for security reasons.
|
||||
*/
|
||||
@Override
|
||||
boolean excludesFromResult(ObjectName targetName, String queryMethod) {
|
||||
return !checkQuery(targetName, queryMethod);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Hooks for checking permissions
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* This method is a hook to implement permission checking in subclasses.
|
||||
* A subclass may override this method and throw a {@link
|
||||
* SecurityException} if the permission is denied.
|
||||
*
|
||||
* @param routingName The name of the MBean in the enclosing context.
|
||||
* This is of the form {@code <namespace>//<ObjectName>}.
|
||||
* @param member The {@link
|
||||
* javax.management.namespace.JMXNamespacePermission#getMember member}
|
||||
* name.
|
||||
* @param action The {@link
|
||||
* javax.management.namespace.JMXNamespacePermission#getActions action}
|
||||
* name.
|
||||
* @throws SecurityException if the caller doesn't have the permission
|
||||
* to perform the given action on the MBean pointed to
|
||||
* by routingName.
|
||||
*/
|
||||
abstract void check(ObjectName routingName,
|
||||
String member, String action);
|
||||
|
||||
// called in createMBean and registerMBean
|
||||
abstract void checkCreate(ObjectName routingName, String className,
|
||||
String action);
|
||||
|
||||
/**
|
||||
* This is a hook to implement permission checking in subclasses.
|
||||
*
|
||||
* Checks that the caller has sufficient permission for returning
|
||||
* information about {@code sourceName} in {@code action}.
|
||||
*
|
||||
* Subclass may override this method and return false if the caller
|
||||
* doesn't have sufficient permissions.
|
||||
*
|
||||
* @param routingName The name of the MBean to include or exclude from
|
||||
* the query, expressed in the enclosing context.
|
||||
* This is of the form {@code <namespace>//<ObjectName>}.
|
||||
* @param action one of "queryNames" or "queryMBeans"
|
||||
* @return true if {@code sourceName} can be returned.
|
||||
*/
|
||||
abstract boolean checkQuery(ObjectName routingName, String action);
|
||||
|
||||
/**
|
||||
* This method is a hook to implement permission checking in subclasses.
|
||||
*
|
||||
* @param routingName The name of the MBean in the enclosing context.
|
||||
* This is of the form {@code <namespace>//<ObjectName>}.
|
||||
* @param attributes The list of attributes to check permission for.
|
||||
* @param action one of "getAttribute" or "setAttribute"
|
||||
* @return The list of attributes for which the callers has the
|
||||
* appropriate {@link
|
||||
* javax.management.namespace.JMXNamespacePermission}.
|
||||
* @throws SecurityException if the caller doesn't have the permission
|
||||
* to perform {@code action} on the MBean pointed to by routingName.
|
||||
*/
|
||||
abstract String[] checkAttributes(ObjectName routingName,
|
||||
String[] attributes, String action);
|
||||
|
||||
/**
|
||||
* This method is a hook to implement permission checking in subclasses.
|
||||
*
|
||||
* @param routingName The name of the MBean in the enclosing context.
|
||||
* This is of the form {@code <namespace>//<ObjectName>}.
|
||||
* @param attributes The list of attributes to check permission for.
|
||||
* @param action one of "getAttribute" or "setAttribute"
|
||||
* @return The list of attributes for which the callers has the
|
||||
* appropriate {@link
|
||||
* javax.management.namespace.JMXNamespacePermission}.
|
||||
* @throws SecurityException if the caller doesn't have the permission
|
||||
* to perform {@code action} on the MBean pointed to by routingName.
|
||||
*/
|
||||
abstract AttributeList checkAttributes(ObjectName routingName,
|
||||
AttributeList attributes, String action);
|
||||
|
||||
/**
|
||||
* This method is a hook to implement permission checking in subclasses.
|
||||
* Checks that the caller as the necessary permissions to view the
|
||||
* given domain. If not remove the domains for which the caller doesn't
|
||||
* have permission from the list.
|
||||
* <p>
|
||||
* By default, this method always returns {@code domains}
|
||||
*
|
||||
* @param domains The domains to return.
|
||||
* @param action "getDomains"
|
||||
* @return a filtered list of domains.
|
||||
*/
|
||||
String[] checkDomains(String[] domains, String action) {
|
||||
return domains;
|
||||
}
|
||||
|
||||
// A priori check for queryNames/queryMBeans/
|
||||
void checkPattern(ObjectName routingPattern,
|
||||
String member, String action) {
|
||||
// pattern is checked only at posteriori by checkQuery.
|
||||
// checking it a priori usually doesn't work, because ObjectName.apply
|
||||
// does not work between two patterns.
|
||||
// We only check that we have the permission requested for 'action'.
|
||||
check(null,null,action);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -29,7 +29,6 @@ import com.sun.jmx.defaults.JmxProperties;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.logging.Level;
|
||||
@ -40,6 +39,8 @@ import javax.management.MBeanServerConnection;
|
||||
import javax.management.NotificationFilter;
|
||||
import javax.management.NotificationListener;
|
||||
import javax.management.event.EventClient;
|
||||
import javax.management.event.EventClientDelegateMBean;
|
||||
import javax.management.namespace.JMXNamespace;
|
||||
import javax.management.namespace.JMXNamespaces;
|
||||
import javax.management.remote.JMXAddressable;
|
||||
import javax.management.remote.JMXConnector;
|
||||
@ -66,26 +67,10 @@ public final class JMXNamespaceUtils {
|
||||
return new WeakHashMap<K,V>();
|
||||
}
|
||||
|
||||
/** Creates a new instance of JMXNamespaces */
|
||||
/** There are no instances of this class */
|
||||
private JMXNamespaceUtils() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable option map in which the given keys have been
|
||||
* filtered out.
|
||||
* @param keys keys to filter out from the map.
|
||||
* @return An unmodifiable option map in which the given keys have been
|
||||
* filtered out.
|
||||
*/
|
||||
public static <K,V> Map<K,V> filterMap(Map<K,V> map, K... keys) {
|
||||
final Map<K,V> filtered;
|
||||
filtered=new HashMap<K,V>(map);
|
||||
for (K key : keys) {
|
||||
filtered.remove(key);
|
||||
}
|
||||
return unmodifiableMap(filtered);
|
||||
}
|
||||
|
||||
// returns un unmodifiable view of a map.
|
||||
public static <K,V> Map<K,V> unmodifiableMap(Map<K,V> aMap) {
|
||||
if (aMap == null || aMap.isEmpty())
|
||||
|
||||
@ -25,22 +25,15 @@
|
||||
package com.sun.jmx.namespace;
|
||||
|
||||
import com.sun.jmx.defaults.JmxProperties;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.management.Attribute;
|
||||
import javax.management.AttributeList;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.QueryExp;
|
||||
import javax.management.namespace.JMXNamespaces;
|
||||
import javax.management.namespace.JMXNamespace;
|
||||
import javax.management.namespace.JMXNamespacePermission;
|
||||
|
||||
@ -54,12 +47,6 @@ import javax.management.namespace.JMXNamespacePermission;
|
||||
*/
|
||||
public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
|
||||
|
||||
/**
|
||||
* A logger for this class.
|
||||
**/
|
||||
private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
|
||||
private static final Logger PROBE_LOG = Logger.getLogger(
|
||||
JmxProperties.NAMESPACE_LOGGER+".probe");
|
||||
|
||||
// The target name space in which the NamepsaceHandler is mounted.
|
||||
private final String targetNs;
|
||||
@ -68,21 +55,6 @@ public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
|
||||
|
||||
private final ObjectNameRouter proc;
|
||||
|
||||
/**
|
||||
* Internal hack. The JMXRemoteNamespace can be closed and reconnected.
|
||||
* Each time the JMXRemoteNamespace connects, a probe should be sent
|
||||
* to detect cycle. The MBeanServer exposed by JMXRemoteNamespace thus
|
||||
* implements the DynamicProbe interface, which makes it possible for
|
||||
* this handler to know that it should send a new probe.
|
||||
*
|
||||
* XXX: TODO this probe thing is way too complex and fragile.
|
||||
* This *must* go away or be replaced by something simpler.
|
||||
* ideas are welcomed.
|
||||
**/
|
||||
public static interface DynamicProbe {
|
||||
public boolean isProbeRequested();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of NamespaceInterceptor
|
||||
*/
|
||||
@ -104,164 +76,6 @@ public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
|
||||
", namespace="+this.targetNs+")";
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: TODO this probe thing is way too complex and fragile.
|
||||
* This *must* go away or be replaced by something simpler.
|
||||
* ideas are welcomed.
|
||||
*/
|
||||
private volatile boolean probed = false;
|
||||
private volatile ObjectName probe;
|
||||
|
||||
// Query Pattern that we will send through the source server in order
|
||||
// to detect self-linking namespaces.
|
||||
//
|
||||
// XXX: TODO this probe thing is way too complex and fragile.
|
||||
// This *must* go away or be replaced by something simpler.
|
||||
// ideas are welcomed.
|
||||
final ObjectName makeProbePattern(ObjectName probe)
|
||||
throws MalformedObjectNameException {
|
||||
|
||||
// we could probably link the probe pattern with the probe - e.g.
|
||||
// using the UUID as key in the pattern - but is it worth it? it
|
||||
// also has some side effects on the context namespace - because
|
||||
// such a probe may get rejected by the jmx.context// namespace.
|
||||
//
|
||||
// The trick here is to devise a pattern that is not likely to
|
||||
// be blocked by intermediate levels. Querying for all namespace
|
||||
// handlers in the source (or source namespace) is more likely to
|
||||
// achieve this goal.
|
||||
//
|
||||
return ObjectName.getInstance("*" +
|
||||
JMXNamespaces.NAMESPACE_SEPARATOR + ":" +
|
||||
JMXNamespace.TYPE_ASSIGNMENT);
|
||||
}
|
||||
|
||||
// tell whether the name pattern corresponds to what might have been
|
||||
// sent as a probe.
|
||||
// XXX: TODO this probe thing is way too complex and fragile.
|
||||
// This *must* go away or be replaced by something simpler.
|
||||
// ideas are welcomed.
|
||||
final boolean isProbePattern(ObjectName name) {
|
||||
final ObjectName p = probe;
|
||||
if (p == null) return false;
|
||||
try {
|
||||
return String.valueOf(name).endsWith(targetNs+
|
||||
JMXNamespaces.NAMESPACE_SEPARATOR + "*" +
|
||||
JMXNamespaces.NAMESPACE_SEPARATOR + ":" +
|
||||
JMXNamespace.TYPE_ASSIGNMENT);
|
||||
} catch (RuntimeException x) {
|
||||
// should not happen.
|
||||
PROBE_LOG.finest("Ignoring unexpected exception in self link detection: "+
|
||||
x);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// The first time a request reaches this NamespaceInterceptor, the
|
||||
// interceptor will send a probe to detect whether the underlying
|
||||
// JMXNamespace links to itslef.
|
||||
//
|
||||
// One way to create such self-linking namespace would be for instance
|
||||
// to create a JMXNamespace whose getSourceServer() method would return:
|
||||
// JMXNamespaces.narrowToNamespace(getMBeanServer(),
|
||||
// getObjectName().getDomain())
|
||||
//
|
||||
// If such an MBeanServer is returned, then any call to that MBeanServer
|
||||
// will trigger an infinite loop.
|
||||
// There can be even trickier configurations if remote connections are
|
||||
// involved.
|
||||
//
|
||||
// In order to prevent this from happening, the NamespaceInterceptor will
|
||||
// send a probe, in an attempt to detect whether it will receive it at
|
||||
// the other end. If the probe is received, an exception will be thrown
|
||||
// in order to break the recursion. The probe is only sent once - when
|
||||
// the first request to the namespace occurs. The DynamicProbe interface
|
||||
// can also be used by a Sun JMXNamespace implementation to request the
|
||||
// emission of a probe at any time (see JMXRemoteNamespace
|
||||
// implementation).
|
||||
//
|
||||
// Probes work this way: the NamespaceInterceptor sets a flag and sends
|
||||
// a queryNames() request. If a queryNames() request comes in when the flag
|
||||
// is on, then it deduces that there is a self-linking loop - and instead
|
||||
// of calling queryNames() on the source MBeanServer of the JMXNamespace
|
||||
// handler (which would cause the loop to go on) it breaks the recursion
|
||||
// by returning the probe ObjectName.
|
||||
// If the NamespaceInterceptor receives the probe ObjectName as result of
|
||||
// its original sendProbe() request it knows that it has been looping
|
||||
// back on itslef and throws an IOException...
|
||||
//
|
||||
//
|
||||
// XXX: TODO this probe thing is way too complex and fragile.
|
||||
// This *must* go away or be replaced by something simpler.
|
||||
// ideas are welcomed.
|
||||
//
|
||||
final void sendProbe(MBeanServerConnection msc)
|
||||
throws IOException {
|
||||
try {
|
||||
PROBE_LOG.fine("Sending probe");
|
||||
|
||||
// This is just to prevent any other thread to modify
|
||||
// the probe while the detection cycle is in progress.
|
||||
//
|
||||
final ObjectName probePattern;
|
||||
// we don't want to synchronize on this - we use targetNs
|
||||
// because it's non null and final.
|
||||
synchronized (targetNs) {
|
||||
probed = false;
|
||||
if (probe != null) {
|
||||
throw new IOException("concurent connection in progress");
|
||||
}
|
||||
final String uuid = UUID.randomUUID().toString();
|
||||
final String endprobe =
|
||||
JMXNamespaces.NAMESPACE_SEPARATOR + uuid +
|
||||
":type=Probe,key="+uuid;
|
||||
final ObjectName newprobe =
|
||||
ObjectName.getInstance(endprobe);
|
||||
probePattern = makeProbePattern(newprobe);
|
||||
probe = newprobe;
|
||||
}
|
||||
|
||||
try {
|
||||
PROBE_LOG.finer("Probe query: "+probePattern+" expecting: "+probe);
|
||||
final Set<ObjectName> res = msc.queryNames(probePattern, null);
|
||||
final ObjectName expected = probe;
|
||||
PROBE_LOG.finer("Probe res: "+res);
|
||||
if (res.contains(expected)) {
|
||||
throw new IOException("namespace " +
|
||||
targetNs + " is linking to itself: " +
|
||||
"cycle detected by probe");
|
||||
}
|
||||
} catch (SecurityException x) {
|
||||
PROBE_LOG.finer("Can't check for cycles: " + x);
|
||||
// can't do anything....
|
||||
} catch (RuntimeException x) {
|
||||
PROBE_LOG.finer("Exception raised by queryNames: " + x);
|
||||
throw x;
|
||||
} finally {
|
||||
probe = null;
|
||||
}
|
||||
} catch (MalformedObjectNameException x) {
|
||||
final IOException io =
|
||||
new IOException("invalid name space: probe failed");
|
||||
io.initCause(x);
|
||||
throw io;
|
||||
}
|
||||
PROBE_LOG.fine("Probe returned - no cycles");
|
||||
probed = true;
|
||||
}
|
||||
|
||||
// allows a Sun implementation JMX Namespace, such as the
|
||||
// JMXRemoteNamespace, to control when a probe should be sent.
|
||||
//
|
||||
// XXX: TODO this probe thing is way too complex and fragile.
|
||||
// This *must* go away or be replaced by something simpler.
|
||||
// ideas are welcomed.
|
||||
private boolean isProbeRequested(Object o) {
|
||||
if (o instanceof DynamicProbe)
|
||||
return ((DynamicProbe)o).isProbeRequested();
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will send a probe to detect self-linking name spaces.
|
||||
* A self linking namespace is a namespace that links back directly
|
||||
@ -281,29 +95,9 @@ public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
|
||||
* (see JMXRemoteNamespace implementation).
|
||||
*/
|
||||
private MBeanServer connection() {
|
||||
try {
|
||||
final MBeanServer c = super.source();
|
||||
if (probe != null) // should not happen
|
||||
throw new RuntimeException("connection is being probed");
|
||||
|
||||
if (probed == false || isProbeRequested(c)) {
|
||||
try {
|
||||
// Should not happen if class well behaved.
|
||||
// Never probed. Force it.
|
||||
//System.err.println("sending probe for " +
|
||||
// "target="+targetNs+", source="+srcNs);
|
||||
sendProbe(c);
|
||||
} catch (IOException io) {
|
||||
throw new RuntimeException(io.getMessage(), io);
|
||||
}
|
||||
}
|
||||
|
||||
if (c != null) {
|
||||
return c;
|
||||
}
|
||||
} catch (RuntimeException x) {
|
||||
throw x;
|
||||
}
|
||||
final MBeanServer c = super.source();
|
||||
if (c != null) return c;
|
||||
// should not come here
|
||||
throw new NullPointerException("getMBeanServerConnection");
|
||||
}
|
||||
|
||||
@ -319,24 +113,6 @@ public class NamespaceInterceptor extends HandlerInterceptor<JMXNamespace> {
|
||||
return super.source();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls {@link MBeanServerConnection#queryNames queryNames}
|
||||
* on the underlying
|
||||
* {@link #getMBeanServerConnection MBeanServerConnection}.
|
||||
**/
|
||||
@Override
|
||||
public final Set<ObjectName> queryNames(ObjectName name, QueryExp query) {
|
||||
// XXX: TODO this probe thing is way too complex and fragile.
|
||||
// This *must* go away or be replaced by something simpler.
|
||||
// ideas are welcomed.
|
||||
PROBE_LOG.finer("probe is: "+probe+" pattern is: "+name);
|
||||
if (probe != null && isProbePattern(name)) {
|
||||
PROBE_LOG.finer("Return probe: "+probe);
|
||||
return Collections.singleton(probe);
|
||||
}
|
||||
return super.queryNames(name, query);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ObjectName toSource(ObjectName targetName)
|
||||
throws MalformedObjectNameException {
|
||||
|
||||
@ -45,6 +45,9 @@ import javax.management.namespace.JMXNamespaces;
|
||||
* </b></p>
|
||||
* @since 1.7
|
||||
*/
|
||||
// See class hierarchy and detailled explanations in RoutingProxy in this
|
||||
// package.
|
||||
//
|
||||
public class RoutingConnectionProxy
|
||||
extends RoutingProxy<MBeanServerConnection> {
|
||||
|
||||
@ -93,40 +96,28 @@ public class RoutingConnectionProxy
|
||||
targetNs+"\", "+forwardsContext+")";
|
||||
}
|
||||
|
||||
static final RoutingProxyFactory
|
||||
<MBeanServerConnection,RoutingConnectionProxy>
|
||||
FACTORY = new RoutingProxyFactory
|
||||
<MBeanServerConnection,RoutingConnectionProxy>() {
|
||||
|
||||
public RoutingConnectionProxy newInstance(MBeanServerConnection source,
|
||||
String sourcePath, String targetPath,
|
||||
boolean forwardsContext) {
|
||||
return new RoutingConnectionProxy(source,sourcePath,
|
||||
targetPath,forwardsContext);
|
||||
}
|
||||
|
||||
public RoutingConnectionProxy newInstance(
|
||||
MBeanServerConnection source, String sourcePath) {
|
||||
return new RoutingConnectionProxy(source,sourcePath);
|
||||
}
|
||||
};
|
||||
|
||||
public static MBeanServerConnection cd(MBeanServerConnection source,
|
||||
String sourcePath) {
|
||||
if (source == null) throw new IllegalArgumentException("null");
|
||||
if (source.getClass().equals(RoutingConnectionProxy.class)) {
|
||||
// cast is OK here, but findbugs complains unless we use class.cast
|
||||
final RoutingConnectionProxy other =
|
||||
RoutingConnectionProxy.class.cast(source);
|
||||
final String target = other.getTargetNamespace();
|
||||
|
||||
// Avoid multiple layers of serialization.
|
||||
//
|
||||
// We construct a new proxy from the original source instead of
|
||||
// stacking a new proxy on top of the old one.
|
||||
// - that is we replace
|
||||
// cd ( cd ( x, dir1), dir2);
|
||||
// by
|
||||
// cd (x, dir1//dir2);
|
||||
//
|
||||
// We can do this only when the source class is exactly
|
||||
// NamespaceConnectionProxy.
|
||||
//
|
||||
if (target == null || target.equals("")) {
|
||||
final String path =
|
||||
JMXNamespaces.concat(other.getSourceNamespace(),
|
||||
sourcePath);
|
||||
return new RoutingConnectionProxy(other.source(),path,"",
|
||||
other.forwardsContext);
|
||||
}
|
||||
// Note: we could do possibly something here - but it would involve
|
||||
// removing part of targetDir, and possibly adding
|
||||
// something to sourcePath.
|
||||
// Too complex to bother! => simply default to stacking...
|
||||
}
|
||||
return new RoutingConnectionProxy(source,sourcePath);
|
||||
return RoutingProxy.cd(RoutingConnectionProxy.class, FACTORY,
|
||||
source, sourcePath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -83,18 +83,32 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the wrapped source connection.
|
||||
* Returns the wrapped source connection. The {@code source} connection
|
||||
* is a connection to the MBeanServer that contains the actual MBean.
|
||||
* In the case of cascading, that would be a connection to the sub
|
||||
* agent.
|
||||
**/
|
||||
protected abstract T source() throws IOException;
|
||||
|
||||
/**
|
||||
* Converts a target ObjectName to a source ObjectName.
|
||||
* The target ObjectName is the name of the MBean in the mount point
|
||||
* target. In the case of cascading, that would be the name of the
|
||||
* MBean in the master agent. So if a subagent S containing an MBean
|
||||
* named "X" is mounted in the target namespace "foo//" of a master agent M,
|
||||
* the source is S, the target is "foo//" in M, the source name is "X", and
|
||||
* the target name is "foo//X".
|
||||
* In the case of cascading - such as in NamespaceInterceptor, this method
|
||||
* will convert "foo//X" (the targetName) into "X", the source name.
|
||||
**/
|
||||
protected abstract ObjectName toSource(ObjectName targetName)
|
||||
throws MalformedObjectNameException;
|
||||
|
||||
/**
|
||||
* Converts a source ObjectName to a target ObjectName.
|
||||
* (see description of toSource above for explanations)
|
||||
* In the case of cascading - such as in NamespaceInterceptor, this method
|
||||
* will convert "X" (the sourceName) into "foo//X", the target name.
|
||||
**/
|
||||
protected abstract ObjectName toTarget(ObjectName sourceName)
|
||||
throws MalformedObjectNameException;
|
||||
@ -142,90 +156,17 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
return new RuntimeOperationsException(x2);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a hook to implement permission checking in subclasses.
|
||||
* By default, this method does nothing and simply returns
|
||||
* {@code attribute}.
|
||||
*
|
||||
* @param routingName The name of the MBean in the enclosing context.
|
||||
* This is of the form {@code <namespace>//<ObjectName>}.
|
||||
* @param attributes The list of attributes to check permission for.
|
||||
* @param action one of "getAttribute" or "setAttribute"
|
||||
* @return The list of attributes for which the callers has the
|
||||
* appropriate {@link
|
||||
* javax.management.namespace.JMXNamespacePermission}.
|
||||
*/
|
||||
String[] checkAttributes(ObjectName routingName,
|
||||
String[] attributes, String action) {
|
||||
check(routingName,null,action);
|
||||
return attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a hook to implement permission checking in subclasses.
|
||||
* By default, this method does nothing and simply returns
|
||||
* {@code attribute}.
|
||||
*
|
||||
* @param routingName The name of the MBean in the enclosing context.
|
||||
* This is of the form {@code <namespace>//<ObjectName>}.
|
||||
* @param attributes The list of attributes to check permission for.
|
||||
* @param action one of "getAttribute" or "setAttribute"
|
||||
* @return The list of attributes for which the callers has the
|
||||
* appropriate {@link
|
||||
* javax.management.namespace.JMXNamespacePermission}.
|
||||
*/
|
||||
AttributeList checkAttributes(ObjectName routingName,
|
||||
AttributeList attributes, String action) {
|
||||
check(routingName,null,action);
|
||||
return attributes;
|
||||
}
|
||||
|
||||
// from MBeanServerConnection
|
||||
public AttributeList getAttributes(ObjectName name, String[] attributes)
|
||||
throws InstanceNotFoundException, ReflectionException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
final String[] authorized =
|
||||
checkAttributes(name,attributes,"getAttribute");
|
||||
final AttributeList attrList =
|
||||
source().getAttributes(sourceName,authorized);
|
||||
return attrList;
|
||||
return source().getAttributes(sourceName, attributes);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a hook to implement permission checking in subclasses.
|
||||
* By default, this method does nothing.
|
||||
* A subclass may override this method and throw a {@link
|
||||
* SecurityException} if the permission is denied.
|
||||
*
|
||||
* @param routingName The name of the MBean in the enclosing context.
|
||||
* This is of the form {@code <namespace>//<ObjectName>}.
|
||||
* @param member The {@link
|
||||
* javax.management.namespace.JMXNamespacePermission#getMember member}
|
||||
* name.
|
||||
* @param action The {@link
|
||||
* javax.management.namespace.JMXNamespacePermission#getActions action}
|
||||
* name.
|
||||
*/
|
||||
void check(ObjectName routingName,
|
||||
String member, String action) {
|
||||
}
|
||||
|
||||
void checkPattern(ObjectName routingPattern,
|
||||
String member, String action) {
|
||||
// pattern is checked only at posteriori by checkQuery.
|
||||
// checking it a priori usually doesn't work, because ObjectName.apply
|
||||
// does not work between two patterns.
|
||||
check(null,null,action);
|
||||
}
|
||||
|
||||
void checkCreate(ObjectName routingName, String className,
|
||||
String action) {
|
||||
}
|
||||
|
||||
// from MBeanServerConnection
|
||||
public Object invoke(ObjectName name, String operationName, Object[] params,
|
||||
String[] signature)
|
||||
@ -233,7 +174,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name, operationName, "invoke");
|
||||
final Object result =
|
||||
source().invoke(sourceName,operationName,params,
|
||||
signature);
|
||||
@ -249,7 +189,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name, null, "unregisterMBean");
|
||||
source().unregisterMBean(sourceName);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
@ -262,7 +201,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
ReflectionException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name, null, "getMBeanInfo");
|
||||
return source().getMBeanInfo(sourceName);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
@ -274,7 +212,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
throws InstanceNotFoundException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name, null, "getObjectInstance");
|
||||
return processOutputInstance(
|
||||
source().getObjectInstance(sourceName));
|
||||
} catch (RuntimeException ex) {
|
||||
@ -301,9 +238,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
ReflectionException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name,
|
||||
(attribute==null?null:attribute.getName()),
|
||||
"setAttribute");
|
||||
source().setAttribute(sourceName,attribute);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
@ -321,8 +255,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
// Loader Name is already a sourceLoaderName.
|
||||
final ObjectName sourceLoaderName = loaderName;
|
||||
try {
|
||||
checkCreate(name, className, "instantiate");
|
||||
checkCreate(name, className, "registerMBean");
|
||||
final ObjectInstance instance =
|
||||
source().createMBean(className,sourceName,
|
||||
sourceLoaderName,
|
||||
@ -341,8 +273,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
NotCompliantMBeanException, IOException {
|
||||
final ObjectName sourceName = newSourceMBeanName(name);
|
||||
try {
|
||||
checkCreate(name, className, "instantiate");
|
||||
checkCreate(name, className, "registerMBean");
|
||||
return processOutputInstance(source().createMBean(className,
|
||||
sourceName,params,signature));
|
||||
} catch (RuntimeException ex) {
|
||||
@ -360,8 +290,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
// Loader Name is already a source Loader Name.
|
||||
final ObjectName sourceLoaderName = loaderName;
|
||||
try {
|
||||
checkCreate(name, className, "instantiate");
|
||||
checkCreate(name, className, "registerMBean");
|
||||
return processOutputInstance(source().createMBean(className,
|
||||
sourceName,sourceLoaderName));
|
||||
} catch (RuntimeException ex) {
|
||||
@ -376,8 +304,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
NotCompliantMBeanException, IOException {
|
||||
final ObjectName sourceName = newSourceMBeanName(name);
|
||||
try {
|
||||
checkCreate(name, className, "instantiate");
|
||||
checkCreate(name, className, "registerMBean");
|
||||
return processOutputInstance(source().
|
||||
createMBean(className,sourceName));
|
||||
} catch (RuntimeException ex) {
|
||||
@ -391,7 +317,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
InstanceNotFoundException, ReflectionException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name, attribute, "getAttribute");
|
||||
return source().getAttribute(sourceName,attribute);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
@ -403,7 +328,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
throws InstanceNotFoundException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name, null, "isInstanceOf");
|
||||
return source().isInstanceOf(sourceName,className);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
@ -415,10 +339,8 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
throws InstanceNotFoundException, ReflectionException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
final AttributeList authorized =
|
||||
checkAttributes(name, attributes, "setAttribute");
|
||||
return source().
|
||||
setAttributes(sourceName,authorized);
|
||||
setAttributes(sourceName,attributes);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
}
|
||||
@ -431,7 +353,7 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
for (ObjectInstance i : sources) {
|
||||
try {
|
||||
final ObjectInstance target = processOutputInstance(i);
|
||||
if (!checkQuery(target.getObjectName(), "queryMBeans"))
|
||||
if (excludesFromResult(target.getObjectName(), "queryMBeans"))
|
||||
continue;
|
||||
result.add(target);
|
||||
} catch (Exception x) {
|
||||
@ -446,24 +368,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a hook to implement permission checking in subclasses.
|
||||
*
|
||||
* Checks that the caller has sufficient permission for returning
|
||||
* information about {@code sourceName} in {@code action}.
|
||||
*
|
||||
* By default always return true. Subclass may override this method
|
||||
* and return false if the caller doesn't have sufficient permissions.
|
||||
*
|
||||
* @param routingName The name of the MBean to include or exclude from
|
||||
* the query, expressed in the enclosing context.
|
||||
* This is of the form {@code <namespace>//<ObjectName>}.
|
||||
* @param action one of "queryNames" or "queryMBeans"
|
||||
* @return true if {@code sourceName} can be returned.
|
||||
*/
|
||||
boolean checkQuery(ObjectName routingName, String action) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Return names in the target's context.
|
||||
ObjectInstance processOutputInstance(ObjectInstance source) {
|
||||
@ -488,7 +392,7 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
for (ObjectName n : sourceNames) {
|
||||
try {
|
||||
final ObjectName targetName = toTarget(n);
|
||||
if (!checkQuery(targetName, "queryNames")) continue;
|
||||
if (excludesFromResult(targetName, "queryNames")) continue;
|
||||
names.add(targetName);
|
||||
} catch (Exception x) {
|
||||
if (LOG.isLoggable(Level.FINE)) {
|
||||
@ -508,7 +412,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
if (name == null) name=ObjectName.WILDCARD;
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
checkPattern(name,null,"queryMBeans");
|
||||
return processOutputInstances(
|
||||
source().queryMBeans(sourceName,query));
|
||||
} catch (RuntimeException ex) {
|
||||
@ -523,7 +426,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
if (name == null) name=ObjectName.WILDCARD;
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
checkPattern(name,null,"queryNames");
|
||||
final Set<ObjectName> tmp = source().queryNames(sourceName,query);
|
||||
final Set<ObjectName> out = processOutputNames(tmp);
|
||||
//System.err.println("queryNames: out: "+out);
|
||||
@ -540,7 +442,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
ListenerNotFoundException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name,null,"removeNotificationListener");
|
||||
source().removeNotificationListener(sourceName,listener);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
@ -554,7 +455,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
// Listener name is already a source listener name.
|
||||
try {
|
||||
check(name,null,"addNotificationListener");
|
||||
source().addNotificationListener(sourceName,listener,
|
||||
filter,handback);
|
||||
} catch (RuntimeException ex) {
|
||||
@ -568,7 +468,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
Object handback) throws InstanceNotFoundException, IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name,null,"addNotificationListener");
|
||||
source().addNotificationListener(sourceName, listener, filter,
|
||||
handback);
|
||||
} catch (RuntimeException ex) {
|
||||
@ -585,7 +484,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name,null,"removeNotificationListener");
|
||||
source().removeNotificationListener(sourceName,listener,filter,
|
||||
handback);
|
||||
} catch (RuntimeException ex) {
|
||||
@ -600,7 +498,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
IOException {
|
||||
final ObjectName sourceName = toSourceOrRuntime(name);
|
||||
try {
|
||||
check(name,null,"removeNotificationListener");
|
||||
source().removeNotificationListener(sourceName,listener,
|
||||
filter,handback);
|
||||
} catch (RuntimeException ex) {
|
||||
@ -616,7 +513,6 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
// listener name is already a source name...
|
||||
final ObjectName sourceListener = listener;
|
||||
try {
|
||||
check(name,null,"removeNotificationListener");
|
||||
source().removeNotificationListener(sourceName,sourceListener);
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
@ -635,30 +531,12 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
// from MBeanServerConnection
|
||||
public String[] getDomains() throws IOException {
|
||||
try {
|
||||
check(null,null,"getDomains");
|
||||
final String[] domains = source().getDomains();
|
||||
return checkDomains(domains,"getDomains");
|
||||
return source().getDomains();
|
||||
} catch (RuntimeException ex) {
|
||||
throw makeCompliantRuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is a hook to implement permission checking in subclasses.
|
||||
* Checks that the caller as the necessary permissions to view the
|
||||
* given domain. If not remove the domains for which the caller doesn't
|
||||
* have permission from the list.
|
||||
* <p>
|
||||
* By default, this method always returns {@code domains}
|
||||
*
|
||||
* @param domains The domains to return.
|
||||
* @param action "getDomains"
|
||||
* @return a filtered list of domains.
|
||||
*/
|
||||
String[] checkDomains(String[] domains, String action) {
|
||||
return domains;
|
||||
}
|
||||
|
||||
// from MBeanServerConnection
|
||||
public String getDefaultDomain() throws IOException {
|
||||
try {
|
||||
@ -668,4 +546,22 @@ public abstract class RoutingMBeanServerConnection<T extends MBeanServerConnecti
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given targetName must be excluded from the
|
||||
* query result.
|
||||
* In this base class, always return {@code false}.
|
||||
* By default all object names returned by the sources are
|
||||
* transmitted to the caller - there is no filtering.
|
||||
*
|
||||
* @param name A target object name expressed in the caller's
|
||||
* context. In the case of cascading, where the source
|
||||
* is a sub agent mounted on e.g. namespace "foo",
|
||||
* that would be a name prefixed by "foo//"...
|
||||
* @param queryMethod either "queryNames" or "queryMBeans".
|
||||
* @return true if the name must be excluded.
|
||||
*/
|
||||
boolean excludesFromResult(ObjectName targetName, String queryMethod) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -30,31 +30,110 @@ import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.management.AttributeNotFoundException;
|
||||
import javax.management.InstanceNotFoundException;
|
||||
import javax.management.MBeanException;
|
||||
import javax.management.MBeanRegistrationException;
|
||||
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.ReflectionException;
|
||||
import javax.management.namespace.JMXNamespaces;
|
||||
|
||||
|
||||
/**
|
||||
* An RoutingProxy narrows on a given name space in a
|
||||
* A RoutingProxy narrows on a given name space in a
|
||||
* source object implementing MBeanServerConnection.
|
||||
* It is used to implement
|
||||
* {@code JMXNamespaces.narrowToNamespace(...)}.
|
||||
* This abstract class has two concrete subclasses:
|
||||
* <p>{@link RoutingConnectionProxy}: to cd in an MBeanServerConnection.</p>
|
||||
* <p>{@link RoutingServerProxy}: to cd in an MBeanServer.</p>
|
||||
* <p>{@link RoutingConnectionProxy}: to narrow down into an
|
||||
* MBeanServerConnection.</p>
|
||||
* <p>{@link RoutingServerProxy}: to narrow down into an MBeanServer.</p>
|
||||
*
|
||||
* <p>This class can also be used to "broaden" from a namespace. The same
|
||||
* class is used for both purposes because in both cases all that happens
|
||||
* is that ObjectNames are rewritten in one way on the way in (e.g. the
|
||||
* parameter of getMBeanInfo) and another way on the way out (e.g. the
|
||||
* return value of queryNames).</p>
|
||||
*
|
||||
* <p>Specifically, if you narrow into "a//" then you want to add the
|
||||
* "a//" prefix to ObjectNames on the way in and subtract it on the way
|
||||
* out. But ClientContext uses this class to subtract the
|
||||
* "jmx.context//foo=bar//" prefix on the way in and add it back on the
|
||||
* way out.</p>
|
||||
*
|
||||
* <p><b>
|
||||
* This API is a Sun internal API and is subject to changes without notice.
|
||||
* </b></p>
|
||||
* @since 1.7
|
||||
*/
|
||||
//
|
||||
// RoutingProxies are client side objects which are used to narrow down
|
||||
// into a namespace. They are used to perform ObjectName translation,
|
||||
// adding the namespace to the routing ObjectName before sending it over
|
||||
// to the source connection, and removing that prefix from results of
|
||||
// queries, createMBean, registerMBean, and getObjectInstance.
|
||||
// This translation is the opposite to that which is performed by
|
||||
// NamespaceInterceptors.
|
||||
//
|
||||
// There is however a special case where routing proxies are used on the
|
||||
// 'server' side to remove a namespace - rather than to add it:
|
||||
// This the case of ClientContext.
|
||||
// When an ObjectName like "jmx.context//c1=v1,c2=v2//D:k=v" reaches the
|
||||
// jmx.context namespace, a routing proxy is used to remove the prefix
|
||||
// c1=v1,c2=v2// from the routing objectname.
|
||||
//
|
||||
// For a RoutingProxy used in a narrowDownToNamespace operation, we have:
|
||||
// targetNs="" // targetNS is the namespace 'to remove'
|
||||
// sourceNS=<namespace-we-narrow-down-to> // namespace 'to add'
|
||||
//
|
||||
// For a RoutingProxy used in a ClientContext operation, we have:
|
||||
// targetNs=<encoded-context> // context must be removed from object name
|
||||
// sourceNs="" // nothing to add...
|
||||
//
|
||||
// RoutingProxies can also be used on the client side to implement
|
||||
// "withClientContext" operations. In that case, the boolean parameter
|
||||
// 'forwards context' is set to true, targetNs is "", and sourceNS may
|
||||
// also be "". When forwardsContext is true, the RoutingProxy dynamically
|
||||
// creates an ObjectNameRouter for each operation - in order to dynamically add
|
||||
// the context attached to the thread to the routing ObjectName. This is
|
||||
// performed in the getObjectNameRouter() method.
|
||||
//
|
||||
// Finally, in order to avoid too many layers of wrapping,
|
||||
// RoutingConnectionProxy and RoutingServerProxy can be created through a
|
||||
// factory method that can concatenate namespace pathes in order to
|
||||
// return a single RoutingProxy - rather than wrapping a RoutingProxy inside
|
||||
// another RoutingProxy. See RoutingConnectionProxy.cd and
|
||||
// RoutingServerProxy.cd
|
||||
//
|
||||
// The class hierarchy is as follows:
|
||||
//
|
||||
// RoutingMBeanServerConnection
|
||||
// [abstract class for all routing interceptors,
|
||||
// such as RoutingProxies and HandlerInterceptors]
|
||||
// / \
|
||||
// / \
|
||||
// RoutingProxy HandlerInterceptor
|
||||
// [base class for [base class for server side
|
||||
// client-side objects used objects, created by
|
||||
// in narrowDownTo] DispatchInterceptors]
|
||||
// / \ | \
|
||||
// RoutingConnectionProxy \ | NamespaceInterceptor
|
||||
// [wraps MBeanServerConnection \ | [used to remove
|
||||
// objects] \ | namespace prefix and
|
||||
// RoutingServerProxy | wrap JMXNamespace]
|
||||
// [wraps MBeanServer |
|
||||
// Objects] |
|
||||
// DomainInterceptor
|
||||
// [used to wrap JMXDomain]
|
||||
//
|
||||
// RoutingProxies also differ from HandlerInterceptors in that they transform
|
||||
// calls to MBeanServerConnection operations that do not have any parameters
|
||||
// into a call to the underlying JMXNamespace MBean.
|
||||
// So for instance a call to:
|
||||
// JMXNamespaces.narrowDownToNamespace(conn,"foo").getDomains()
|
||||
// is transformed into
|
||||
// conn.getAttribute("foo//type=JMXNamespace","Domains");
|
||||
//
|
||||
public abstract class RoutingProxy<T extends MBeanServerConnection>
|
||||
extends RoutingMBeanServerConnection<T> {
|
||||
|
||||
@ -179,17 +258,11 @@ public abstract class RoutingProxy<T extends MBeanServerConnection>
|
||||
throw x;
|
||||
} catch (MBeanException ex) {
|
||||
throw new IOException("Failed to get "+attributeName+": "+
|
||||
ex.getMessage(),
|
||||
ex.getTargetException());
|
||||
} catch (AttributeNotFoundException ex) {
|
||||
ex.getCause(),
|
||||
ex.getCause());
|
||||
} catch (Exception ex) {
|
||||
throw new IOException("Failed to get "+attributeName+": "+
|
||||
ex.getMessage(),ex);
|
||||
} catch (InstanceNotFoundException ex) {
|
||||
throw new IOException("Failed to get "+attributeName+": "+
|
||||
ex.getMessage(),ex);
|
||||
} catch (ReflectionException ex) {
|
||||
throw new IOException("Failed to get "+attributeName+": "+
|
||||
ex.getMessage(),ex);
|
||||
ex,ex);
|
||||
}
|
||||
}
|
||||
|
||||
@ -279,4 +352,62 @@ public abstract class RoutingProxy<T extends MBeanServerConnection>
|
||||
(" mounted on targetNs="+targetNs));
|
||||
}
|
||||
|
||||
// Creates an instance of a subclass 'R' of RoutingProxy<T>
|
||||
// RoutingServerProxy and RoutingConnectionProxy have their own factory
|
||||
// instance.
|
||||
static interface RoutingProxyFactory<T extends MBeanServerConnection,
|
||||
R extends RoutingProxy<T>> {
|
||||
R newInstance(T source,
|
||||
String sourcePath, String targetPath,
|
||||
boolean forwardsContext);
|
||||
R newInstance(T source,
|
||||
String sourcePath);
|
||||
}
|
||||
|
||||
// Performs a narrowDownToNamespace operation.
|
||||
// This method will attempt to merge two RoutingProxies in a single
|
||||
// one if they are of the same class.
|
||||
//
|
||||
// This method is never called directly - it should be called only by
|
||||
// subclasses of RoutingProxy.
|
||||
//
|
||||
// As for now it is called by:
|
||||
// RoutingServerProxy.cd and RoutingConnectionProxy.cd.
|
||||
//
|
||||
static <T extends MBeanServerConnection, R extends RoutingProxy<T>>
|
||||
R cd(Class<R> routingProxyClass,
|
||||
RoutingProxyFactory<T,R> factory,
|
||||
T source, String sourcePath) {
|
||||
if (source == null) throw new IllegalArgumentException("null");
|
||||
if (source.getClass().equals(routingProxyClass)) {
|
||||
// cast is OK here, but findbugs complains unless we use class.cast
|
||||
final R other = routingProxyClass.cast(source);
|
||||
final String target = other.getTargetNamespace();
|
||||
|
||||
// Avoid multiple layers of serialization.
|
||||
//
|
||||
// We construct a new proxy from the original source instead of
|
||||
// stacking a new proxy on top of the old one.
|
||||
// - that is we replace
|
||||
// cd ( cd ( x, dir1), dir2);
|
||||
// by
|
||||
// cd (x, dir1//dir2);
|
||||
//
|
||||
// We can do this only when the source class is exactly
|
||||
// RoutingServerProxy.
|
||||
//
|
||||
if (target == null || target.equals("")) {
|
||||
final String path =
|
||||
JMXNamespaces.concat(other.getSourceNamespace(),
|
||||
sourcePath);
|
||||
return factory.newInstance(other.source(),path,"",
|
||||
other.forwardsContext);
|
||||
}
|
||||
// Note: we could do possibly something here - but it would involve
|
||||
// removing part of targetDir, and possibly adding
|
||||
// something to sourcePath.
|
||||
// Too complex to bother! => simply default to stacking...
|
||||
}
|
||||
return factory.newInstance(source,sourcePath);
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,6 +69,9 @@ import javax.management.namespace.JMXNamespaces;
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
// See class hierarchy and detailled explanations in RoutingProxy in this
|
||||
// package.
|
||||
//
|
||||
public class RoutingServerProxy
|
||||
extends RoutingProxy<MBeanServer>
|
||||
implements MBeanServer {
|
||||
@ -564,39 +567,24 @@ public class RoutingServerProxy
|
||||
}
|
||||
}
|
||||
|
||||
static final RoutingProxyFactory<MBeanServer,RoutingServerProxy>
|
||||
FACTORY = new RoutingProxyFactory<MBeanServer,RoutingServerProxy>() {
|
||||
|
||||
public RoutingServerProxy newInstance(MBeanServer source,
|
||||
String sourcePath, String targetPath,
|
||||
boolean forwardsContext) {
|
||||
return new RoutingServerProxy(source,sourcePath,
|
||||
targetPath,forwardsContext);
|
||||
}
|
||||
|
||||
public RoutingServerProxy newInstance(
|
||||
MBeanServer source, String sourcePath) {
|
||||
return new RoutingServerProxy(source,sourcePath);
|
||||
}
|
||||
};
|
||||
|
||||
public static MBeanServer cd(MBeanServer source, String sourcePath) {
|
||||
if (source == null) throw new IllegalArgumentException("null");
|
||||
if (source.getClass().equals(RoutingServerProxy.class)) {
|
||||
// cast is OK here, but findbugs complains unless we use class.cast
|
||||
final RoutingServerProxy other =
|
||||
RoutingServerProxy.class.cast(source);
|
||||
final String target = other.getTargetNamespace();
|
||||
|
||||
// Avoid multiple layers of serialization.
|
||||
//
|
||||
// We construct a new proxy from the original source instead of
|
||||
// stacking a new proxy on top of the old one.
|
||||
// - that is we replace
|
||||
// cd ( cd ( x, dir1), dir2);
|
||||
// by
|
||||
// cd (x, dir1//dir2);
|
||||
//
|
||||
// We can do this only when the source class is exactly
|
||||
// NamespaceServerProxy.
|
||||
//
|
||||
if (target == null || target.equals("")) {
|
||||
final String path =
|
||||
JMXNamespaces.concat(other.getSourceNamespace(),
|
||||
sourcePath);
|
||||
return new RoutingServerProxy(other.source(),path,"",
|
||||
other.forwardsContext);
|
||||
}
|
||||
// Note: we could do possibly something here - but it would involve
|
||||
// removing part of targetDir, and possibly adding
|
||||
// something to sourcePath.
|
||||
// Too complex to bother! => simply default to stacking...
|
||||
}
|
||||
return new RoutingServerProxy(source,sourcePath);
|
||||
return RoutingProxy.cd(RoutingServerProxy.class, FACTORY,
|
||||
source, sourcePath);
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,13 +32,15 @@ import com.sun.jmx.remote.util.ClassLogger;
|
||||
import com.sun.jmx.remote.util.EnvHelp;
|
||||
|
||||
public abstract class ClientCommunicatorAdmin {
|
||||
private static volatile long threadNo = 1;
|
||||
|
||||
public ClientCommunicatorAdmin(long period) {
|
||||
this.period = period;
|
||||
|
||||
if (period > 0) {
|
||||
checker = new Checker();
|
||||
|
||||
Thread t = new Thread(checker);
|
||||
Thread t = new Thread(checker, "JMX client heartbeat " + ++threadNo);
|
||||
t.setDaemon(true);
|
||||
t.start();
|
||||
} else
|
||||
|
||||
@ -290,28 +290,6 @@ public abstract class ClientNotifForwarder {
|
||||
|
||||
infoList.clear();
|
||||
|
||||
if (currentFetchThread == Thread.currentThread()) {
|
||||
/* we do not need to stop the fetching thread, because this thread is
|
||||
used to do restarting and it will not be used to do fetching during
|
||||
the re-registering the listeners.*/
|
||||
return tmp;
|
||||
}
|
||||
|
||||
while (state == STARTING) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException ire) {
|
||||
IOException ioe = new IOException(ire.toString());
|
||||
EnvHelp.initCause(ioe, ire);
|
||||
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
|
||||
if (state == STARTED) {
|
||||
setState(STOPPING);
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@ -353,8 +331,9 @@ public abstract class ClientNotifForwarder {
|
||||
beingReconnected = false;
|
||||
notifyAll();
|
||||
|
||||
if (currentFetchThread == Thread.currentThread()) {
|
||||
// no need to init, simply get the id
|
||||
if (currentFetchThread == Thread.currentThread() ||
|
||||
state == STARTING || state == STARTED) { // doing or waiting reconnection
|
||||
// only update mbeanRemovedNotifID
|
||||
try {
|
||||
mbeanRemovedNotifID = addListenerForMBeanRemovedNotif();
|
||||
} catch (Exception e) {
|
||||
@ -366,12 +345,23 @@ public abstract class ClientNotifForwarder {
|
||||
logger.trace("init", msg, e);
|
||||
}
|
||||
}
|
||||
} else if (listenerInfos.length > 0) { // old listeners re-registered
|
||||
init(true);
|
||||
} else if (infoList.size() > 0) {
|
||||
// but new listeners registered during reconnection
|
||||
init(false);
|
||||
}
|
||||
} else {
|
||||
while (state == STOPPING) {
|
||||
try {
|
||||
wait();
|
||||
} catch (InterruptedException ire) {
|
||||
IOException ioe = new IOException(ire.toString());
|
||||
EnvHelp.initCause(ioe, ire);
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
|
||||
if (listenerInfos.length > 0) { // old listeners are re-added
|
||||
init(true); // not update clientSequenceNumber
|
||||
} else if (infoList.size() > 0) { // only new listeners added during reconnection
|
||||
init(false); // need update clientSequenceNumber
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void terminate() {
|
||||
@ -486,6 +476,15 @@ public abstract class ClientNotifForwarder {
|
||||
if (nr == null || shouldStop()) {
|
||||
// tell that the thread is REALLY stopped
|
||||
setState(STOPPED);
|
||||
|
||||
try {
|
||||
removeListenerForMBeanRemovedNotif(mbeanRemovedNotifID);
|
||||
} catch (Exception e) {
|
||||
if (logger.traceOn()) {
|
||||
logger.trace("NotifFetcher-run",
|
||||
"removeListenerForMBeanRemovedNotif", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
executor.execute(this);
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
/**
|
||||
* The value is used for character storage.
|
||||
*/
|
||||
char value[];
|
||||
char[] value;
|
||||
|
||||
/**
|
||||
* The count is the number of characters used.
|
||||
@ -333,8 +333,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
* <code>dst.length</code>
|
||||
* </ul>
|
||||
*/
|
||||
public void getChars(int srcBegin, int srcEnd, char dst[],
|
||||
int dstBegin)
|
||||
public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
|
||||
{
|
||||
if (srcBegin < 0)
|
||||
throw new StringIndexOutOfBoundsException(srcBegin);
|
||||
@ -366,14 +365,14 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of the <code>Object</code>
|
||||
* argument.
|
||||
* Appends the string representation of the {@code Object} argument.
|
||||
* <p>
|
||||
* The argument is converted to a string as if by the method
|
||||
* <code>String.valueOf</code>, and the characters of that
|
||||
* string are then appended to this sequence.
|
||||
* The overall effect is exactly as if the argument were converted
|
||||
* to a string by the method {@link String#valueOf(Object)},
|
||||
* and the characters of that string were then
|
||||
* {@link #append(String) appended} to this character sequence.
|
||||
*
|
||||
* @param obj an <code>Object</code>.
|
||||
* @param obj an {@code Object}.
|
||||
* @return a reference to this object.
|
||||
*/
|
||||
public AbstractStringBuilder append(Object obj) {
|
||||
@ -383,17 +382,17 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
/**
|
||||
* Appends the specified string to this character sequence.
|
||||
* <p>
|
||||
* The characters of the <code>String</code> argument are appended, in
|
||||
* The characters of the {@code String} argument are appended, in
|
||||
* order, increasing the length of this sequence by the length of the
|
||||
* argument. If <code>str</code> is <code>null</code>, then the four
|
||||
* characters <code>"null"</code> are appended.
|
||||
* argument. If {@code str} is {@code null}, then the four
|
||||
* characters {@code "null"} are appended.
|
||||
* <p>
|
||||
* Let <i>n</i> be the length of this character sequence just prior to
|
||||
* execution of the <code>append</code> method. Then the character at
|
||||
* execution of the {@code append} method. Then the character at
|
||||
* index <i>k</i> in the new character sequence is equal to the character
|
||||
* at index <i>k</i> in the old character sequence, if <i>k</i> is less
|
||||
* than <i>n</i>; otherwise, it is equal to the character at index
|
||||
* <i>k-n</i> in the argument <code>str</code>.
|
||||
* <i>k-n</i> in the argument {@code str}.
|
||||
*
|
||||
* @param str a string.
|
||||
* @return a reference to this object.
|
||||
@ -435,33 +434,33 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a subsequence of the specified <code>CharSequence</code> to this
|
||||
* Appends a subsequence of the specified {@code CharSequence} to this
|
||||
* sequence.
|
||||
* <p>
|
||||
* Characters of the argument <code>s</code>, starting at
|
||||
* index <code>start</code>, are appended, in order, to the contents of
|
||||
* this sequence up to the (exclusive) index <code>end</code>. The length
|
||||
* of this sequence is increased by the value of <code>end - start</code>.
|
||||
* Characters of the argument {@code s}, starting at
|
||||
* index {@code start}, are appended, in order, to the contents of
|
||||
* this sequence up to the (exclusive) index {@code end}. The length
|
||||
* of this sequence is increased by the value of {@code end - start}.
|
||||
* <p>
|
||||
* Let <i>n</i> be the length of this character sequence just prior to
|
||||
* execution of the <code>append</code> method. Then the character at
|
||||
* execution of the {@code append} method. Then the character at
|
||||
* index <i>k</i> in this character sequence becomes equal to the
|
||||
* character at index <i>k</i> in this sequence, if <i>k</i> is less than
|
||||
* <i>n</i>; otherwise, it is equal to the character at index
|
||||
* <i>k+start-n</i> in the argument <code>s</code>.
|
||||
* <i>k+start-n</i> in the argument {@code s}.
|
||||
* <p>
|
||||
* If <code>s</code> is <code>null</code>, then this method appends
|
||||
* If {@code s} is {@code null}, then this method appends
|
||||
* characters as if the s parameter was a sequence containing the four
|
||||
* characters <code>"null"</code>.
|
||||
* characters {@code "null"}.
|
||||
*
|
||||
* @param s the sequence to append.
|
||||
* @param start the starting index of the subsequence to be appended.
|
||||
* @param end the end index of the subsequence to be appended.
|
||||
* @return a reference to this object.
|
||||
* @throws IndexOutOfBoundsException if
|
||||
* <code>start</code> or <code>end</code> are negative, or
|
||||
* <code>start</code> is greater than <code>end</code> or
|
||||
* <code>end</code> is greater than <code>s.length()</code>
|
||||
* {@code start} is negative, or
|
||||
* {@code start} is greater than {@code end} or
|
||||
* {@code end} is greater than {@code s.length()}
|
||||
*/
|
||||
public AbstractStringBuilder append(CharSequence s, int start, int end) {
|
||||
if (s == null)
|
||||
@ -483,22 +482,22 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of the <code>char</code> array
|
||||
* Appends the string representation of the {@code char} array
|
||||
* argument to this sequence.
|
||||
* <p>
|
||||
* The characters of the array argument are appended, in order, to
|
||||
* the contents of this sequence. The length of this sequence
|
||||
* increases by the length of the argument.
|
||||
* <p>
|
||||
* The overall effect is exactly as if the argument were converted to
|
||||
* a string by the method {@link String#valueOf(char[])} and the
|
||||
* characters of that string were then {@link #append(String) appended}
|
||||
* to this character sequence.
|
||||
* The overall effect is exactly as if the argument were converted
|
||||
* to a string by the method {@link String#valueOf(char[])},
|
||||
* and the characters of that string were then
|
||||
* {@link #append(String) appended} to this character sequence.
|
||||
*
|
||||
* @param str the characters to be appended.
|
||||
* @return a reference to this object.
|
||||
*/
|
||||
public AbstractStringBuilder append(char str[]) {
|
||||
public AbstractStringBuilder append(char[] str) {
|
||||
int newCount = count + str.length;
|
||||
if (newCount > value.length)
|
||||
expandCapacity(newCount);
|
||||
@ -509,22 +508,25 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
|
||||
/**
|
||||
* Appends the string representation of a subarray of the
|
||||
* <code>char</code> array argument to this sequence.
|
||||
* {@code char} array argument to this sequence.
|
||||
* <p>
|
||||
* Characters of the <code>char</code> array <code>str</code>, starting at
|
||||
* index <code>offset</code>, are appended, in order, to the contents
|
||||
* Characters of the {@code char} array {@code str}, starting at
|
||||
* index {@code offset}, are appended, in order, to the contents
|
||||
* of this sequence. The length of this sequence increases
|
||||
* by the value of <code>len</code>.
|
||||
* by the value of {@code len}.
|
||||
* <p>
|
||||
* The overall effect is exactly as if the arguments were converted to
|
||||
* a string by the method {@link String#valueOf(char[],int,int)} and the
|
||||
* characters of that string were then {@link #append(String) appended}
|
||||
* to this character sequence.
|
||||
* The overall effect is exactly as if the arguments were converted
|
||||
* to a string by the method {@link String#valueOf(char[],int,int)},
|
||||
* and the characters of that string were then
|
||||
* {@link #append(String) appended} to this character sequence.
|
||||
*
|
||||
* @param str the characters to be appended.
|
||||
* @param offset the index of the first <code>char</code> to append.
|
||||
* @param len the number of <code>char</code>s to append.
|
||||
* @param offset the index of the first {@code char} to append.
|
||||
* @param len the number of {@code char}s to append.
|
||||
* @return a reference to this object.
|
||||
* @throws IndexOutOfBoundsException
|
||||
* if {@code offset < 0} or {@code len < 0}
|
||||
* or {@code offset+len > str.length}
|
||||
*/
|
||||
public AbstractStringBuilder append(char str[], int offset, int len) {
|
||||
int newCount = count + len;
|
||||
@ -536,14 +538,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of the <code>boolean</code>
|
||||
* Appends the string representation of the {@code boolean}
|
||||
* argument to the sequence.
|
||||
* <p>
|
||||
* The argument is converted to a string as if by the method
|
||||
* <code>String.valueOf</code>, and the characters of that
|
||||
* string are then appended to this sequence.
|
||||
* The overall effect is exactly as if the argument were converted
|
||||
* to a string by the method {@link String#valueOf(boolean)},
|
||||
* and the characters of that string were then
|
||||
* {@link #append(String) appended} to this character sequence.
|
||||
*
|
||||
* @param b a <code>boolean</code>.
|
||||
* @param b a {@code boolean}.
|
||||
* @return a reference to this object.
|
||||
*/
|
||||
public AbstractStringBuilder append(boolean b) {
|
||||
@ -569,18 +572,18 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of the <code>char</code>
|
||||
* Appends the string representation of the {@code char}
|
||||
* argument to this sequence.
|
||||
* <p>
|
||||
* The argument is appended to the contents of this sequence.
|
||||
* The length of this sequence increases by <code>1</code>.
|
||||
* The length of this sequence increases by {@code 1}.
|
||||
* <p>
|
||||
* The overall effect is exactly as if the argument were converted to
|
||||
* a string by the method {@link String#valueOf(char)} and the character
|
||||
* in that string were then {@link #append(String) appended} to this
|
||||
* character sequence.
|
||||
* The overall effect is exactly as if the argument were converted
|
||||
* to a string by the method {@link String#valueOf(char)},
|
||||
* and the character in that string were then
|
||||
* {@link #append(String) appended} to this character sequence.
|
||||
*
|
||||
* @param c a <code>char</code>.
|
||||
* @param c a {@code char}.
|
||||
* @return a reference to this object.
|
||||
*/
|
||||
public AbstractStringBuilder append(char c) {
|
||||
@ -592,14 +595,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of the <code>int</code>
|
||||
* Appends the string representation of the {@code int}
|
||||
* argument to this sequence.
|
||||
* <p>
|
||||
* The argument is converted to a string as if by the method
|
||||
* <code>String.valueOf</code>, and the characters of that
|
||||
* string are then appended to this sequence.
|
||||
* The overall effect is exactly as if the argument were converted
|
||||
* to a string by the method {@link String#valueOf(int)},
|
||||
* and the characters of that string were then
|
||||
* {@link #append(String) appended} to this character sequence.
|
||||
*
|
||||
* @param i an <code>int</code>.
|
||||
* @param i an {@code int}.
|
||||
* @return a reference to this object.
|
||||
*/
|
||||
public AbstractStringBuilder append(int i) {
|
||||
@ -618,14 +622,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of the <code>long</code>
|
||||
* Appends the string representation of the {@code long}
|
||||
* argument to this sequence.
|
||||
* <p>
|
||||
* The argument is converted to a string as if by the method
|
||||
* <code>String.valueOf</code>, and the characters of that
|
||||
* string are then appended to this sequence.
|
||||
* The overall effect is exactly as if the argument were converted
|
||||
* to a string by the method {@link String#valueOf(long)},
|
||||
* and the characters of that string were then
|
||||
* {@link #append(String) appended} to this character sequence.
|
||||
*
|
||||
* @param l a <code>long</code>.
|
||||
* @param l a {@code long}.
|
||||
* @return a reference to this object.
|
||||
*/
|
||||
public AbstractStringBuilder append(long l) {
|
||||
@ -644,14 +649,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of the <code>float</code>
|
||||
* Appends the string representation of the {@code float}
|
||||
* argument to this sequence.
|
||||
* <p>
|
||||
* The argument is converted to a string as if by the method
|
||||
* <code>String.valueOf</code>, and the characters of that
|
||||
* string are then appended to this string sequence.
|
||||
* The overall effect is exactly as if the argument were converted
|
||||
* to a string by the method {@link String#valueOf(float)},
|
||||
* and the characters of that string were then
|
||||
* {@link #append(String) appended} to this character sequence.
|
||||
*
|
||||
* @param f a <code>float</code>.
|
||||
* @param f a {@code float}.
|
||||
* @return a reference to this object.
|
||||
*/
|
||||
public AbstractStringBuilder append(float f) {
|
||||
@ -660,14 +666,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of the <code>double</code>
|
||||
* Appends the string representation of the {@code double}
|
||||
* argument to this sequence.
|
||||
* <p>
|
||||
* The argument is converted to a string as if by the method
|
||||
* <code>String.valueOf</code>, and the characters of that
|
||||
* string are then appended to this sequence.
|
||||
* The overall effect is exactly as if the argument were converted
|
||||
* to a string by the method {@link String#valueOf(double)},
|
||||
* and the characters of that string were then
|
||||
* {@link #append(String) appended} to this character sequence.
|
||||
*
|
||||
* @param d a <code>double</code>.
|
||||
* @param d a {@code double}.
|
||||
* @return a reference to this object.
|
||||
*/
|
||||
public AbstractStringBuilder append(double d) {
|
||||
@ -677,17 +684,17 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
|
||||
/**
|
||||
* Removes the characters in a substring of this sequence.
|
||||
* The substring begins at the specified <code>start</code> and extends to
|
||||
* the character at index <code>end - 1</code> or to the end of the
|
||||
* The substring begins at the specified {@code start} and extends to
|
||||
* the character at index {@code end - 1} or to the end of the
|
||||
* sequence if no such character exists. If
|
||||
* <code>start</code> is equal to <code>end</code>, no changes are made.
|
||||
* {@code start} is equal to {@code end}, no changes are made.
|
||||
*
|
||||
* @param start The beginning index, inclusive.
|
||||
* @param end The ending index, exclusive.
|
||||
* @return This object.
|
||||
* @throws StringIndexOutOfBoundsException if <code>start</code>
|
||||
* is negative, greater than <code>length()</code>, or
|
||||
* greater than <code>end</code>.
|
||||
* @throws StringIndexOutOfBoundsException if {@code start}
|
||||
* is negative, greater than {@code length()}, or
|
||||
* greater than {@code end}.
|
||||
*/
|
||||
public AbstractStringBuilder delete(int start, int end) {
|
||||
if (start < 0)
|
||||
@ -705,7 +712,7 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the string representation of the <code>codePoint</code>
|
||||
* Appends the string representation of the {@code codePoint}
|
||||
* argument to this sequence.
|
||||
*
|
||||
* <p> The argument is appended to the contents of this sequence.
|
||||
@ -713,15 +720,15 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
* {@link Character#charCount(int) Character.charCount(codePoint)}.
|
||||
*
|
||||
* <p> The overall effect is exactly as if the argument were
|
||||
* converted to a <code>char</code> array by the method {@link
|
||||
* Character#toChars(int)} and the character in that array were
|
||||
* then {@link #append(char[]) appended} to this character
|
||||
* converted to a {@code char} array by the method
|
||||
* {@link Character#toChars(int)} and the character in that array
|
||||
* were then {@link #append(char[]) appended} to this character
|
||||
* sequence.
|
||||
*
|
||||
* @param codePoint a Unicode code point
|
||||
* @return a reference to this object.
|
||||
* @exception IllegalArgumentException if the specified
|
||||
* <code>codePoint</code> isn't a valid Unicode code point
|
||||
* {@code codePoint} isn't a valid Unicode code point
|
||||
*/
|
||||
public AbstractStringBuilder appendCodePoint(int codePoint) {
|
||||
if (!Character.isValidCodePoint(codePoint)) {
|
||||
@ -879,27 +886,27 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the string representation of a subarray of the <code>str</code>
|
||||
* Inserts the string representation of a subarray of the {@code str}
|
||||
* array argument into this sequence. The subarray begins at the
|
||||
* specified <code>offset</code> and extends <code>len</code> <code>char</code>s.
|
||||
* specified {@code offset} and extends {@code len} {@code char}s.
|
||||
* The characters of the subarray are inserted into this sequence at
|
||||
* the position indicated by <code>index</code>. The length of this
|
||||
* sequence increases by <code>len</code> <code>char</code>s.
|
||||
* the position indicated by {@code index}. The length of this
|
||||
* sequence increases by {@code len} {@code char}s.
|
||||
*
|
||||
* @param index position at which to insert subarray.
|
||||
* @param str A <code>char</code> array.
|
||||
* @param offset the index of the first <code>char</code> in subarray to
|
||||
* @param str A {@code char} array.
|
||||
* @param offset the index of the first {@code char} in subarray to
|
||||
* be inserted.
|
||||
* @param len the number of <code>char</code>s in the subarray to
|
||||
* @param len the number of {@code char}s in the subarray to
|
||||
* be inserted.
|
||||
* @return This object
|
||||
* @throws StringIndexOutOfBoundsException if <code>index</code>
|
||||
* is negative or greater than <code>length()</code>, or
|
||||
* <code>offset</code> or <code>len</code> are negative, or
|
||||
* <code>(offset+len)</code> is greater than
|
||||
* <code>str.length</code>.
|
||||
* @throws StringIndexOutOfBoundsException if {@code index}
|
||||
* is negative or greater than {@code length()}, or
|
||||
* {@code offset} or {@code len} are negative, or
|
||||
* {@code (offset+len)} is greater than
|
||||
* {@code str.length}.
|
||||
*/
|
||||
public AbstractStringBuilder insert(int index, char str[], int offset,
|
||||
public AbstractStringBuilder insert(int index, char[] str, int offset,
|
||||
int len)
|
||||
{
|
||||
if ((index < 0) || (index > length()))
|
||||
@ -918,20 +925,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the string representation of the <code>Object</code>
|
||||
* Inserts the string representation of the {@code Object}
|
||||
* argument into this character sequence.
|
||||
* <p>
|
||||
* The second argument is converted to a string as if by the method
|
||||
* <code>String.valueOf</code>, and the characters of that
|
||||
* string are then inserted into this sequence at the indicated
|
||||
* offset.
|
||||
* The overall effect is exactly as if the second argument were
|
||||
* converted to a string by the method {@link String#valueOf(Object)},
|
||||
* and the characters of that string were then
|
||||
* {@link #insert(int,String) inserted} into this character
|
||||
* sequence at the indicated offset.
|
||||
* <p>
|
||||
* The offset argument must be greater than or equal to
|
||||
* <code>0</code>, and less than or equal to the length of this
|
||||
* sequence.
|
||||
* The {@code offset} argument must be greater than or equal to
|
||||
* {@code 0}, and less than or equal to the {@linkplain #length() length}
|
||||
* of this sequence.
|
||||
*
|
||||
* @param offset the offset.
|
||||
* @param obj an <code>Object</code>.
|
||||
* @param obj an {@code Object}.
|
||||
* @return a reference to this object.
|
||||
* @throws StringIndexOutOfBoundsException if the offset is invalid.
|
||||
*/
|
||||
@ -942,28 +950,28 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
/**
|
||||
* Inserts the string into this character sequence.
|
||||
* <p>
|
||||
* The characters of the <code>String</code> argument are inserted, in
|
||||
* The characters of the {@code String} argument are inserted, in
|
||||
* order, into this sequence at the indicated offset, moving up any
|
||||
* characters originally above that position and increasing the length
|
||||
* of this sequence by the length of the argument. If
|
||||
* <code>str</code> is <code>null</code>, then the four characters
|
||||
* <code>"null"</code> are inserted into this sequence.
|
||||
* {@code str} is {@code null}, then the four characters
|
||||
* {@code "null"} are inserted into this sequence.
|
||||
* <p>
|
||||
* The character at index <i>k</i> in the new character sequence is
|
||||
* equal to:
|
||||
* <ul>
|
||||
* <li>the character at index <i>k</i> in the old character sequence, if
|
||||
* <i>k</i> is less than <code>offset</code>
|
||||
* <li>the character at index <i>k</i><code>-offset</code> in the
|
||||
* argument <code>str</code>, if <i>k</i> is not less than
|
||||
* <code>offset</code> but is less than <code>offset+str.length()</code>
|
||||
* <li>the character at index <i>k</i><code>-str.length()</code> in the
|
||||
* <i>k</i> is less than {@code offset}
|
||||
* <li>the character at index <i>k</i>{@code -offset} in the
|
||||
* argument {@code str}, if <i>k</i> is not less than
|
||||
* {@code offset} but is less than {@code offset+str.length()}
|
||||
* <li>the character at index <i>k</i>{@code -str.length()} in the
|
||||
* old character sequence, if <i>k</i> is not less than
|
||||
* <code>offset+str.length()</code>
|
||||
* {@code offset+str.length()}
|
||||
* </ul><p>
|
||||
* The offset argument must be greater than or equal to
|
||||
* <code>0</code>, and less than or equal to the length of this
|
||||
* sequence.
|
||||
* The {@code offset} argument must be greater than or equal to
|
||||
* {@code 0}, and less than or equal to the {@linkplain #length() length}
|
||||
* of this sequence.
|
||||
*
|
||||
* @param offset the offset.
|
||||
* @param str a string.
|
||||
@ -986,27 +994,30 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the string representation of the <code>char</code> array
|
||||
* Inserts the string representation of the {@code char} array
|
||||
* argument into this sequence.
|
||||
* <p>
|
||||
* The characters of the array argument are inserted into the
|
||||
* contents of this sequence at the position indicated by
|
||||
* <code>offset</code>. The length of this sequence increases by
|
||||
* {@code offset}. The length of this sequence increases by
|
||||
* the length of the argument.
|
||||
* <p>
|
||||
* The overall effect is exactly as if the argument were converted to
|
||||
* a string by the method {@link String#valueOf(char[])} and the
|
||||
* characters of that string were then
|
||||
* {@link #insert(int,String) inserted} into this
|
||||
* character sequence at the position indicated by
|
||||
* <code>offset</code>.
|
||||
* The overall effect is exactly as if the second argument were
|
||||
* converted to a string by the method {@link String#valueOf(char[])},
|
||||
* and the characters of that string were then
|
||||
* {@link #insert(int,String) inserted} into this character
|
||||
* sequence at the indicated offset.
|
||||
* <p>
|
||||
* The {@code offset} argument must be greater than or equal to
|
||||
* {@code 0}, and less than or equal to the {@linkplain #length() length}
|
||||
* of this sequence.
|
||||
*
|
||||
* @param offset the offset.
|
||||
* @param str a character array.
|
||||
* @return a reference to this object.
|
||||
* @throws StringIndexOutOfBoundsException if the offset is invalid.
|
||||
*/
|
||||
public AbstractStringBuilder insert(int offset, char str[]) {
|
||||
public AbstractStringBuilder insert(int offset, char[] str) {
|
||||
if ((offset < 0) || (offset > length()))
|
||||
throw new StringIndexOutOfBoundsException(offset);
|
||||
int len = str.length;
|
||||
@ -1020,18 +1031,20 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the specified <code>CharSequence</code> into this sequence.
|
||||
* Inserts the specified {@code CharSequence} into this sequence.
|
||||
* <p>
|
||||
* The characters of the <code>CharSequence</code> argument are inserted,
|
||||
* The characters of the {@code CharSequence} argument are inserted,
|
||||
* in order, into this sequence at the indicated offset, moving up
|
||||
* any characters originally above that position and increasing the length
|
||||
* of this sequence by the length of the argument s.
|
||||
* <p>
|
||||
* The result of this method is exactly the same as if it were an
|
||||
* invocation of this object's insert(dstOffset, s, 0, s.length()) method.
|
||||
* invocation of this object's
|
||||
* {@link #insert(int,CharSequence,int,int) insert}(dstOffset, s, 0, s.length())
|
||||
* method.
|
||||
*
|
||||
* <p>If <code>s</code> is <code>null</code>, then the four characters
|
||||
* <code>"null"</code> are inserted into this sequence.
|
||||
* <p>If {@code s} is {@code null}, then the four characters
|
||||
* {@code "null"} are inserted into this sequence.
|
||||
*
|
||||
* @param dstOffset the offset.
|
||||
* @param s the sequence to be inserted
|
||||
@ -1047,51 +1060,51 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a subsequence of the specified <code>CharSequence</code> into
|
||||
* Inserts a subsequence of the specified {@code CharSequence} into
|
||||
* this sequence.
|
||||
* <p>
|
||||
* The subsequence of the argument <code>s</code> specified by
|
||||
* <code>start</code> and <code>end</code> are inserted,
|
||||
* The subsequence of the argument {@code s} specified by
|
||||
* {@code start} and {@code end} are inserted,
|
||||
* in order, into this sequence at the specified destination offset, moving
|
||||
* up any characters originally above that position. The length of this
|
||||
* sequence is increased by <code>end - start</code>.
|
||||
* sequence is increased by {@code end - start}.
|
||||
* <p>
|
||||
* The character at index <i>k</i> in this sequence becomes equal to:
|
||||
* <ul>
|
||||
* <li>the character at index <i>k</i> in this sequence, if
|
||||
* <i>k</i> is less than <code>dstOffset</code>
|
||||
* <li>the character at index <i>k</i><code>+start-dstOffset</code> in
|
||||
* the argument <code>s</code>, if <i>k</i> is greater than or equal to
|
||||
* <code>dstOffset</code> but is less than <code>dstOffset+end-start</code>
|
||||
* <li>the character at index <i>k</i><code>-(end-start)</code> in this
|
||||
* <i>k</i> is less than {@code dstOffset}
|
||||
* <li>the character at index <i>k</i>{@code +start-dstOffset} in
|
||||
* the argument {@code s}, if <i>k</i> is greater than or equal to
|
||||
* {@code dstOffset} but is less than {@code dstOffset+end-start}
|
||||
* <li>the character at index <i>k</i>{@code -(end-start)} in this
|
||||
* sequence, if <i>k</i> is greater than or equal to
|
||||
* <code>dstOffset+end-start</code>
|
||||
* {@code dstOffset+end-start}
|
||||
* </ul><p>
|
||||
* The dstOffset argument must be greater than or equal to
|
||||
* <code>0</code>, and less than or equal to the length of this
|
||||
* sequence.
|
||||
* The {@code dstOffset} argument must be greater than or equal to
|
||||
* {@code 0}, and less than or equal to the {@linkplain #length() length}
|
||||
* of this sequence.
|
||||
* <p>The start argument must be nonnegative, and not greater than
|
||||
* <code>end</code>.
|
||||
* {@code end}.
|
||||
* <p>The end argument must be greater than or equal to
|
||||
* <code>start</code>, and less than or equal to the length of s.
|
||||
* {@code start}, and less than or equal to the length of s.
|
||||
*
|
||||
* <p>If <code>s</code> is <code>null</code>, then this method inserts
|
||||
* <p>If {@code s} is {@code null}, then this method inserts
|
||||
* characters as if the s parameter was a sequence containing the four
|
||||
* characters <code>"null"</code>.
|
||||
* characters {@code "null"}.
|
||||
*
|
||||
* @param dstOffset the offset in this sequence.
|
||||
* @param s the sequence to be inserted.
|
||||
* @param start the starting index of the subsequence to be inserted.
|
||||
* @param end the end index of the subsequence to be inserted.
|
||||
* @return a reference to this object.
|
||||
* @throws IndexOutOfBoundsException if <code>dstOffset</code>
|
||||
* is negative or greater than <code>this.length()</code>, or
|
||||
* <code>start</code> or <code>end</code> are negative, or
|
||||
* <code>start</code> is greater than <code>end</code> or
|
||||
* <code>end</code> is greater than <code>s.length()</code>
|
||||
* @throws IndexOutOfBoundsException if {@code dstOffset}
|
||||
* is negative or greater than {@code this.length()}, or
|
||||
* {@code start} or {@code end} are negative, or
|
||||
* {@code start} is greater than {@code end} or
|
||||
* {@code end} is greater than {@code s.length()}
|
||||
*/
|
||||
public AbstractStringBuilder insert(int dstOffset, CharSequence s,
|
||||
int start, int end) {
|
||||
int start, int end) {
|
||||
if (s == null)
|
||||
s = "null";
|
||||
if ((dstOffset < 0) || (dstOffset > this.length()))
|
||||
@ -1115,20 +1128,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the string representation of the <code>boolean</code>
|
||||
* Inserts the string representation of the {@code boolean}
|
||||
* argument into this sequence.
|
||||
* <p>
|
||||
* The second argument is converted to a string as if by the method
|
||||
* <code>String.valueOf</code>, and the characters of that
|
||||
* string are then inserted into this sequence at the indicated
|
||||
* offset.
|
||||
* The overall effect is exactly as if the second argument were
|
||||
* converted to a string by the method {@link String#valueOf(boolean)},
|
||||
* and the characters of that string were then
|
||||
* {@link #insert(int,String) inserted} into this character
|
||||
* sequence at the indicated offset.
|
||||
* <p>
|
||||
* The offset argument must be greater than or equal to
|
||||
* <code>0</code>, and less than or equal to the length of this
|
||||
* sequence.
|
||||
* The {@code offset} argument must be greater than or equal to
|
||||
* {@code 0}, and less than or equal to the {@linkplain #length() length}
|
||||
* of this sequence.
|
||||
*
|
||||
* @param offset the offset.
|
||||
* @param b a <code>boolean</code>.
|
||||
* @param b a {@code boolean}.
|
||||
* @return a reference to this object.
|
||||
* @throws StringIndexOutOfBoundsException if the offset is invalid.
|
||||
*/
|
||||
@ -1137,25 +1151,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the string representation of the <code>char</code>
|
||||
* Inserts the string representation of the {@code char}
|
||||
* argument into this sequence.
|
||||
* <p>
|
||||
* The second argument is inserted into the contents of this sequence
|
||||
* at the position indicated by <code>offset</code>. The length
|
||||
* of this sequence increases by one.
|
||||
* The overall effect is exactly as if the second argument were
|
||||
* converted to a string by the method {@link String#valueOf(char)},
|
||||
* and the character in that string were then
|
||||
* {@link #insert(int,String) inserted} into this character
|
||||
* sequence at the indicated offset.
|
||||
* <p>
|
||||
* The overall effect is exactly as if the argument were converted to
|
||||
* a string by the method {@link String#valueOf(char)} and the character
|
||||
* in that string were then {@link #insert(int, String) inserted} into
|
||||
* this character sequence at the position indicated by
|
||||
* <code>offset</code>.
|
||||
* <p>
|
||||
* The offset argument must be greater than or equal to
|
||||
* <code>0</code>, and less than or equal to the length of this
|
||||
* sequence.
|
||||
* The {@code offset} argument must be greater than or equal to
|
||||
* {@code 0}, and less than or equal to the {@linkplain #length() length}
|
||||
* of this sequence.
|
||||
*
|
||||
* @param offset the offset.
|
||||
* @param c a <code>char</code>.
|
||||
* @param c a {@code char}.
|
||||
* @return a reference to this object.
|
||||
* @throws IndexOutOfBoundsException if the offset is invalid.
|
||||
*/
|
||||
@ -1170,20 +1180,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the string representation of the second <code>int</code>
|
||||
* Inserts the string representation of the second {@code int}
|
||||
* argument into this sequence.
|
||||
* <p>
|
||||
* The second argument is converted to a string as if by the method
|
||||
* <code>String.valueOf</code>, and the characters of that
|
||||
* string are then inserted into this sequence at the indicated
|
||||
* offset.
|
||||
* The overall effect is exactly as if the second argument were
|
||||
* converted to a string by the method {@link String#valueOf(int)},
|
||||
* and the characters of that string were then
|
||||
* {@link #insert(int,String) inserted} into this character
|
||||
* sequence at the indicated offset.
|
||||
* <p>
|
||||
* The offset argument must be greater than or equal to
|
||||
* <code>0</code>, and less than or equal to the length of this
|
||||
* sequence.
|
||||
* The {@code offset} argument must be greater than or equal to
|
||||
* {@code 0}, and less than or equal to the {@linkplain #length() length}
|
||||
* of this sequence.
|
||||
*
|
||||
* @param offset the offset.
|
||||
* @param i an <code>int</code>.
|
||||
* @param i an {@code int}.
|
||||
* @return a reference to this object.
|
||||
* @throws StringIndexOutOfBoundsException if the offset is invalid.
|
||||
*/
|
||||
@ -1192,20 +1203,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the string representation of the <code>long</code>
|
||||
* Inserts the string representation of the {@code long}
|
||||
* argument into this sequence.
|
||||
* <p>
|
||||
* The second argument is converted to a string as if by the method
|
||||
* <code>String.valueOf</code>, and the characters of that
|
||||
* string are then inserted into this sequence at the position
|
||||
* indicated by <code>offset</code>.
|
||||
* The overall effect is exactly as if the second argument were
|
||||
* converted to a string by the method {@link String#valueOf(long)},
|
||||
* and the characters of that string were then
|
||||
* {@link #insert(int,String) inserted} into this character
|
||||
* sequence at the indicated offset.
|
||||
* <p>
|
||||
* The offset argument must be greater than or equal to
|
||||
* <code>0</code>, and less than or equal to the length of this
|
||||
* sequence.
|
||||
* The {@code offset} argument must be greater than or equal to
|
||||
* {@code 0}, and less than or equal to the {@linkplain #length() length}
|
||||
* of this sequence.
|
||||
*
|
||||
* @param offset the offset.
|
||||
* @param l a <code>long</code>.
|
||||
* @param l a {@code long}.
|
||||
* @return a reference to this object.
|
||||
* @throws StringIndexOutOfBoundsException if the offset is invalid.
|
||||
*/
|
||||
@ -1214,20 +1226,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the string representation of the <code>float</code>
|
||||
* Inserts the string representation of the {@code float}
|
||||
* argument into this sequence.
|
||||
* <p>
|
||||
* The second argument is converted to a string as if by the method
|
||||
* <code>String.valueOf</code>, and the characters of that
|
||||
* string are then inserted into this sequence at the indicated
|
||||
* offset.
|
||||
* The overall effect is exactly as if the second argument were
|
||||
* converted to a string by the method {@link String#valueOf(float)},
|
||||
* and the characters of that string were then
|
||||
* {@link #insert(int,String) inserted} into this character
|
||||
* sequence at the indicated offset.
|
||||
* <p>
|
||||
* The offset argument must be greater than or equal to
|
||||
* <code>0</code>, and less than or equal to the length of this
|
||||
* sequence.
|
||||
* The {@code offset} argument must be greater than or equal to
|
||||
* {@code 0}, and less than or equal to the {@linkplain #length() length}
|
||||
* of this sequence.
|
||||
*
|
||||
* @param offset the offset.
|
||||
* @param f a <code>float</code>.
|
||||
* @param f a {@code float}.
|
||||
* @return a reference to this object.
|
||||
* @throws StringIndexOutOfBoundsException if the offset is invalid.
|
||||
*/
|
||||
@ -1236,20 +1249,21 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts the string representation of the <code>double</code>
|
||||
* Inserts the string representation of the {@code double}
|
||||
* argument into this sequence.
|
||||
* <p>
|
||||
* The second argument is converted to a string as if by the method
|
||||
* <code>String.valueOf</code>, and the characters of that
|
||||
* string are then inserted into this sequence at the indicated
|
||||
* offset.
|
||||
* The overall effect is exactly as if the second argument were
|
||||
* converted to a string by the method {@link String#valueOf(double)},
|
||||
* and the characters of that string were then
|
||||
* {@link #insert(int,String) inserted} into this character
|
||||
* sequence at the indicated offset.
|
||||
* <p>
|
||||
* The offset argument must be greater than or equal to
|
||||
* <code>0</code>, and less than or equal to the length of this
|
||||
* sequence.
|
||||
* The {@code offset} argument must be greater than or equal to
|
||||
* {@code 0}, and less than or equal to the {@linkplain #length() length}
|
||||
* of this sequence.
|
||||
*
|
||||
* @param offset the offset.
|
||||
* @param d a <code>double</code>.
|
||||
* @param d a {@code double}.
|
||||
* @return a reference to this object.
|
||||
* @throws StringIndexOutOfBoundsException if the offset is invalid.
|
||||
*/
|
||||
|
||||
@ -212,7 +212,7 @@ package java.lang;
|
||||
* @throws NullPointerException {@inheritDoc}
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public synchronized void getChars(int srcBegin, int srcEnd, char dst[],
|
||||
public synchronized void getChars(int srcBegin, int srcEnd, char[] dst,
|
||||
int dstBegin)
|
||||
{
|
||||
super.getChars(srcBegin, srcEnd, dst, dstBegin);
|
||||
@ -228,10 +228,6 @@ package java.lang;
|
||||
value[index] = ch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.String#valueOf(java.lang.Object)
|
||||
* @see #append(java.lang.String)
|
||||
*/
|
||||
public synchronized StringBuffer append(Object obj) {
|
||||
super.append(String.valueOf(obj));
|
||||
return this;
|
||||
@ -314,20 +310,19 @@ package java.lang;
|
||||
return this;
|
||||
}
|
||||
|
||||
public synchronized StringBuffer append(char str[]) {
|
||||
public synchronized StringBuffer append(char[] str) {
|
||||
super.append(str);
|
||||
return this;
|
||||
}
|
||||
|
||||
public synchronized StringBuffer append(char str[], int offset, int len) {
|
||||
/**
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public synchronized StringBuffer append(char[] str, int offset, int len) {
|
||||
super.append(str, offset, len);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.String#valueOf(boolean)
|
||||
* @see #append(java.lang.String)
|
||||
*/
|
||||
public synchronized StringBuffer append(boolean b) {
|
||||
super.append(b);
|
||||
return this;
|
||||
@ -338,10 +333,6 @@ package java.lang;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.String#valueOf(int)
|
||||
* @see #append(java.lang.String)
|
||||
*/
|
||||
public synchronized StringBuffer append(int i) {
|
||||
super.append(i);
|
||||
return this;
|
||||
@ -355,28 +346,16 @@ package java.lang;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.String#valueOf(long)
|
||||
* @see #append(java.lang.String)
|
||||
*/
|
||||
public synchronized StringBuffer append(long lng) {
|
||||
super.append(lng);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.String#valueOf(float)
|
||||
* @see #append(java.lang.String)
|
||||
*/
|
||||
public synchronized StringBuffer append(float f) {
|
||||
super.append(f);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.String#valueOf(double)
|
||||
* @see #append(java.lang.String)
|
||||
*/
|
||||
public synchronized StringBuffer append(double d) {
|
||||
super.append(d);
|
||||
return this;
|
||||
@ -437,7 +416,7 @@ package java.lang;
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
* @since 1.2
|
||||
*/
|
||||
public synchronized StringBuffer insert(int index, char str[], int offset,
|
||||
public synchronized StringBuffer insert(int index, char[] str, int offset,
|
||||
int len)
|
||||
{
|
||||
super.insert(index, str, offset, len);
|
||||
@ -446,9 +425,6 @@ package java.lang;
|
||||
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
* @see java.lang.String#valueOf(java.lang.Object)
|
||||
* @see #insert(int, java.lang.String)
|
||||
* @see #length()
|
||||
*/
|
||||
public synchronized StringBuffer insert(int offset, Object obj) {
|
||||
super.insert(offset, String.valueOf(obj));
|
||||
@ -457,7 +433,6 @@ package java.lang;
|
||||
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
* @see #length()
|
||||
*/
|
||||
public synchronized StringBuffer insert(int offset, String str) {
|
||||
super.insert(offset, str);
|
||||
@ -467,7 +442,7 @@ package java.lang;
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public synchronized StringBuffer insert(int offset, char str[]) {
|
||||
public synchronized StringBuffer insert(int offset, char[] str) {
|
||||
super.insert(offset, str);
|
||||
return this;
|
||||
}
|
||||
@ -498,9 +473,6 @@ package java.lang;
|
||||
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
* @see java.lang.String#valueOf(boolean)
|
||||
* @see #insert(int, java.lang.String)
|
||||
* @see #length()
|
||||
*/
|
||||
public StringBuffer insert(int offset, boolean b) {
|
||||
return insert(offset, String.valueOf(b));
|
||||
@ -508,7 +480,6 @@ package java.lang;
|
||||
|
||||
/**
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
* @see #length()
|
||||
*/
|
||||
public synchronized StringBuffer insert(int offset, char c) {
|
||||
super.insert(offset, c);
|
||||
@ -517,9 +488,6 @@ package java.lang;
|
||||
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
* @see java.lang.String#valueOf(int)
|
||||
* @see #insert(int, java.lang.String)
|
||||
* @see #length()
|
||||
*/
|
||||
public StringBuffer insert(int offset, int i) {
|
||||
return insert(offset, String.valueOf(i));
|
||||
@ -527,9 +495,6 @@ package java.lang;
|
||||
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
* @see java.lang.String#valueOf(long)
|
||||
* @see #insert(int, java.lang.String)
|
||||
* @see #length()
|
||||
*/
|
||||
public StringBuffer insert(int offset, long l) {
|
||||
return insert(offset, String.valueOf(l));
|
||||
@ -537,9 +502,6 @@ package java.lang;
|
||||
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
* @see java.lang.String#valueOf(float)
|
||||
* @see #insert(int, java.lang.String)
|
||||
* @see #length()
|
||||
*/
|
||||
public StringBuffer insert(int offset, float f) {
|
||||
return insert(offset, String.valueOf(f));
|
||||
@ -547,9 +509,6 @@ package java.lang;
|
||||
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
* @see java.lang.String#valueOf(double)
|
||||
* @see #insert(int, java.lang.String)
|
||||
* @see #length()
|
||||
*/
|
||||
public StringBuffer insert(int offset, double d) {
|
||||
return insert(offset, String.valueOf(d));
|
||||
|
||||
@ -124,10 +124,6 @@ public final class StringBuilder
|
||||
append(seq);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.String#valueOf(java.lang.Object)
|
||||
* @see #append(java.lang.String)
|
||||
*/
|
||||
public StringBuilder append(Object obj) {
|
||||
return append(String.valueOf(obj));
|
||||
}
|
||||
@ -175,7 +171,6 @@ public final class StringBuilder
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public StringBuilder append(CharSequence s) {
|
||||
if (s == null)
|
||||
@ -197,20 +192,19 @@ public final class StringBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
public StringBuilder append(char str[]) {
|
||||
public StringBuilder append(char[] str) {
|
||||
super.append(str);
|
||||
return this;
|
||||
}
|
||||
|
||||
public StringBuilder append(char str[], int offset, int len) {
|
||||
/**
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public StringBuilder append(char[] str, int offset, int len) {
|
||||
super.append(str, offset, len);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.String#valueOf(boolean)
|
||||
* @see #append(java.lang.String)
|
||||
*/
|
||||
public StringBuilder append(boolean b) {
|
||||
super.append(b);
|
||||
return this;
|
||||
@ -221,37 +215,21 @@ public final class StringBuilder
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.String#valueOf(int)
|
||||
* @see #append(java.lang.String)
|
||||
*/
|
||||
public StringBuilder append(int i) {
|
||||
super.append(i);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.String#valueOf(long)
|
||||
* @see #append(java.lang.String)
|
||||
*/
|
||||
public StringBuilder append(long lng) {
|
||||
super.append(lng);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.String#valueOf(float)
|
||||
* @see #append(java.lang.String)
|
||||
*/
|
||||
public StringBuilder append(float f) {
|
||||
super.append(f);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see java.lang.String#valueOf(double)
|
||||
* @see #append(java.lang.String)
|
||||
*/
|
||||
public StringBuilder append(double d) {
|
||||
super.append(d);
|
||||
return this;
|
||||
@ -292,7 +270,7 @@ public final class StringBuilder
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public StringBuilder insert(int index, char str[], int offset,
|
||||
public StringBuilder insert(int index, char[] str, int offset,
|
||||
int len)
|
||||
{
|
||||
super.insert(index, str, offset, len);
|
||||
@ -301,9 +279,6 @@ public final class StringBuilder
|
||||
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
* @see java.lang.String#valueOf(java.lang.Object)
|
||||
* @see #insert(int, java.lang.String)
|
||||
* @see #length()
|
||||
*/
|
||||
public StringBuilder insert(int offset, Object obj) {
|
||||
return insert(offset, String.valueOf(obj));
|
||||
@ -311,7 +286,6 @@ public final class StringBuilder
|
||||
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
* @see #length()
|
||||
*/
|
||||
public StringBuilder insert(int offset, String str) {
|
||||
super.insert(offset, str);
|
||||
@ -321,7 +295,7 @@ public final class StringBuilder
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
*/
|
||||
public StringBuilder insert(int offset, char str[]) {
|
||||
public StringBuilder insert(int offset, char[] str) {
|
||||
super.insert(offset, str);
|
||||
return this;
|
||||
}
|
||||
@ -349,9 +323,6 @@ public final class StringBuilder
|
||||
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
* @see java.lang.String#valueOf(boolean)
|
||||
* @see #insert(int, java.lang.String)
|
||||
* @see #length()
|
||||
*/
|
||||
public StringBuilder insert(int offset, boolean b) {
|
||||
super.insert(offset, b);
|
||||
@ -360,7 +331,6 @@ public final class StringBuilder
|
||||
|
||||
/**
|
||||
* @throws IndexOutOfBoundsException {@inheritDoc}
|
||||
* @see #length()
|
||||
*/
|
||||
public StringBuilder insert(int offset, char c) {
|
||||
super.insert(offset, c);
|
||||
@ -369,9 +339,6 @@ public final class StringBuilder
|
||||
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
* @see java.lang.String#valueOf(int)
|
||||
* @see #insert(int, java.lang.String)
|
||||
* @see #length()
|
||||
*/
|
||||
public StringBuilder insert(int offset, int i) {
|
||||
return insert(offset, String.valueOf(i));
|
||||
@ -379,9 +346,6 @@ public final class StringBuilder
|
||||
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
* @see java.lang.String#valueOf(long)
|
||||
* @see #insert(int, java.lang.String)
|
||||
* @see #length()
|
||||
*/
|
||||
public StringBuilder insert(int offset, long l) {
|
||||
return insert(offset, String.valueOf(l));
|
||||
@ -389,9 +353,6 @@ public final class StringBuilder
|
||||
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
* @see java.lang.String#valueOf(float)
|
||||
* @see #insert(int, java.lang.String)
|
||||
* @see #length()
|
||||
*/
|
||||
public StringBuilder insert(int offset, float f) {
|
||||
return insert(offset, String.valueOf(f));
|
||||
@ -399,9 +360,6 @@ public final class StringBuilder
|
||||
|
||||
/**
|
||||
* @throws StringIndexOutOfBoundsException {@inheritDoc}
|
||||
* @see java.lang.String#valueOf(double)
|
||||
* @see #insert(int, java.lang.String)
|
||||
* @see #length()
|
||||
*/
|
||||
public StringBuilder insert(int offset, double d) {
|
||||
return insert(offset, String.valueOf(d));
|
||||
|
||||
@ -388,7 +388,7 @@ enum PlatformComponent {
|
||||
// if there are more than 1 key properties (i.e. other than "type")
|
||||
domainAndType += ",*";
|
||||
}
|
||||
ObjectName on = com.sun.jmx.mbeanserver.Util.newObjectName(domainAndType);
|
||||
ObjectName on = ObjectName.valueOf(domainAndType);
|
||||
Set<ObjectName> set = mbs.queryNames(on, null);
|
||||
for (PlatformComponent pc : subComponents) {
|
||||
set.addAll(pc.getObjectNames(mbs));
|
||||
|
||||
@ -75,6 +75,7 @@ public final class HttpCookie implements Cloneable {
|
||||
private String path; // Path=VALUE ... URLs that see the cookie
|
||||
private String portlist; // Port[="portlist"] ... the port cookie may be returned to
|
||||
private boolean secure; // Secure ... e.g. use SSL
|
||||
private boolean httpOnly; // HttpOnly ... i.e. not accessible to scripts
|
||||
private int version = 1; // Version=1 ... RFC 2965 style
|
||||
|
||||
//
|
||||
@ -656,6 +657,32 @@ public final class HttpCookie implements Cloneable {
|
||||
version = v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns {@code true} if this cookie contains the <i>HttpOnly</i>
|
||||
* attribute. This means that the cookie should not be accessible to
|
||||
* scripting engines, like javascript.
|
||||
*
|
||||
* @return {@code true} if this cookie should be considered http only.
|
||||
* @see #setHttpOnly(boolean)
|
||||
*/
|
||||
public boolean isHttpOnly()
|
||||
{
|
||||
return httpOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the cookie should be considered HTTP Only. If set to
|
||||
* {@code true} it means the cookie should not be accessible to scripting
|
||||
* engines like javascript.
|
||||
*
|
||||
* @param httpOnly if {@code true} make the cookie HTTP only, i.e.
|
||||
* only visible as part of an HTTP request.
|
||||
* @see #isHttpOnly()
|
||||
*/
|
||||
public void setHttpOnly(boolean httpOnly)
|
||||
{
|
||||
this.httpOnly = httpOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* The utility method to check whether a host name is in a domain
|
||||
@ -877,6 +904,7 @@ public final class HttpCookie implements Cloneable {
|
||||
|| name.equalsIgnoreCase("Port") // rfc2965 only
|
||||
|| name.equalsIgnoreCase("Secure")
|
||||
|| name.equalsIgnoreCase("Version")
|
||||
|| name.equalsIgnoreCase("HttpOnly")
|
||||
|| name.charAt(0) == '$')
|
||||
{
|
||||
return true;
|
||||
@ -996,6 +1024,11 @@ public final class HttpCookie implements Cloneable {
|
||||
cookie.setSecure(true);
|
||||
}
|
||||
});
|
||||
assignors.put("httponly", new CookieAttributeAssignor(){
|
||||
public void assign(HttpCookie cookie, String attrName, String attrValue) {
|
||||
cookie.setHttpOnly(true);
|
||||
}
|
||||
});
|
||||
assignors.put("version", new CookieAttributeAssignor(){
|
||||
public void assign(HttpCookie cookie, String attrName, String attrValue) {
|
||||
try {
|
||||
|
||||
@ -186,7 +186,7 @@ class ByteBufferAs$Type$Buffer$RW$$BO$ // package-private
|
||||
|
||||
// --- Methods to support CharSequence ---
|
||||
|
||||
public CharSequence subSequence(int start, int end) {
|
||||
public CharBuffer subSequence(int start, int end) {
|
||||
int pos = position();
|
||||
int lim = limit();
|
||||
assert (pos <= lim);
|
||||
|
||||
@ -402,7 +402,7 @@ class Direct$Type$Buffer$RW$$BO$
|
||||
|
||||
// --- Methods to support CharSequence ---
|
||||
|
||||
public CharSequence subSequence(int start, int end) {
|
||||
public CharBuffer subSequence(int start, int end) {
|
||||
int pos = position();
|
||||
int lim = limit();
|
||||
assert (pos <= lim);
|
||||
|
||||
@ -566,7 +566,7 @@ class Heap$Type$Buffer$RW$
|
||||
|
||||
// --- Methods to support CharSequence ---
|
||||
|
||||
public CharSequence subSequence(int start, int end) {
|
||||
public CharBuffer subSequence(int start, int end) {
|
||||
if ((start < 0)
|
||||
|| (end > length())
|
||||
|| (start > end))
|
||||
|
||||
@ -99,7 +99,7 @@ class StringCharBuffer // package-private
|
||||
return str.toString().substring(start + offset, end + offset);
|
||||
}
|
||||
|
||||
public final CharSequence subSequence(int start, int end) {
|
||||
public final CharBuffer subSequence(int start, int end) {
|
||||
try {
|
||||
int pos = position();
|
||||
return new StringCharBuffer(str, -1,
|
||||
|
||||
@ -1239,13 +1239,13 @@ public abstract class $Type$Buffer
|
||||
* smaller than <tt>start</tt> and no larger than
|
||||
* <tt>remaining()</tt>
|
||||
*
|
||||
* @return The new character sequence
|
||||
* @return The new character buffer
|
||||
*
|
||||
* @throws IndexOutOfBoundsException
|
||||
* If the preconditions on <tt>start</tt> and <tt>end</tt>
|
||||
* do not hold
|
||||
*/
|
||||
public abstract CharSequence subSequence(int start, int end);
|
||||
public abstract CharBuffer subSequence(int start, int end);
|
||||
|
||||
|
||||
// --- Methods to support Appendable ---
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. 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
|
||||
@ -25,6 +25,9 @@
|
||||
|
||||
package java.security.cert;
|
||||
|
||||
import java.io.InvalidObjectException;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.security.GeneralSecurityException;
|
||||
|
||||
/**
|
||||
@ -36,10 +39,11 @@ import java.security.GeneralSecurityException;
|
||||
* if any, that caused this exception to be thrown.
|
||||
* <p>
|
||||
* A <code>CertPathValidatorException</code> may also include the
|
||||
* certification path that was being validated when the exception was thrown
|
||||
* and the index of the certificate in the certification path that caused the
|
||||
* exception to be thrown. Use the {@link #getCertPath getCertPath} and
|
||||
* {@link #getIndex getIndex} methods to retrieve this information.
|
||||
* certification path that was being validated when the exception was thrown,
|
||||
* the index of the certificate in the certification path that caused the
|
||||
* exception to be thrown, and the reason that caused the failure. Use the
|
||||
* {@link #getCertPath getCertPath}, {@link #getIndex getIndex}, and
|
||||
* {@link #getReason getReason} methods to retrieve this information.
|
||||
*
|
||||
* <p>
|
||||
* <b>Concurrent Access</b>
|
||||
@ -71,12 +75,17 @@ public class CertPathValidatorException extends GeneralSecurityException {
|
||||
*/
|
||||
private CertPath certPath;
|
||||
|
||||
/**
|
||||
* @serial the reason the validation failed
|
||||
*/
|
||||
private Reason reason = BasicReason.UNSPECIFIED;
|
||||
|
||||
/**
|
||||
* Creates a <code>CertPathValidatorException</code> with
|
||||
* no detail message.
|
||||
*/
|
||||
public CertPathValidatorException() {
|
||||
super();
|
||||
this(null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,7 +96,7 @@ public class CertPathValidatorException extends GeneralSecurityException {
|
||||
* @param msg the detail message
|
||||
*/
|
||||
public CertPathValidatorException(String msg) {
|
||||
super(msg);
|
||||
this(msg, null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -104,7 +113,7 @@ public class CertPathValidatorException extends GeneralSecurityException {
|
||||
* permitted, and indicates that the cause is nonexistent or unknown.)
|
||||
*/
|
||||
public CertPathValidatorException(Throwable cause) {
|
||||
super(cause);
|
||||
this(null, cause);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -117,7 +126,7 @@ public class CertPathValidatorException extends GeneralSecurityException {
|
||||
* permitted, and indicates that the cause is nonexistent or unknown.)
|
||||
*/
|
||||
public CertPathValidatorException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
this(msg, cause, null, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,6 +148,32 @@ public class CertPathValidatorException extends GeneralSecurityException {
|
||||
*/
|
||||
public CertPathValidatorException(String msg, Throwable cause,
|
||||
CertPath certPath, int index) {
|
||||
this(msg, cause, certPath, index, BasicReason.UNSPECIFIED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a <code>CertPathValidatorException</code> with the specified
|
||||
* detail message, cause, certification path, index, and reason.
|
||||
*
|
||||
* @param msg the detail message (or <code>null</code> if none)
|
||||
* @param cause the cause (or <code>null</code> if none)
|
||||
* @param certPath the certification path that was in the process of
|
||||
* being validated when the error was encountered
|
||||
* @param index the index of the certificate in the certification path
|
||||
* that caused the error (or -1 if not applicable). Note that
|
||||
* the list of certificates in a <code>CertPath</code> is zero based.
|
||||
* @param reason the reason the validation failed
|
||||
* @throws IndexOutOfBoundsException if the index is out of range
|
||||
* <code>(index < -1 || (certPath != null && index >=
|
||||
* certPath.getCertificates().size())</code>
|
||||
* @throws IllegalArgumentException if <code>certPath</code> is
|
||||
* <code>null</code> and <code>index</code> is not -1
|
||||
* @throws NullPointerException if <code>reason</code> is <code>null</code>
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public CertPathValidatorException(String msg, Throwable cause,
|
||||
CertPath certPath, int index, Reason reason) {
|
||||
super(msg, cause);
|
||||
if (certPath == null && index != -1) {
|
||||
throw new IllegalArgumentException();
|
||||
@ -147,8 +182,12 @@ public class CertPathValidatorException extends GeneralSecurityException {
|
||||
(certPath != null && index >= certPath.getCertificates().size())) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
if (reason == null) {
|
||||
throw new NullPointerException("reason can't be null");
|
||||
}
|
||||
this.certPath = certPath;
|
||||
this.index = index;
|
||||
this.reason = reason;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -174,4 +213,79 @@ public class CertPathValidatorException extends GeneralSecurityException {
|
||||
return this.index;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the reason that the validation failed. The reason is
|
||||
* associated with the index of the certificate returned by
|
||||
* {@link getIndex}.
|
||||
*
|
||||
* @return the reason that the validation failed, or
|
||||
* <code>BasicReason.UNSPECIFIED</code> if a reason has not been
|
||||
* specified
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public Reason getReason() {
|
||||
return this.reason;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream stream)
|
||||
throws ClassNotFoundException, IOException {
|
||||
stream.defaultReadObject();
|
||||
if (reason == null) {
|
||||
reason = BasicReason.UNSPECIFIED;
|
||||
}
|
||||
if (certPath == null && index != -1) {
|
||||
throw new InvalidObjectException("certpath is null and index != -1");
|
||||
}
|
||||
if (index < -1 ||
|
||||
(certPath != null && index >= certPath.getCertificates().size())) {
|
||||
throw new InvalidObjectException("index out of range");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The reason the validation algorithm failed.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public static interface Reason extends java.io.Serializable { }
|
||||
|
||||
|
||||
/**
|
||||
* The BasicReason enumerates the potential reasons that a certification
|
||||
* path of any type may be invalid.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public static enum BasicReason implements Reason {
|
||||
/**
|
||||
* Unspecified reason.
|
||||
*/
|
||||
UNSPECIFIED,
|
||||
|
||||
/**
|
||||
* The certificate is expired.
|
||||
*/
|
||||
EXPIRED,
|
||||
|
||||
/**
|
||||
* The certificate is not yet valid.
|
||||
*/
|
||||
NOT_YET_VALID,
|
||||
|
||||
/**
|
||||
* The certificate is revoked.
|
||||
*/
|
||||
REVOKED,
|
||||
|
||||
/**
|
||||
* The revocation status of the certificate could not be determined.
|
||||
*/
|
||||
UNDETERMINED_REVOCATION_STATUS,
|
||||
|
||||
/**
|
||||
* The signature is invalid.
|
||||
*/
|
||||
INVALID_SIGNATURE
|
||||
}
|
||||
}
|
||||
|
||||
77
jdk/src/share/classes/java/security/cert/PKIXReason.java
Normal file
77
jdk/src/share/classes/java/security/cert/PKIXReason.java
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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. Sun designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
package java.security.cert;
|
||||
|
||||
/**
|
||||
* The <code>PKIXReason</code> enumerates the potential PKIX-specific reasons
|
||||
* that an X.509 certification path may be invalid according to the PKIX
|
||||
* (RFC 3280) standard. These reasons are in addition to those of the
|
||||
* <code>CertPathValidatorException.BasicReason</code> enumeration.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public enum PKIXReason implements CertPathValidatorException.Reason {
|
||||
/**
|
||||
* The certificate does not chain correctly.
|
||||
*/
|
||||
NAME_CHAINING,
|
||||
|
||||
/**
|
||||
* The certificate's key usage is invalid.
|
||||
*/
|
||||
INVALID_KEY_USAGE,
|
||||
|
||||
/**
|
||||
* The policy constraints have been violated.
|
||||
*/
|
||||
INVALID_POLICY,
|
||||
|
||||
/**
|
||||
* No acceptable trust anchor found.
|
||||
*/
|
||||
NO_TRUST_ANCHOR,
|
||||
|
||||
/**
|
||||
* The certificate contains one or more unrecognized critical
|
||||
* extensions.
|
||||
*/
|
||||
UNRECOGNIZED_CRIT_EXT,
|
||||
|
||||
/**
|
||||
* The certificate is not a CA certificate.
|
||||
*/
|
||||
NOT_CA_CERT,
|
||||
|
||||
/**
|
||||
* The path length constraint has been violated.
|
||||
*/
|
||||
PATH_TOO_LONG,
|
||||
|
||||
/**
|
||||
* The name constraints have been violated.
|
||||
*/
|
||||
INVALID_NAME
|
||||
}
|
||||
@ -118,6 +118,6 @@ class Logging implements LoggingMXBean {
|
||||
}
|
||||
|
||||
public ObjectName getObjectName() {
|
||||
return com.sun.jmx.mbeanserver.Util.newObjectName(LogManager.LOGGING_MXBEAN_NAME);
|
||||
return ObjectName.valueOf(LogManager.LOGGING_MXBEAN_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1996-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1996-2008 Sun Microsystems, Inc. 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
|
||||
@ -317,9 +317,6 @@ class ZipOutputStream extends DeflaterOutputStream implements ZipConstants {
|
||||
if (current != null) {
|
||||
closeEntry();
|
||||
}
|
||||
if (xentries.size() < 1) {
|
||||
throw new ZipException("ZIP file must have at least one entry");
|
||||
}
|
||||
// write central directory
|
||||
long off = written;
|
||||
for (XEntry xentry : xentries)
|
||||
|
||||
@ -61,6 +61,6 @@ public class InstanceNotFoundException extends OperationsException {
|
||||
* @since 1.7
|
||||
*/
|
||||
public InstanceNotFoundException(ObjectName name) {
|
||||
this(name.toString());
|
||||
this(String.valueOf(name));
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,7 +304,7 @@ public class MBeanServerDelegate implements MBeanServerDelegateMBean,
|
||||
* @since 1.6
|
||||
*/
|
||||
public static final ObjectName DELEGATE_NAME =
|
||||
Util.newObjectName("JMImplementation:type=MBeanServerDelegate");
|
||||
ObjectName.valueOf("JMImplementation:type=MBeanServerDelegate");
|
||||
|
||||
/* Return a timestamp that is monotonically increasing even if
|
||||
System.currentTimeMillis() isn't (for example, if you call this
|
||||
|
||||
@ -413,7 +413,7 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
}
|
||||
|
||||
private void copyToOtherDomain(String domain, ObjectName aname)
|
||||
throws MalformedObjectNameException, NullPointerException {
|
||||
throws MalformedObjectNameException {
|
||||
|
||||
// The domain cannot be null
|
||||
if (domain == null)
|
||||
@ -467,7 +467,7 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
* is null.
|
||||
*/
|
||||
private void construct(String name)
|
||||
throws MalformedObjectNameException, NullPointerException {
|
||||
throws MalformedObjectNameException {
|
||||
|
||||
// The name cannot be null
|
||||
if (name == null)
|
||||
@ -729,7 +729,7 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
* @exception NullPointerException One of the parameters is null.
|
||||
*/
|
||||
private void construct(String domain, Map<String,String> props)
|
||||
throws MalformedObjectNameException, NullPointerException {
|
||||
throws MalformedObjectNameException {
|
||||
|
||||
// The domain cannot be null
|
||||
if (domain == null)
|
||||
@ -1071,7 +1071,7 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
* Check if the supplied key is a valid key.
|
||||
*/
|
||||
private static void checkKey(String key)
|
||||
throws MalformedObjectNameException, NullPointerException {
|
||||
throws MalformedObjectNameException {
|
||||
|
||||
if (key == null) throw new
|
||||
NullPointerException("Invalid key (null)");
|
||||
@ -1359,9 +1359,10 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
* @exception NullPointerException The <code>name</code> parameter
|
||||
* is null.
|
||||
*
|
||||
* @see #valueOf(String)
|
||||
*/
|
||||
public static ObjectName getInstance(String name)
|
||||
throws MalformedObjectNameException, NullPointerException {
|
||||
throws MalformedObjectNameException {
|
||||
return new ObjectName(name);
|
||||
}
|
||||
|
||||
@ -1386,10 +1387,11 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
* follow the rules for quoting.
|
||||
* @exception NullPointerException One of the parameters is null.
|
||||
*
|
||||
* @see #valueOf(String, String, String)
|
||||
*/
|
||||
public static ObjectName getInstance(String domain, String key,
|
||||
String value)
|
||||
throws MalformedObjectNameException, NullPointerException {
|
||||
throws MalformedObjectNameException {
|
||||
return new ObjectName(domain, key, value);
|
||||
}
|
||||
|
||||
@ -1417,10 +1419,11 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
* quoting.
|
||||
* @exception NullPointerException One of the parameters is null.
|
||||
*
|
||||
* @see #valueOf(String, Hashtable)
|
||||
*/
|
||||
public static ObjectName getInstance(String domain,
|
||||
Hashtable<String,String> table)
|
||||
throws MalformedObjectNameException, NullPointerException {
|
||||
throws MalformedObjectNameException {
|
||||
return new ObjectName(domain, table);
|
||||
}
|
||||
|
||||
@ -1453,11 +1456,120 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
* @exception NullPointerException The <code>name</code> is null.
|
||||
*
|
||||
*/
|
||||
public static ObjectName getInstance(ObjectName name)
|
||||
throws NullPointerException {
|
||||
public static ObjectName getInstance(ObjectName name) {
|
||||
if (name.getClass().equals(ObjectName.class))
|
||||
return name;
|
||||
return Util.newObjectName(name.getSerializedNameString());
|
||||
return valueOf(name.getSerializedNameString());
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Return an instance of ObjectName that can be used anywhere
|
||||
* an object obtained with {@link #ObjectName(String) new
|
||||
* ObjectName(name)} can be used. The returned object may be of
|
||||
* a subclass of ObjectName. Calling this method twice with the
|
||||
* same parameters may return the same object or two equal but
|
||||
* not identical objects.</p>
|
||||
*
|
||||
* <p>This method is equivalent to {@link #getInstance(String)} except that
|
||||
* it does not throw any checked exceptions.</p>
|
||||
*
|
||||
* @param name A string representation of the object name.
|
||||
*
|
||||
* @return an ObjectName corresponding to the given String.
|
||||
*
|
||||
* @exception IllegalArgumentException The string passed as a
|
||||
* parameter does not have the right format. The {@linkplain
|
||||
* Throwable#getCause() cause} of this exception will be a
|
||||
* {@link MalformedObjectNameException}.
|
||||
* @exception NullPointerException The <code>name</code> parameter
|
||||
* is null.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public static ObjectName valueOf(String name) {
|
||||
try {
|
||||
return getInstance(name);
|
||||
} catch (MalformedObjectNameException e) {
|
||||
throw new IllegalArgumentException(e.getMessage(), e);
|
||||
// Just plain IllegalArgumentException(e) produces an exception
|
||||
// message "javax.management.MalformedObjectNameException: ..."
|
||||
// which is distracting.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Return an instance of ObjectName that can be used anywhere
|
||||
* an object obtained with {@link #ObjectName(String, String,
|
||||
* String) new ObjectName(domain, key, value)} can be used. The
|
||||
* returned object may be of a subclass of ObjectName. Calling
|
||||
* this method twice with the same parameters may return the same
|
||||
* object or two equal but not identical objects.</p>
|
||||
*
|
||||
* <p>This method is equivalent to {@link #getInstance(String, String,
|
||||
* String)} except that it does not throw any checked exceptions.</p>
|
||||
*
|
||||
* @param domain The domain part of the object name.
|
||||
* @param key The attribute in the key property of the object name.
|
||||
* @param value The value in the key property of the object name.
|
||||
*
|
||||
* @return an ObjectName corresponding to the given domain,
|
||||
* key, and value.
|
||||
*
|
||||
* @exception IllegalArgumentException The
|
||||
* <code>domain</code>, <code>key</code>, or <code>value</code>
|
||||
* contains an illegal character, or <code>value</code> does not
|
||||
* follow the rules for quoting. The {@linkplain
|
||||
* Throwable#getCause() cause} of this exception will be a
|
||||
* {@link MalformedObjectNameException}.
|
||||
* @exception NullPointerException One of the parameters is null.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public static ObjectName valueOf(String domain, String key, String value) {
|
||||
try {
|
||||
return getInstance(domain, key, value);
|
||||
} catch (MalformedObjectNameException e) {
|
||||
throw new IllegalArgumentException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Return an instance of ObjectName that can be used anywhere
|
||||
* an object obtained with {@link #ObjectName(String, Hashtable)
|
||||
* new ObjectName(domain, table)} can be used. The returned
|
||||
* object may be of a subclass of ObjectName. Calling this method
|
||||
* twice with the same parameters may return the same object or
|
||||
* two equal but not identical objects.</p>
|
||||
*
|
||||
* <p>This method is equivalent to {@link #getInstance(String, Hashtable)}
|
||||
* except that it does not throw any checked exceptions.</p>
|
||||
*
|
||||
* @param domain The domain part of the object name.
|
||||
* @param table A hash table containing one or more key
|
||||
* properties. The key of each entry in the table is the key of a
|
||||
* key property in the object name. The associated value in the
|
||||
* table is the associated value in the object name.
|
||||
*
|
||||
* @return an ObjectName corresponding to the given domain and
|
||||
* key mappings.
|
||||
*
|
||||
* @exception IllegalArgumentException The <code>domain</code>
|
||||
* contains an illegal character, or one of the keys or values in
|
||||
* <code>table</code> contains an illegal character, or one of the
|
||||
* values in <code>table</code> does not follow the rules for
|
||||
* quoting. The {@linkplain Throwable#getCause() cause} of this exception
|
||||
* will be a {@link MalformedObjectNameException}.
|
||||
* @exception NullPointerException One of the parameters is null.
|
||||
*
|
||||
* @since 1.7
|
||||
*/
|
||||
public static ObjectName valueOf(String domain,
|
||||
Hashtable<String,String> table) {
|
||||
try {
|
||||
return new ObjectName(domain, table);
|
||||
} catch (MalformedObjectNameException e) {
|
||||
throw new IllegalArgumentException(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1477,7 +1589,7 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
* @since 1.7
|
||||
**/
|
||||
public final ObjectName withDomain(String newDomain)
|
||||
throws NullPointerException, MalformedObjectNameException {
|
||||
throws MalformedObjectNameException {
|
||||
return new ObjectName(newDomain, this);
|
||||
}
|
||||
|
||||
@ -1490,9 +1602,11 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
* parameter does not have the right format.
|
||||
* @exception NullPointerException The <code>name</code> parameter
|
||||
* is null.
|
||||
*
|
||||
* @see #valueOf(String)
|
||||
*/
|
||||
public ObjectName(String name)
|
||||
throws MalformedObjectNameException, NullPointerException {
|
||||
throws MalformedObjectNameException {
|
||||
construct(name);
|
||||
}
|
||||
|
||||
@ -1508,9 +1622,11 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
* contains an illegal character, or <code>value</code> does not
|
||||
* follow the rules for quoting.
|
||||
* @exception NullPointerException One of the parameters is null.
|
||||
*
|
||||
* @see #valueOf(String, String, String)
|
||||
*/
|
||||
public ObjectName(String domain, String key, String value)
|
||||
throws MalformedObjectNameException, NullPointerException {
|
||||
throws MalformedObjectNameException {
|
||||
// If key or value are null a NullPointerException
|
||||
// will be thrown by the put method in Hashtable.
|
||||
//
|
||||
@ -1533,9 +1649,11 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
* values in <code>table</code> does not follow the rules for
|
||||
* quoting.
|
||||
* @exception NullPointerException One of the parameters is null.
|
||||
*
|
||||
* @see #valueOf(String, Hashtable)
|
||||
*/
|
||||
public ObjectName(String domain, Hashtable<String,String> table)
|
||||
throws MalformedObjectNameException, NullPointerException {
|
||||
throws MalformedObjectNameException {
|
||||
construct(domain, table);
|
||||
/* The exception for when a key or value in the table is not a
|
||||
String is now ClassCastException rather than
|
||||
@ -1629,8 +1747,7 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public boolean isPropertyValuePattern(String property)
|
||||
throws NullPointerException, IllegalArgumentException {
|
||||
public boolean isPropertyValuePattern(String property) {
|
||||
if (property == null)
|
||||
throw new NullPointerException("key property can't be null");
|
||||
for (int i = 0; i < _ca_array.length; i++) {
|
||||
@ -1691,7 +1808,7 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
*
|
||||
* @exception NullPointerException If <code>property</code> is null.
|
||||
*/
|
||||
public String getKeyProperty(String property) throws NullPointerException {
|
||||
public String getKeyProperty(String property) {
|
||||
return _getKeyPropertyList().get(property);
|
||||
}
|
||||
|
||||
@ -1950,8 +2067,7 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
* @exception NullPointerException if <code>s</code> is null.
|
||||
*
|
||||
*/
|
||||
public static String quote(String s)
|
||||
throws NullPointerException {
|
||||
public static String quote(String s) {
|
||||
final StringBuilder buf = new StringBuilder("\"");
|
||||
final int len = s.length();
|
||||
for (int i = 0; i < len; i++) {
|
||||
@ -1995,8 +2111,7 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
* @exception NullPointerException if <code>q</code> is null.
|
||||
*
|
||||
*/
|
||||
public static String unquote(String q)
|
||||
throws IllegalArgumentException, NullPointerException {
|
||||
public static String unquote(String q) {
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
final int len = q.length();
|
||||
if (len < 2 || q.charAt(0) != '"' || q.charAt(len - 1) != '"')
|
||||
@ -2041,7 +2156,7 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public static final ObjectName WILDCARD = Util.newObjectName("*:*");
|
||||
public static final ObjectName WILDCARD = valueOf("*:*");
|
||||
|
||||
// Category : Utilities <===================================
|
||||
|
||||
@ -2064,7 +2179,7 @@ public class ObjectName implements Comparable<ObjectName>, QueryExp {
|
||||
* @exception NullPointerException if <code>name</code> is null.
|
||||
*
|
||||
*/
|
||||
public boolean apply(ObjectName name) throws NullPointerException {
|
||||
public boolean apply(ObjectName name) {
|
||||
|
||||
if (name == null) throw new NullPointerException();
|
||||
|
||||
|
||||
@ -170,7 +170,7 @@ public class QueryNotificationFilter implements NotificationFilter {
|
||||
private static final long serialVersionUID = -8408613922660635231L;
|
||||
|
||||
private static final ObjectName DEFAULT_NAME =
|
||||
Util.newObjectName(":type=Notification");
|
||||
ObjectName.valueOf(":type=Notification");
|
||||
private static final QueryExp trueQuery;
|
||||
static {
|
||||
ValueExp zero = Query.value(0);
|
||||
|
||||
@ -264,11 +264,12 @@ public class EventClient implements EventConsumer, NotificationManager {
|
||||
new PerThreadGroupPool.Create<ScheduledThreadPoolExecutor>() {
|
||||
public ScheduledThreadPoolExecutor createThreadPool(ThreadGroup group) {
|
||||
ThreadFactory daemonThreadFactory = new DaemonThreadFactory(
|
||||
"EventClient lease renewer %d");
|
||||
"JMX EventClient lease renewer %d");
|
||||
ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(
|
||||
20, daemonThreadFactory);
|
||||
exec.setKeepAliveTime(3, TimeUnit.SECONDS);
|
||||
exec.setKeepAliveTime(1, TimeUnit.SECONDS);
|
||||
exec.allowCoreThreadTimeOut(true);
|
||||
exec.setRemoveOnCancelPolicy(true);
|
||||
return exec;
|
||||
}
|
||||
};
|
||||
|
||||
@ -96,7 +96,7 @@ public interface EventClientDelegateMBean {
|
||||
* <code>{@value #OBJECT_NAME_STRING}</code>.
|
||||
*/
|
||||
public final static ObjectName OBJECT_NAME =
|
||||
Util.newObjectName(OBJECT_NAME_STRING);
|
||||
ObjectName.valueOf(OBJECT_NAME_STRING);
|
||||
|
||||
/**
|
||||
* A unique listener identifier specified for an EventClient.
|
||||
|
||||
@ -149,10 +149,10 @@ public class EventSubscriber implements EventConsumer {
|
||||
if (listener == null)
|
||||
throw new IllegalArgumentException("Null listener");
|
||||
|
||||
final ListenerInfo li = new ListenerInfo(listener, filter, handback);
|
||||
List<ListenerInfo> list;
|
||||
final MyListenerInfo li = new MyListenerInfo(listener, filter, handback);
|
||||
List<MyListenerInfo> list;
|
||||
|
||||
Map<ObjectName, List<ListenerInfo>> map;
|
||||
Map<ObjectName, List<MyListenerInfo>> map;
|
||||
Set<ObjectName> names;
|
||||
if (name.isPattern()) {
|
||||
map = patternSubscriptionMap;
|
||||
@ -165,7 +165,7 @@ public class EventSubscriber implements EventConsumer {
|
||||
synchronized (map) {
|
||||
list = map.get(name);
|
||||
if (list == null) {
|
||||
list = new ArrayList<ListenerInfo>();
|
||||
list = new ArrayList<MyListenerInfo>();
|
||||
map.put(name, list);
|
||||
}
|
||||
list.add(li);
|
||||
@ -186,7 +186,6 @@ public class EventSubscriber implements EventConsumer {
|
||||
public void unsubscribe(ObjectName name,
|
||||
NotificationListener listener)
|
||||
throws ListenerNotFoundException, IOException {
|
||||
|
||||
if (logger.traceOn())
|
||||
logger.trace("unsubscribe", "" + name);
|
||||
|
||||
@ -196,7 +195,7 @@ public class EventSubscriber implements EventConsumer {
|
||||
if (listener == null)
|
||||
throw new ListenerNotFoundException();
|
||||
|
||||
Map<ObjectName, List<ListenerInfo>> map;
|
||||
Map<ObjectName, List<MyListenerInfo>> map;
|
||||
Set<ObjectName> names;
|
||||
|
||||
if (name.isPattern()) {
|
||||
@ -207,22 +206,39 @@ public class EventSubscriber implements EventConsumer {
|
||||
names = Collections.singleton(name);
|
||||
}
|
||||
|
||||
final ListenerInfo li = new ListenerInfo(listener, null, null);
|
||||
List<ListenerInfo> list;
|
||||
List<MyListenerInfo> toRemove = new ArrayList<MyListenerInfo>();
|
||||
synchronized (map) {
|
||||
list = map.get(name);
|
||||
if (list == null || !list.remove(li))
|
||||
List<MyListenerInfo> list = map.get(name);
|
||||
if (list == null) {
|
||||
throw new ListenerNotFoundException();
|
||||
}
|
||||
|
||||
for (MyListenerInfo info : list) {
|
||||
if (info.listener == listener) {
|
||||
toRemove.add(info);
|
||||
}
|
||||
}
|
||||
|
||||
if (toRemove.isEmpty()) {
|
||||
throw new ListenerNotFoundException();
|
||||
}
|
||||
|
||||
for (MyListenerInfo info : toRemove) {
|
||||
list.remove(info);
|
||||
}
|
||||
|
||||
if (list.isEmpty())
|
||||
map.remove(name);
|
||||
}
|
||||
|
||||
for (ObjectName mbeanName : names) {
|
||||
try {
|
||||
mbeanServer.removeNotificationListener(mbeanName, li.listener);
|
||||
} catch (Exception e) {
|
||||
logger.fine("unsubscribe", "removeNotificationListener", e);
|
||||
for (MyListenerInfo i : toRemove) {
|
||||
try {
|
||||
mbeanServer.removeNotificationListener(mbeanName,
|
||||
i.listener, i.filter, i.handback);
|
||||
} catch (Exception e) {
|
||||
logger.fine("unsubscribe", "removeNotificationListener", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -256,12 +272,12 @@ public class EventSubscriber implements EventConsumer {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<ListenerInfo> listeners = new ArrayList<ListenerInfo>();
|
||||
final List<MyListenerInfo> listeners = new ArrayList<MyListenerInfo>();
|
||||
|
||||
// If there are subscribers for the exact name that has just arrived
|
||||
// then add their listeners to the list.
|
||||
synchronized (exactSubscriptionMap) {
|
||||
List<ListenerInfo> exactListeners = exactSubscriptionMap.get(name);
|
||||
List<MyListenerInfo> exactListeners = exactSubscriptionMap.get(name);
|
||||
if (exactListeners != null)
|
||||
listeners.addAll(exactListeners);
|
||||
}
|
||||
@ -277,7 +293,7 @@ public class EventSubscriber implements EventConsumer {
|
||||
}
|
||||
|
||||
// Add all the listeners just found to the new MBean.
|
||||
for (ListenerInfo li : listeners) {
|
||||
for (MyListenerInfo li : listeners) {
|
||||
try {
|
||||
mbeanServer.addNotificationListener(
|
||||
name,
|
||||
@ -292,12 +308,12 @@ public class EventSubscriber implements EventConsumer {
|
||||
}
|
||||
};
|
||||
|
||||
private static class ListenerInfo {
|
||||
private static class MyListenerInfo {
|
||||
public final NotificationListener listener;
|
||||
public final NotificationFilter filter;
|
||||
public final Object handback;
|
||||
|
||||
public ListenerInfo(NotificationListener listener,
|
||||
public MyListenerInfo(NotificationListener listener,
|
||||
NotificationFilter filter,
|
||||
Object handback) {
|
||||
|
||||
@ -308,26 +324,6 @@ public class EventSubscriber implements EventConsumer {
|
||||
this.filter = filter;
|
||||
this.handback = handback;
|
||||
}
|
||||
|
||||
/* Two ListenerInfo instances are equal if they have the same
|
||||
* NotificationListener. This means that we can use List.remove
|
||||
* to implement the two-argument removeNotificationListener.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this)
|
||||
return true;
|
||||
|
||||
if (!(o instanceof ListenerInfo))
|
||||
return false;
|
||||
|
||||
return listener.equals(((ListenerInfo)o).listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return listener.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------
|
||||
@ -338,10 +334,10 @@ public class EventSubscriber implements EventConsumer {
|
||||
// ---------------------------------
|
||||
private final MBeanServer mbeanServer;
|
||||
|
||||
private final Map<ObjectName, List<ListenerInfo>> exactSubscriptionMap =
|
||||
new HashMap<ObjectName, List<ListenerInfo>>();
|
||||
private final Map<ObjectName, List<ListenerInfo>> patternSubscriptionMap =
|
||||
new HashMap<ObjectName, List<ListenerInfo>>();
|
||||
private final Map<ObjectName, List<MyListenerInfo>> exactSubscriptionMap =
|
||||
new HashMap<ObjectName, List<MyListenerInfo>>();
|
||||
private final Map<ObjectName, List<MyListenerInfo>> patternSubscriptionMap =
|
||||
new HashMap<ObjectName, List<MyListenerInfo>>();
|
||||
|
||||
|
||||
|
||||
|
||||
@ -31,10 +31,8 @@ import com.sun.jmx.remote.util.ClassLogger;
|
||||
import java.io.IOException;
|
||||
import java.io.NotSerializableException;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.RejectedExecutionException;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import javax.management.MBeanException;
|
||||
@ -215,50 +213,47 @@ public class FetchingEventRelay implements EventRelay {
|
||||
this.maxNotifs = maxNotifs;
|
||||
|
||||
if (executor == null) {
|
||||
executor = Executors.newSingleThreadScheduledExecutor(
|
||||
ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(1,
|
||||
daemonThreadFactory);
|
||||
}
|
||||
stpe.setKeepAliveTime(1, TimeUnit.SECONDS);
|
||||
stpe.allowCoreThreadTimeOut(true);
|
||||
executor = stpe;
|
||||
this.defaultExecutor = stpe;
|
||||
} else
|
||||
this.defaultExecutor = null;
|
||||
this.executor = executor;
|
||||
if (executor instanceof ScheduledExecutorService)
|
||||
leaseScheduler = (ScheduledExecutorService) executor;
|
||||
else {
|
||||
leaseScheduler = Executors.newSingleThreadScheduledExecutor(
|
||||
daemonThreadFactory);
|
||||
}
|
||||
|
||||
startSequenceNumber = 0;
|
||||
fetchingJob = new MyJob();
|
||||
}
|
||||
|
||||
public void setEventReceiver(EventReceiver eventReceiver) {
|
||||
public synchronized void setEventReceiver(EventReceiver eventReceiver) {
|
||||
if (logger.traceOn()) {
|
||||
logger.trace("setEventReceiver", ""+eventReceiver);
|
||||
}
|
||||
|
||||
EventReceiver old = this.eventReceiver;
|
||||
synchronized(fetchingJob) {
|
||||
this.eventReceiver = eventReceiver;
|
||||
if (old == null && eventReceiver != null)
|
||||
fetchingJob.resume();
|
||||
}
|
||||
this.eventReceiver = eventReceiver;
|
||||
if (old == null && eventReceiver != null)
|
||||
fetchingJob.resume();
|
||||
}
|
||||
|
||||
public String getClientId() {
|
||||
return clientId;
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
public synchronized void stop() {
|
||||
if (logger.traceOn()) {
|
||||
logger.trace("stop", "");
|
||||
}
|
||||
synchronized(fetchingJob) {
|
||||
if (stopped) {
|
||||
return;
|
||||
}
|
||||
|
||||
stopped = true;
|
||||
clientId = null;
|
||||
if (stopped) {
|
||||
return;
|
||||
}
|
||||
|
||||
stopped = true;
|
||||
clientId = null;
|
||||
if (defaultExecutor != null)
|
||||
defaultExecutor.shutdown();
|
||||
}
|
||||
|
||||
private class MyJob extends RepeatedSingletonJob {
|
||||
@ -372,10 +367,9 @@ public class FetchingEventRelay implements EventRelay {
|
||||
private final EventClientDelegateMBean delegate;
|
||||
private String clientId;
|
||||
private boolean stopped = false;
|
||||
private volatile ScheduledFuture<?> leaseRenewalFuture;
|
||||
|
||||
private final Executor executor;
|
||||
private final ScheduledExecutorService leaseScheduler;
|
||||
private final ExecutorService defaultExecutor;
|
||||
private final MyJob fetchingJob;
|
||||
|
||||
private final long timeout;
|
||||
@ -385,5 +379,5 @@ public class FetchingEventRelay implements EventRelay {
|
||||
new ClassLogger("javax.management.event",
|
||||
"FetchingEventRelay");
|
||||
private static final ThreadFactory daemonThreadFactory =
|
||||
new DaemonThreadFactory("FetchingEventRelay-executor");
|
||||
new DaemonThreadFactory("JMX FetchingEventRelay executor %d");
|
||||
}
|
||||
|
||||
@ -185,7 +185,7 @@ public class RMIPushEventForwarder implements EventForwarder {
|
||||
|
||||
private static final ExecutorService executor =
|
||||
Executors.newCachedThreadPool(
|
||||
new DaemonThreadFactory("RMIEventForwarder Executor"));
|
||||
new DaemonThreadFactory("JMX RMIEventForwarder Executor"));
|
||||
private final SendingJob sendingJob = new SendingJob();
|
||||
|
||||
private final BlockingQueue<TargetedNotification> buffer;
|
||||
|
||||
@ -308,17 +308,17 @@ public class JMXDomain extends JMXNamespace {
|
||||
* It is however only available for subclasses in this package.
|
||||
**/
|
||||
@Override
|
||||
ObjectName validateHandlerName(ObjectName supliedName) {
|
||||
if (supliedName == null)
|
||||
ObjectName validateHandlerName(ObjectName suppliedName) {
|
||||
if (suppliedName == null)
|
||||
throw new IllegalArgumentException("Must supply a valid name");
|
||||
final String dirName = JMXNamespaces.
|
||||
normalizeNamespaceName(supliedName.getDomain());
|
||||
normalizeNamespaceName(suppliedName.getDomain());
|
||||
final ObjectName handlerName = getDomainObjectName(dirName);
|
||||
if (!supliedName.equals(handlerName))
|
||||
if (!suppliedName.equals(handlerName))
|
||||
throw new IllegalArgumentException("invalid name space name: "+
|
||||
supliedName);
|
||||
suppliedName);
|
||||
|
||||
return supliedName;
|
||||
return suppliedName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -482,8 +482,8 @@ public class JMXNamespace
|
||||
/**
|
||||
* This method is part of the {@link MBeanRegistration} interface.
|
||||
* The {@link JMXNamespace} class uses the {@link MBeanRegistration}
|
||||
* interface in order to get a handle to the MBean server in which it is
|
||||
* registered. It also check the validity of its own ObjectName.
|
||||
* interface in order to get a reference to the MBean server in which it is
|
||||
* registered. It also checks the validity of its own ObjectName.
|
||||
* <p>
|
||||
* This method is called by the MBean server.
|
||||
* Application classes should never call this method directly.
|
||||
@ -502,11 +502,14 @@ public class JMXNamespace
|
||||
*/
|
||||
public ObjectName preRegister(MBeanServer server, ObjectName name)
|
||||
throws Exception {
|
||||
if (objectName != null && ! objectName.equals(name))
|
||||
throw new IllegalStateException(
|
||||
// need to synchronize to protect against multiple registration.
|
||||
synchronized(this) {
|
||||
if (objectName != null && ! objectName.equals(name))
|
||||
throw new IllegalStateException(
|
||||
"Already registered under another name: " + objectName);
|
||||
objectName = validateHandlerName(name);
|
||||
mbeanServer = server;
|
||||
objectName = validateHandlerName(name);
|
||||
mbeanServer = server;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
@ -517,23 +520,23 @@ public class JMXNamespace
|
||||
* reuse JMXNamespace in order to implement sessions...
|
||||
* It is however only available for subclasses in this package.
|
||||
**/
|
||||
ObjectName validateHandlerName(ObjectName supliedName) {
|
||||
if (supliedName == null)
|
||||
ObjectName validateHandlerName(ObjectName suppliedName) {
|
||||
if (suppliedName == null)
|
||||
throw new IllegalArgumentException("Must supply a valid name");
|
||||
final String dirName = JMXNamespaces.
|
||||
normalizeNamespaceName(supliedName.getDomain());
|
||||
normalizeNamespaceName(suppliedName.getDomain());
|
||||
final ObjectName handlerName =
|
||||
JMXNamespaces.getNamespaceObjectName(dirName);
|
||||
if (!supliedName.equals(handlerName))
|
||||
if (!suppliedName.equals(handlerName))
|
||||
throw new IllegalArgumentException("invalid name space name: "+
|
||||
supliedName);
|
||||
return supliedName;
|
||||
suppliedName);
|
||||
return suppliedName;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is part of the {@link MBeanRegistration} interface.
|
||||
* The {@link JMXNamespace} class uses the {@link MBeanRegistration}
|
||||
* interface in order to get a handle to the MBean server in which it is
|
||||
* interface in order to get a reference to the MBean server in which it is
|
||||
* registered.
|
||||
* <p>
|
||||
* This method is called by the MBean server. Application classes should
|
||||
@ -549,7 +552,7 @@ public class JMXNamespace
|
||||
/**
|
||||
* This method is part of the {@link MBeanRegistration} interface.
|
||||
* The {@link JMXNamespace} class uses the {@link MBeanRegistration}
|
||||
* interface in order to get a handle to the MBean server in which it is
|
||||
* interface in order to get a reference to the MBean server in which it is
|
||||
* registered.
|
||||
* <p>
|
||||
* This method is called by the MBean server. Application classes should
|
||||
@ -573,8 +576,11 @@ public class JMXNamespace
|
||||
* @see MBeanRegistration#postDeregister MBeanRegistration
|
||||
*/
|
||||
public void postDeregister() {
|
||||
mbeanServer = null;
|
||||
objectName = null;
|
||||
// need to synchronize to protect against multiple registration.
|
||||
synchronized(this) {
|
||||
mbeanServer = null;
|
||||
objectName = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -266,11 +266,15 @@ public class JMXNamespaces {
|
||||
ObjectNameRouter.normalizeNamespacePath(namespace,false,
|
||||
true,false);
|
||||
try {
|
||||
// We could use Util.newObjectName here - but throwing an
|
||||
// IllegalArgumentException that contains just the supplied
|
||||
// namespace instead of the whole ObjectName seems preferable.
|
||||
return ObjectName.getInstance(sourcePath+
|
||||
NAMESPACE_SEPARATOR+":"+
|
||||
JMXNamespace.TYPE_ASSIGNMENT);
|
||||
} catch (MalformedObjectNameException x) {
|
||||
throw new IllegalArgumentException(namespace,x);
|
||||
throw new IllegalArgumentException("Invalid namespace: " +
|
||||
namespace,x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -28,13 +28,12 @@ package javax.management.namespace;
|
||||
import com.sun.jmx.defaults.JmxProperties;
|
||||
import com.sun.jmx.mbeanserver.Util;
|
||||
import com.sun.jmx.namespace.JMXNamespaceUtils;
|
||||
import com.sun.jmx.namespace.NamespaceInterceptor.DynamicProbe;
|
||||
import com.sun.jmx.remote.util.EnvHelp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.AccessControlException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@ -43,9 +42,7 @@ import javax.management.AttributeChangeNotification;
|
||||
import javax.management.InstanceNotFoundException;
|
||||
import javax.management.ListenerNotFoundException;
|
||||
import javax.management.MBeanNotificationInfo;
|
||||
import javax.management.MBeanPermission;
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.Notification;
|
||||
import javax.management.NotificationBroadcasterSupport;
|
||||
import javax.management.NotificationEmitter;
|
||||
@ -117,18 +114,13 @@ public class JMXRemoteNamespace
|
||||
*/
|
||||
private static final Logger LOG = JmxProperties.NAMESPACE_LOGGER;
|
||||
|
||||
private static final Logger PROBE_LOG = Logger.getLogger(
|
||||
JmxProperties.NAMESPACE_LOGGER_NAME+".probe");
|
||||
|
||||
|
||||
// This connection listener is used to listen for connection events from
|
||||
// the underlying JMXConnector. It is used in particular to maintain the
|
||||
// "connected" state in this MBean.
|
||||
//
|
||||
private static class ConnectionListener implements NotificationListener {
|
||||
private final JMXRemoteNamespace handler;
|
||||
private ConnectionListener(JMXRemoteNamespace handler) {
|
||||
this.handler = handler;
|
||||
private class ConnectionListener implements NotificationListener {
|
||||
private ConnectionListener() {
|
||||
}
|
||||
public void handleNotification(Notification notification,
|
||||
Object handback) {
|
||||
@ -136,7 +128,11 @@ public class JMXRemoteNamespace
|
||||
return;
|
||||
final JMXConnectionNotification cn =
|
||||
(JMXConnectionNotification)notification;
|
||||
handler.checkState(this,cn,(JMXConnector)handback);
|
||||
final String type = cn.getType();
|
||||
if (JMXConnectionNotification.CLOSED.equals(type)
|
||||
|| JMXConnectionNotification.FAILED.equals(type)) {
|
||||
checkState(this,cn,(JMXConnector)handback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,8 +146,7 @@ public class JMXRemoteNamespace
|
||||
// because the one that is actually used is the one supplied by the
|
||||
// override of getMBeanServerConnection().
|
||||
private static class JMXRemoteNamespaceDelegate
|
||||
extends MBeanServerConnectionWrapper
|
||||
implements DynamicProbe {
|
||||
extends MBeanServerConnectionWrapper {
|
||||
private volatile JMXRemoteNamespace parent=null;
|
||||
|
||||
JMXRemoteNamespaceDelegate() {
|
||||
@ -177,9 +172,6 @@ public class JMXRemoteNamespace
|
||||
|
||||
}
|
||||
|
||||
public boolean isProbeRequested() {
|
||||
return this.parent.isProbeRequested();
|
||||
}
|
||||
}
|
||||
|
||||
private static final MBeanNotificationInfo connectNotification =
|
||||
@ -188,7 +180,7 @@ public class JMXRemoteNamespace
|
||||
"Connected",
|
||||
"Emitted when the Connected state of this object changes");
|
||||
|
||||
private static long seqNumber=0;
|
||||
private static AtomicLong seqNumber = new AtomicLong(0);
|
||||
|
||||
private final NotificationBroadcasterSupport broadcaster;
|
||||
private final ConnectionListener listener;
|
||||
@ -198,7 +190,6 @@ public class JMXRemoteNamespace
|
||||
private volatile MBeanServerConnection server = null;
|
||||
private volatile JMXConnector conn = null;
|
||||
private volatile ClassLoader defaultClassLoader = null;
|
||||
private volatile boolean probed;
|
||||
|
||||
/**
|
||||
* Creates a new instance of {@code JMXRemoteNamespace}.
|
||||
@ -237,10 +228,7 @@ public class JMXRemoteNamespace
|
||||
this.optionsMap = JMXNamespaceUtils.unmodifiableMap(optionsMap);
|
||||
|
||||
// handles (dis)connection events
|
||||
this.listener = new ConnectionListener(this);
|
||||
|
||||
// XXX TODO: remove the probe, or simplify it.
|
||||
this.probed = false;
|
||||
this.listener = new ConnectionListener();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -271,10 +259,6 @@ public class JMXRemoteNamespace
|
||||
return optionsMap;
|
||||
}
|
||||
|
||||
boolean isProbeRequested() {
|
||||
return probed==false;
|
||||
}
|
||||
|
||||
public void addNotificationListener(NotificationListener listener,
|
||||
NotificationFilter filter, Object handback) {
|
||||
broadcaster.addNotificationListener(listener, filter, handback);
|
||||
@ -313,8 +297,8 @@ public class JMXRemoteNamespace
|
||||
broadcaster.removeNotificationListener(listener, filter, handback);
|
||||
}
|
||||
|
||||
private static synchronized long getNextSeqNumber() {
|
||||
return seqNumber++;
|
||||
private static long getNextSeqNumber() {
|
||||
return seqNumber.getAndIncrement();
|
||||
}
|
||||
|
||||
|
||||
@ -362,14 +346,18 @@ public class JMXRemoteNamespace
|
||||
// lock while evaluating the true value of the connected state,
|
||||
// while anyone might also call close() or connect() from a
|
||||
// different thread.
|
||||
//
|
||||
// The method switchConnection() (called from here too) also has the
|
||||
// same kind of complex logic.
|
||||
// same kind of complex logic:
|
||||
//
|
||||
// We use the JMXConnector has a handback to the notification listener
|
||||
// (emittingConnector) in order to be able to determine whether the
|
||||
// notification concerns the current connector in use, or an older
|
||||
// one.
|
||||
// one. The 'emittingConnector' is the connector from which the
|
||||
// notification originated. This could be an 'old' connector - as
|
||||
// closed() and connect() could already have been called before the
|
||||
// notification arrived. So what we do is to compare the
|
||||
// 'emittingConnector' with the current connector, to see if the
|
||||
// notification actually comes from the curent connector.
|
||||
//
|
||||
boolean remove = false;
|
||||
|
||||
@ -486,14 +474,12 @@ public class JMXRemoteNamespace
|
||||
}
|
||||
}
|
||||
|
||||
private void closeall(JMXConnector... a) {
|
||||
for (JMXConnector c : a) {
|
||||
try {
|
||||
if (c != null) c.close();
|
||||
} catch (Exception x) {
|
||||
// OK: we're gonna throw the original exception later.
|
||||
LOG.finest("Ignoring exception when closing connector: "+x);
|
||||
}
|
||||
private void close(JMXConnector c) {
|
||||
try {
|
||||
if (c != null) c.close();
|
||||
} catch (Exception x) {
|
||||
// OK: we're gonna throw the original exception later.
|
||||
LOG.finest("Ignoring exception when closing connector: "+x);
|
||||
}
|
||||
}
|
||||
|
||||
@ -598,26 +584,7 @@ public class JMXRemoteNamespace
|
||||
}
|
||||
|
||||
public void connect() throws IOException {
|
||||
if (conn != null) {
|
||||
try {
|
||||
// This is much too fragile. It must go away!
|
||||
PROBE_LOG.finest("Probing again...");
|
||||
triggerProbe(getMBeanServerConnection());
|
||||
} catch(Exception x) {
|
||||
close();
|
||||
Throwable cause = x;
|
||||
// if the cause is a security exception - rethrows it...
|
||||
while (cause != null) {
|
||||
if (cause instanceof SecurityException)
|
||||
throw (SecurityException) cause;
|
||||
cause = cause.getCause();
|
||||
}
|
||||
throw new IOException("connection failed: cycle?",x);
|
||||
}
|
||||
}
|
||||
LOG.fine("connecting...");
|
||||
// TODO remove these traces
|
||||
// System.err.println(getInitParameter()+" connecting");
|
||||
final Map<String,Object> env =
|
||||
new HashMap<String,Object>(getEnvMap());
|
||||
try {
|
||||
@ -640,86 +607,16 @@ public class JMXRemoteNamespace
|
||||
msc = aconn.getMBeanServerConnection();
|
||||
aconn.addConnectionNotificationListener(listener,null,aconn);
|
||||
} catch (IOException io) {
|
||||
closeall(aconn);
|
||||
close(aconn);
|
||||
throw io;
|
||||
} catch (RuntimeException x) {
|
||||
closeall(aconn);
|
||||
close(aconn);
|
||||
throw x;
|
||||
}
|
||||
|
||||
|
||||
// XXX Revisit here
|
||||
// Note from the author: This business of switching connection is
|
||||
// incredibly complex. Isn't there any means to simplify it?
|
||||
//
|
||||
switchConnection(conn,aconn,msc);
|
||||
try {
|
||||
triggerProbe(msc);
|
||||
} catch(Exception x) {
|
||||
close();
|
||||
Throwable cause = x;
|
||||
// if the cause is a security exception - rethrows it...
|
||||
while (cause != null) {
|
||||
if (cause instanceof SecurityException)
|
||||
throw (SecurityException) cause;
|
||||
cause = cause.getCause();
|
||||
}
|
||||
throw new IOException("connection failed: cycle?",x);
|
||||
}
|
||||
LOG.fine("connected.");
|
||||
}
|
||||
|
||||
// If this is a self-linking namespace, this method should trigger
|
||||
// the emission of a probe in the wrapping NamespaceInterceptor.
|
||||
// The first call to source() in the wrapping NamespaceInterceptor
|
||||
// causes the emission of the probe.
|
||||
//
|
||||
// Note: the MBeanServer returned by getSourceServer
|
||||
// (our private JMXRemoteNamespaceDelegate inner class)
|
||||
// implements a sun private interface (DynamicProbe) which is
|
||||
// used by the NamespaceInterceptor to determine whether it should
|
||||
// send a probe or not.
|
||||
// We needed this interface here because the NamespaceInterceptor
|
||||
// has otherwise no means to knows that this object has just
|
||||
// connected, and that a new probe should be sent.
|
||||
//
|
||||
// Probes work this way: the NamespaceInterceptor sets a flag and sends
|
||||
// a queryNames() request. If a queryNames() request comes in when the flag
|
||||
// is on, then it deduces that there is a self-linking loop - and instead
|
||||
// of calling queryNames() on the JMXNamespace (which would cause the
|
||||
// loop to go on) it breaks the recursion by returning the probe ObjectName.
|
||||
// If the NamespaceInterceptor receives the probe ObjectName as result of
|
||||
// its original queryNames() it knows that it has been looping back on
|
||||
// itslef and throws an Exception - which will be raised through this
|
||||
// method, thus preventing the connection to be established...
|
||||
//
|
||||
// More info in the com.sun.jmx.namespace.NamespaceInterceptor class
|
||||
//
|
||||
// XXX: TODO this probe thing is way too complex and fragile.
|
||||
// This *must* go away or be replaced by something simpler.
|
||||
// ideas are welcomed.
|
||||
//
|
||||
private void triggerProbe(final MBeanServerConnection msc)
|
||||
throws MalformedObjectNameException, IOException {
|
||||
// Query Pattern that we will send through the source server in order
|
||||
// to detect self-linking namespaces.
|
||||
//
|
||||
//
|
||||
final ObjectName pattern;
|
||||
pattern = ObjectName.getInstance("*" +
|
||||
JMXNamespaces.NAMESPACE_SEPARATOR + ":" +
|
||||
JMXNamespace.TYPE_ASSIGNMENT);
|
||||
probed = false;
|
||||
try {
|
||||
msc.queryNames(pattern, null);
|
||||
probed = true;
|
||||
} catch (AccessControlException x) {
|
||||
// if we have an MBeanPermission missing then do nothing...
|
||||
if (!(x.getPermission() instanceof MBeanPermission))
|
||||
throw x;
|
||||
PROBE_LOG.finer("Can't check for cycles: " + x);
|
||||
probed = false; // no need to do it again...
|
||||
}
|
||||
LOG.fine("connected.");
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
|
||||
@ -28,7 +28,6 @@ package javax.management.namespace;
|
||||
import com.sun.jmx.mbeanserver.Util;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.security.AccessController;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.management.Attribute;
|
||||
|
||||
@ -193,14 +193,6 @@ import javax.management.loading.ClassLoaderRepository;
|
||||
* }
|
||||
*
|
||||
* <a name="PropsMBS"></a>public class PropsMBS extends MBeanServerSupport {
|
||||
* private static ObjectName newObjectName(String name) {
|
||||
* try {
|
||||
* return new ObjectName(name);
|
||||
* } catch (MalformedObjectNameException e) {
|
||||
* throw new AssertionError(e);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* public static class PropertyImpl implements PropertyMBean {
|
||||
* private final String name;
|
||||
*
|
||||
@ -219,7 +211,7 @@ import javax.management.loading.ClassLoaderRepository;
|
||||
* throws InstanceNotFoundException {
|
||||
*
|
||||
* // Check that the name is a legal one for a Property MBean
|
||||
* ObjectName namePattern = newObjectName(
|
||||
* ObjectName namePattern = ObjectName.valueOf(
|
||||
* "com.example:type=Property,name=\"*\"");
|
||||
* if (!namePattern.apply(name))
|
||||
* throw new InstanceNotFoundException(name);
|
||||
@ -239,7 +231,7 @@ import javax.management.loading.ClassLoaderRepository;
|
||||
* {@code Set<ObjectName> names = new TreeSet<ObjectName>();}
|
||||
* Properties props = System.getProperties();
|
||||
* for (String propName : props.stringPropertyNames()) {
|
||||
* ObjectName objectName = newObjectName(
|
||||
* ObjectName objectName = ObjectName.valueOf(
|
||||
* "com.example:type=Property,name=" +
|
||||
* ObjectName.quote(propName));
|
||||
* names.add(objectName);
|
||||
@ -278,7 +270,7 @@ import javax.management.loading.ClassLoaderRepository;
|
||||
* }
|
||||
*
|
||||
* public void propertyChanged(String name, String newValue) {
|
||||
* ObjectName objectName = newObjectName(
|
||||
* ObjectName objectName = ObjectName.valueOf(
|
||||
* "com.example:type=Property,name=" + ObjectName.quote(name));
|
||||
* Notification n = new Notification(
|
||||
* "com.example.property.changed", objectName, 0L,
|
||||
|
||||
@ -420,7 +420,7 @@ public class RMIConnector implements JMXConnector, Serializable, JMXAddressable
|
||||
new PerThreadGroupPool.Create<ThreadPoolExecutor>() {
|
||||
public ThreadPoolExecutor createThreadPool(ThreadGroup group) {
|
||||
ThreadFactory daemonThreadFactory = new DaemonThreadFactory(
|
||||
"RMIConnector listener dispatch %d");
|
||||
"JMX RMIConnector listener dispatch %d");
|
||||
ThreadPoolExecutor exec = new ThreadPoolExecutor(
|
||||
1, 10, 1, TimeUnit.SECONDS,
|
||||
new LinkedBlockingDeque<Runnable>(),
|
||||
|
||||
@ -71,6 +71,6 @@ class ClassLoadingImpl implements ClassLoadingMXBean {
|
||||
native static void setVerboseClass(boolean value);
|
||||
|
||||
public ObjectName getObjectName() {
|
||||
return Util.newObjectName(ManagementFactory.CLASS_LOADING_MXBEAN_NAME);
|
||||
return ObjectName.valueOf(ManagementFactory.CLASS_LOADING_MXBEAN_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ class CompilationImpl implements CompilationMXBean {
|
||||
}
|
||||
|
||||
public ObjectName getObjectName() {
|
||||
return Util.newObjectName(ManagementFactory.COMPILATION_MXBEAN_NAME);
|
||||
return ObjectName.valueOf(ManagementFactory.COMPILATION_MXBEAN_NAME);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -117,6 +117,6 @@ public class HotSpotDiagnostic implements HotSpotDiagnosticMXBean {
|
||||
}
|
||||
|
||||
public ObjectName getObjectName() {
|
||||
return Util.newObjectName("com.sun.management:type=HotSpotDiagnostic");
|
||||
return ObjectName.valueOf("com.sun.management:type=HotSpotDiagnostic");
|
||||
}
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ public class HotspotInternal
|
||||
|
||||
private final static String HOTSPOT_INTERNAL_MBEAN_NAME =
|
||||
"sun.management:type=HotspotInternal";
|
||||
private static ObjectName objName = Util.newObjectName(HOTSPOT_INTERNAL_MBEAN_NAME);
|
||||
private static ObjectName objName = ObjectName.valueOf(HOTSPOT_INTERNAL_MBEAN_NAME);
|
||||
private MBeanServer server = null;
|
||||
|
||||
/**
|
||||
|
||||
@ -220,7 +220,7 @@ public class ManagementFactoryHelper {
|
||||
*/
|
||||
private static void addMBean(MBeanServer mbs, Object mbean, String mbeanName) {
|
||||
try {
|
||||
final ObjectName objName = Util.newObjectName(mbeanName);
|
||||
final ObjectName objName = ObjectName.valueOf(mbeanName);
|
||||
|
||||
// inner class requires these fields to be final
|
||||
final MBeanServer mbs0 = mbs;
|
||||
@ -280,7 +280,7 @@ public class ManagementFactoryHelper {
|
||||
|
||||
private static void unregisterMBean(MBeanServer mbs, String mbeanName) {
|
||||
try {
|
||||
final ObjectName objName = Util.newObjectName(mbeanName);
|
||||
final ObjectName objName = ObjectName.valueOf(mbeanName);
|
||||
|
||||
// inner class requires these fields to be final
|
||||
final MBeanServer mbs0 = mbs;
|
||||
|
||||
@ -177,7 +177,7 @@ class MemoryImpl extends NotificationEmitterSupport
|
||||
}
|
||||
|
||||
public ObjectName getObjectName() {
|
||||
return Util.newObjectName(ManagementFactory.MEMORY_MXBEAN_NAME);
|
||||
return ObjectName.valueOf(ManagementFactory.MEMORY_MXBEAN_NAME);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -74,7 +74,7 @@ public class OperatingSystemImpl implements OperatingSystemMXBean {
|
||||
}
|
||||
}
|
||||
public ObjectName getObjectName() {
|
||||
return Util.newObjectName(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME);
|
||||
return ObjectName.valueOf(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -149,7 +149,7 @@ class RuntimeImpl implements RuntimeMXBean {
|
||||
}
|
||||
|
||||
public ObjectName getObjectName() {
|
||||
return Util.newObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME);
|
||||
return ObjectName.valueOf(ManagementFactory.RUNTIME_MXBEAN_NAME);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -415,7 +415,7 @@ class ThreadImpl implements ThreadMXBean {
|
||||
private static native void resetContentionTimes0(long tid);
|
||||
|
||||
public ObjectName getObjectName() {
|
||||
return Util.newObjectName(ManagementFactory.THREAD_MXBEAN_NAME);
|
||||
return ObjectName.valueOf(ManagementFactory.THREAD_MXBEAN_NAME);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -43,12 +43,8 @@ class Util {
|
||||
return (String[]) list.toArray(EMPTY_STRING_ARRAY);
|
||||
}
|
||||
|
||||
static ObjectName newObjectName(String name) {
|
||||
return com.sun.jmx.mbeanserver.Util.newObjectName(name);
|
||||
}
|
||||
|
||||
public static ObjectName newObjectName(String domainAndType, String name) {
|
||||
return newObjectName(domainAndType + ",name=" + name);
|
||||
return ObjectName.valueOf(domainAndType + ",name=" + name);
|
||||
}
|
||||
|
||||
private static ManagementPermission monitorPermission =
|
||||
|
||||
@ -73,6 +73,7 @@ class ChunkedOutputStream extends FilterOutputStream
|
||||
if (count == CHUNK_SIZE) {
|
||||
writeChunk();
|
||||
}
|
||||
assert count < CHUNK_SIZE;
|
||||
}
|
||||
|
||||
public void write (byte[]b, int off, int len) throws IOException {
|
||||
@ -86,20 +87,22 @@ class ChunkedOutputStream extends FilterOutputStream
|
||||
writeChunk();
|
||||
len -= remain;
|
||||
off += remain;
|
||||
while (len > CHUNK_SIZE) {
|
||||
while (len >= CHUNK_SIZE) {
|
||||
System.arraycopy (b,off,buf,OFFSET,CHUNK_SIZE);
|
||||
len -= CHUNK_SIZE;
|
||||
off += CHUNK_SIZE;
|
||||
count = CHUNK_SIZE;
|
||||
writeChunk();
|
||||
}
|
||||
pos = OFFSET;
|
||||
}
|
||||
if (len > 0) {
|
||||
System.arraycopy (b,off,buf,pos,len);
|
||||
count += len;
|
||||
pos += len;
|
||||
}
|
||||
if (count == CHUNK_SIZE) {
|
||||
writeChunk();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -803,7 +803,7 @@ public class Config {
|
||||
for (int j = 0; j < line.length(); j++) {
|
||||
if (line.charAt(j) == '=') {
|
||||
int index;
|
||||
key = line.substring(0, j - 1).trim();
|
||||
key = line.substring(0, j).trim();
|
||||
if (! exists(key, keyVector)) {
|
||||
keyVector.addElement(key);
|
||||
nameVector = new Vector<String> ();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. 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
|
||||
@ -29,12 +29,18 @@ import java.math.BigInteger;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.PublicKey;
|
||||
import java.security.SignatureException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateExpiredException;
|
||||
import java.security.cert.CertificateNotYetValidException;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.CertPathValidatorException.BasicReason;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.cert.PKIXCertPathChecker;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.PKIXReason;
|
||||
import java.security.cert.TrustAnchor;
|
||||
import java.security.interfaces.DSAParams;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
@ -152,11 +158,11 @@ class BasicChecker extends PKIXCertPathChecker {
|
||||
|
||||
try {
|
||||
cert.verify(prevPubKey, sigProvider);
|
||||
} catch (Exception e) {
|
||||
if (debug != null) {
|
||||
debug.println(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
} catch (SignatureException e) {
|
||||
throw new CertPathValidatorException
|
||||
(msg + " check failed", e, null, -1,
|
||||
BasicReason.INVALID_SIGNATURE);
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new CertPathValidatorException(msg + " check failed", e);
|
||||
}
|
||||
|
||||
@ -176,12 +182,12 @@ class BasicChecker extends PKIXCertPathChecker {
|
||||
|
||||
try {
|
||||
cert.checkValidity(date);
|
||||
} catch (Exception e) {
|
||||
if (debug != null) {
|
||||
debug.println(e.getMessage());
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new CertPathValidatorException(msg + " check failed", e);
|
||||
} catch (CertificateExpiredException e) {
|
||||
throw new CertPathValidatorException
|
||||
(msg + " check failed", e, null, -1, BasicReason.EXPIRED);
|
||||
} catch (CertificateNotYetValidException e) {
|
||||
throw new CertPathValidatorException
|
||||
(msg + " check failed", e, null, -1, BasicReason.NOT_YET_VALID);
|
||||
}
|
||||
|
||||
if (debug != null)
|
||||
@ -204,12 +210,16 @@ class BasicChecker extends PKIXCertPathChecker {
|
||||
// reject null or empty issuer DNs
|
||||
|
||||
if (X500Name.asX500Name(currIssuer).isEmpty()) {
|
||||
throw new CertPathValidatorException(msg + " check failed: " +
|
||||
"empty/null issuer DN in certificate is invalid");
|
||||
throw new CertPathValidatorException
|
||||
(msg + " check failed: " +
|
||||
"empty/null issuer DN in certificate is invalid", null,
|
||||
null, -1, PKIXReason.NAME_CHAINING);
|
||||
}
|
||||
|
||||
if (!(currIssuer.equals(prevSubject))) {
|
||||
throw new CertPathValidatorException(msg + " check failed");
|
||||
throw new CertPathValidatorException
|
||||
(msg + " check failed", null, null, -1,
|
||||
PKIXReason.NAME_CHAINING);
|
||||
}
|
||||
|
||||
if (debug != null)
|
||||
@ -270,7 +280,7 @@ class BasicChecker extends PKIXCertPathChecker {
|
||||
params.getQ(),
|
||||
params.getG());
|
||||
usableKey = kf.generatePublic(ks);
|
||||
} catch (Exception e) {
|
||||
} catch (GeneralSecurityException e) {
|
||||
throw new CertPathValidatorException("Unable to generate key with" +
|
||||
" inherited parameters: " +
|
||||
e.getMessage(), e);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -32,9 +32,10 @@ import java.util.HashSet;
|
||||
import java.io.IOException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.cert.PKIXCertPathChecker;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.PKIXReason;
|
||||
import sun.security.util.Debug;
|
||||
import sun.security.x509.PKIXExtensions;
|
||||
import sun.security.x509.NameConstraintsExtension;
|
||||
@ -147,7 +148,8 @@ class ConstraintsChecker extends PKIXCertPathChecker {
|
||||
|
||||
try {
|
||||
if (!prevNC.verify(currCert)) {
|
||||
throw new CertPathValidatorException(msg + " check failed");
|
||||
throw new CertPathValidatorException(msg + " check failed",
|
||||
null, null, -1, PKIXReason.INVALID_NAME);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
throw new CertPathValidatorException(ioe);
|
||||
@ -228,8 +230,9 @@ class ConstraintsChecker extends PKIXCertPathChecker {
|
||||
if (i < certPathLength) {
|
||||
int pathLenConstraint = currCert.getBasicConstraints();
|
||||
if (pathLenConstraint == -1) {
|
||||
throw new CertPathValidatorException(msg + " check failed: "
|
||||
+ "this is not a CA certificate");
|
||||
throw new CertPathValidatorException
|
||||
(msg + " check failed: this is not a CA certificate", null,
|
||||
null, -1, PKIXReason.NOT_CA_CERT);
|
||||
}
|
||||
|
||||
if (!X509CertImpl.isSelfIssued(currCert)) {
|
||||
@ -237,7 +240,8 @@ class ConstraintsChecker extends PKIXCertPathChecker {
|
||||
throw new CertPathValidatorException
|
||||
(msg + " check failed: pathLenConstraint violated - "
|
||||
+ "this cert must be the last cert in the "
|
||||
+ "certification path");
|
||||
+ "certification path", null, null, -1,
|
||||
PKIXReason.PATH_TOO_LONG);
|
||||
}
|
||||
maxPathLength--;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. 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
|
||||
@ -39,6 +39,7 @@ import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.*;
|
||||
import java.security.cert.CertPathValidatorException.BasicReason;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
import sun.security.util.Debug;
|
||||
@ -268,7 +269,8 @@ class CrlRevocationChecker extends PKIXCertPathChecker {
|
||||
" circular dependency");
|
||||
}
|
||||
throw new CertPathValidatorException
|
||||
("Could not determine revocation status");
|
||||
("Could not determine revocation status", null, null, -1,
|
||||
BasicReason.UNDETERMINED_REVOCATION_STATUS);
|
||||
}
|
||||
|
||||
// init the state for this run
|
||||
@ -324,7 +326,8 @@ class CrlRevocationChecker extends PKIXCertPathChecker {
|
||||
return;
|
||||
} else {
|
||||
throw new CertPathValidatorException
|
||||
("Could not determine revocation status");
|
||||
("Could not determine revocation status", null, null, -1,
|
||||
BasicReason.UNDETERMINED_REVOCATION_STATUS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -370,7 +373,8 @@ class CrlRevocationChecker extends PKIXCertPathChecker {
|
||||
+ unresCritExts);
|
||||
}
|
||||
throw new CertPathValidatorException
|
||||
("Could not determine revocation status");
|
||||
("Could not determine revocation status", null, null,
|
||||
-1, BasicReason.UNDETERMINED_REVOCATION_STATUS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -378,10 +382,11 @@ class CrlRevocationChecker extends PKIXCertPathChecker {
|
||||
if (reasonCode == null) {
|
||||
reasonCode = CRLReason.UNSPECIFIED;
|
||||
}
|
||||
throw new CertPathValidatorException(
|
||||
new CertificateRevokedException
|
||||
(entry.getRevocationDate(), reasonCode,
|
||||
crl.getIssuerX500Principal(), entry.getExtensions()));
|
||||
Throwable t = new CertificateRevokedException
|
||||
(entry.getRevocationDate(), reasonCode,
|
||||
crl.getIssuerX500Principal(), entry.getExtensions());
|
||||
throw new CertPathValidatorException(t.getMessage(), t,
|
||||
null, -1, BasicReason.REVOKED);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -428,7 +433,8 @@ class CrlRevocationChecker extends PKIXCertPathChecker {
|
||||
" circular dependency");
|
||||
}
|
||||
throw new CertPathValidatorException
|
||||
("Could not determine revocation status");
|
||||
("Could not determine revocation status", null, null,
|
||||
-1, BasicReason.UNDETERMINED_REVOCATION_STATUS);
|
||||
}
|
||||
|
||||
// If prevKey wasn't trusted, maybe we just didn't have the right
|
||||
@ -617,7 +623,7 @@ class CrlRevocationChecker extends PKIXCertPathChecker {
|
||||
return;
|
||||
} catch (CertPathValidatorException cpve) {
|
||||
// If it is revoked, rethrow exception
|
||||
if (cpve.getCause() instanceof CertificateRevokedException) {
|
||||
if (cpve.getReason() == BasicReason.REVOKED) {
|
||||
throw cpve;
|
||||
}
|
||||
// Otherwise, ignore the exception and
|
||||
@ -628,7 +634,8 @@ class CrlRevocationChecker extends PKIXCertPathChecker {
|
||||
throw new CertPathValidatorException(iape);
|
||||
} catch (CertPathBuilderException cpbe) {
|
||||
throw new CertPathValidatorException
|
||||
("Could not determine revocation status", cpbe);
|
||||
("Could not determine revocation status", null, null,
|
||||
-1, BasicReason.UNDETERMINED_REVOCATION_STATUS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,6 +32,7 @@ import java.security.GeneralSecurityException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.PKIXReason;
|
||||
import java.security.cert.CertStore;
|
||||
import java.security.cert.CertStoreException;
|
||||
import java.security.cert.PKIXBuilderParameters;
|
||||
@ -732,8 +733,9 @@ class ForwardBuilder extends Builder {
|
||||
PKIXExtensions.ExtendedKeyUsage_Id.toString());
|
||||
|
||||
if (!unresCritExts.isEmpty())
|
||||
throw new CertificateException("Unrecognized critical "
|
||||
+ "extension(s)");
|
||||
throw new CertPathValidatorException
|
||||
("Unrecognized critical extension(s)", null, null, -1,
|
||||
PKIXReason.UNRECOGNIZED_CRIT_EXT);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2003 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. 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
|
||||
@ -27,6 +27,7 @@ package sun.security.provider.certpath;
|
||||
|
||||
import java.util.*;
|
||||
import java.security.cert.*;
|
||||
import java.security.cert.PKIXReason;
|
||||
|
||||
import sun.security.util.Debug;
|
||||
import sun.security.x509.PKIXExtensions;
|
||||
@ -75,11 +76,12 @@ class KeyChecker extends PKIXCertPathChecker {
|
||||
if (!forward) {
|
||||
remainingCerts = certPathLen;
|
||||
} else {
|
||||
throw new CertPathValidatorException("forward checking not supported");
|
||||
throw new CertPathValidatorException
|
||||
("forward checking not supported");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isForwardCheckingSupported() {
|
||||
public final boolean isForwardCheckingSupported() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -155,8 +157,9 @@ class KeyChecker extends PKIXCertPathChecker {
|
||||
|
||||
// throw an exception if the keyCertSign bit is not set
|
||||
if (!keyUsageBits[keyCertSign]) {
|
||||
throw new CertPathValidatorException(msg + " check failed: "
|
||||
+ "keyCertSign bit is not set");
|
||||
throw new CertPathValidatorException
|
||||
(msg + " check failed: keyCertSign bit is not set", null,
|
||||
null, -1, PKIXReason.INVALID_KEY_USAGE);
|
||||
}
|
||||
|
||||
if (debug != null) {
|
||||
|
||||
@ -33,6 +33,7 @@ import java.security.Principal;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.Security;
|
||||
import java.security.cert.*;
|
||||
import java.security.cert.CertPathValidatorException.BasicReason;
|
||||
import java.net.*;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
@ -381,17 +382,18 @@ class OCSPChecker extends PKIXCertPathChecker {
|
||||
}
|
||||
|
||||
if (certOCSPStatus == OCSPResponse.CERT_STATUS_REVOKED) {
|
||||
throw new CertPathValidatorException(
|
||||
new CertificateRevokedException(
|
||||
Throwable t = new CertificateRevokedException(
|
||||
ocspResponse.getRevocationTime(),
|
||||
ocspResponse.getRevocationReason(),
|
||||
responderCert.getSubjectX500Principal(),
|
||||
ocspResponse.getSingleExtensions()));
|
||||
ocspResponse.getSingleExtensions());
|
||||
throw new CertPathValidatorException(t.getMessage(), t,
|
||||
null, -1, BasicReason.REVOKED);
|
||||
|
||||
} else if (certOCSPStatus == OCSPResponse.CERT_STATUS_UNKNOWN) {
|
||||
throw new CertPathValidatorException(
|
||||
"Certificate's revocation status is unknown", null, cp,
|
||||
remainingCerts);
|
||||
remainingCerts, BasicReason.UNDETERMINED_REVOCATION_STATUS);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new CertPathValidatorException(e);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. 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
|
||||
@ -38,6 +38,7 @@ import java.security.cert.CertPathValidatorResult;
|
||||
import java.security.cert.PKIXCertPathChecker;
|
||||
import java.security.cert.PKIXCertPathValidatorResult;
|
||||
import java.security.cert.PKIXParameters;
|
||||
import java.security.cert.PKIXReason;
|
||||
import java.security.cert.PolicyNode;
|
||||
import java.security.cert.TrustAnchor;
|
||||
import java.security.cert.X509Certificate;
|
||||
@ -47,7 +48,6 @@ import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
import sun.security.util.Debug;
|
||||
|
||||
@ -67,6 +67,7 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
|
||||
private List<PKIXCertPathChecker> userCheckers;
|
||||
private String sigProvider;
|
||||
private BasicChecker basicChecker;
|
||||
private String ocspProperty;
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
@ -126,7 +127,7 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
|
||||
|
||||
// Must copy elements of certList into a new modifiable List before
|
||||
// calling Collections.reverse().
|
||||
List<X509Certificate> certList = new ArrayList<X509Certificate>
|
||||
ArrayList<X509Certificate> certList = new ArrayList<X509Certificate>
|
||||
((List<X509Certificate>)cp.getCertificates());
|
||||
if (debug != null) {
|
||||
if (certList.isEmpty()) {
|
||||
@ -201,7 +202,8 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
|
||||
}
|
||||
// (b) otherwise, generate new exception
|
||||
throw new CertPathValidatorException
|
||||
("Path does not chain with any of the trust anchors");
|
||||
("Path does not chain with any of the trust anchors",
|
||||
null, null, -1, PKIXReason.NO_TRUST_ANCHOR);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -210,7 +212,6 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
|
||||
*/
|
||||
private boolean isWorthTrying(X509Certificate trustedCert,
|
||||
X509Certificate firstCert)
|
||||
throws CertPathValidatorException
|
||||
{
|
||||
if (debug != null) {
|
||||
debug.println("PKIXCertPathValidator.isWorthTrying() checking "
|
||||
@ -240,7 +241,6 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
|
||||
* Internal method to setup the internal state
|
||||
*/
|
||||
private void populateVariables(PKIXParameters pkixParam)
|
||||
throws CertPathValidatorException
|
||||
{
|
||||
// default value for testDate is current time
|
||||
testDate = pkixParam.getDate();
|
||||
@ -250,6 +250,17 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
|
||||
|
||||
userCheckers = pkixParam.getCertPathCheckers();
|
||||
sigProvider = pkixParam.getSigProvider();
|
||||
|
||||
if (pkixParam.isRevocationEnabled()) {
|
||||
// Examine OCSP security property
|
||||
ocspProperty = AccessController.doPrivileged(
|
||||
new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return
|
||||
Security.getProperty(OCSPChecker.OCSP_ENABLE_PROP);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -259,12 +270,9 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
|
||||
*/
|
||||
private PolicyNode doValidate(
|
||||
TrustAnchor anchor, CertPath cpOriginal,
|
||||
List<X509Certificate> certList, PKIXParameters pkixParam,
|
||||
ArrayList<X509Certificate> certList, PKIXParameters pkixParam,
|
||||
PolicyNodeImpl rootNode) throws CertPathValidatorException
|
||||
{
|
||||
List<PKIXCertPathChecker> certPathCheckers =
|
||||
new ArrayList<PKIXCertPathChecker>();
|
||||
|
||||
int certPathLen = certList.size();
|
||||
|
||||
basicChecker = new BasicChecker(anchor, testDate, sigProvider, false);
|
||||
@ -281,6 +289,8 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
|
||||
pkixParam.getPolicyQualifiersRejected(),
|
||||
rootNode);
|
||||
|
||||
ArrayList<PKIXCertPathChecker> certPathCheckers =
|
||||
new ArrayList<PKIXCertPathChecker>();
|
||||
// add standard checkers that we will be using
|
||||
certPathCheckers.add(keyChecker);
|
||||
certPathCheckers.add(constraintsChecker);
|
||||
@ -290,15 +300,6 @@ public class PKIXCertPathValidator extends CertPathValidatorSpi {
|
||||
// only add a revocationChecker if revocation is enabled
|
||||
if (pkixParam.isRevocationEnabled()) {
|
||||
|
||||
// Examine OCSP security property
|
||||
String ocspProperty = AccessController.doPrivileged(
|
||||
new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return
|
||||
Security.getProperty(OCSPChecker.OCSP_ENABLE_PROP);
|
||||
}
|
||||
});
|
||||
|
||||
// Use OCSP if it has been enabled
|
||||
if ("true".equalsIgnoreCase(ocspProperty)) {
|
||||
OCSPChecker ocspChecker =
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. 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
|
||||
@ -30,11 +30,12 @@ import sun.security.util.Debug;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Iterator;
|
||||
import java.security.cert.CertificateRevokedException;
|
||||
import java.security.cert.CertPath;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.CertificateRevokedException;
|
||||
import java.security.cert.CertPathValidatorException.BasicReason;
|
||||
import java.security.cert.PKIXCertPathChecker;
|
||||
import java.security.cert.PKIXReason;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
/**
|
||||
@ -153,10 +154,11 @@ class PKIXMasterCertPathValidator {
|
||||
*/
|
||||
CertPathValidatorException currentCause =
|
||||
new CertPathValidatorException(cpve.getMessage(),
|
||||
cpve.getCause(), cpOriginal, cpSize - (i + 1));
|
||||
cpve.getCause(), cpOriginal, cpSize - (i + 1),
|
||||
cpve.getReason());
|
||||
|
||||
// Check if OCSP has confirmed that the cert was revoked
|
||||
if (cpve.getCause() instanceof CertificateRevokedException) {
|
||||
if (cpve.getReason() == BasicReason.REVOKED) {
|
||||
throw currentCause;
|
||||
}
|
||||
// Check if it is appropriate to failover
|
||||
@ -184,7 +186,8 @@ class PKIXMasterCertPathValidator {
|
||||
debug.println("checking for unresolvedCritExts");
|
||||
if (!unresolvedCritExts.isEmpty()) {
|
||||
throw new CertPathValidatorException("unrecognized " +
|
||||
"critical extension(s)", null, cpOriginal, cpSize-(i+1));
|
||||
"critical extension(s)", null, cpOriginal, cpSize-(i+1),
|
||||
PKIXReason.UNRECOGNIZED_CRIT_EXT);
|
||||
}
|
||||
|
||||
if (debug != null)
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. 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
|
||||
@ -30,11 +30,12 @@ import java.io.IOException;
|
||||
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.cert.PKIXCertPathChecker;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.PKIXCertPathChecker;
|
||||
import java.security.cert.PKIXReason;
|
||||
import java.security.cert.PolicyNode;
|
||||
import java.security.cert.PolicyQualifierInfo;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import sun.security.util.Debug;
|
||||
import sun.security.x509.CertificatePoliciesExtension;
|
||||
@ -482,8 +483,9 @@ class PolicyChecker extends PKIXCertPathChecker {
|
||||
// the policyQualifiersRejected flag is set in the params
|
||||
if (!pQuals.isEmpty() && rejectPolicyQualifiers &&
|
||||
policiesCritical) {
|
||||
throw new CertPathValidatorException("critical " +
|
||||
"policy qualifiers present in certificate");
|
||||
throw new CertPathValidatorException(
|
||||
"critical policy qualifiers present in certificate",
|
||||
null, null, -1, PKIXReason.INVALID_POLICY);
|
||||
}
|
||||
|
||||
// PKIX: Section 6.1.3: Step (d)(1)(i)
|
||||
@ -567,7 +569,8 @@ class PolicyChecker extends PKIXCertPathChecker {
|
||||
|
||||
if ((explicitPolicy == 0) && (rootNode == null)) {
|
||||
throw new CertPathValidatorException
|
||||
("non-null policy tree required and policy tree is null");
|
||||
("non-null policy tree required and policy tree is null",
|
||||
null, null, -1, PKIXReason.INVALID_POLICY);
|
||||
}
|
||||
|
||||
return rootNode;
|
||||
@ -776,12 +779,14 @@ class PolicyChecker extends PKIXCertPathChecker {
|
||||
|
||||
if (issuerDomain.equals(ANY_POLICY)) {
|
||||
throw new CertPathValidatorException
|
||||
("encountered an issuerDomainPolicy of ANY_POLICY");
|
||||
("encountered an issuerDomainPolicy of ANY_POLICY",
|
||||
null, null, -1, PKIXReason.INVALID_POLICY);
|
||||
}
|
||||
|
||||
if (subjectDomain.equals(ANY_POLICY)) {
|
||||
throw new CertPathValidatorException
|
||||
("encountered a subjectDomainPolicy of ANY_POLICY");
|
||||
("encountered a subjectDomainPolicy of ANY_POLICY",
|
||||
null, null, -1, PKIXReason.INVALID_POLICY);
|
||||
}
|
||||
|
||||
Set<PolicyNodeImpl> validNodes =
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. 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
|
||||
@ -29,14 +29,15 @@ import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.Principal;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.CertStore;
|
||||
import java.security.cert.CertStoreException;
|
||||
import java.security.cert.PKIXBuilderParameters;
|
||||
import java.security.cert.PKIXCertPathChecker;
|
||||
import java.security.cert.PKIXParameters;
|
||||
import java.security.cert.PKIXReason;
|
||||
import java.security.cert.TrustAnchor;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.security.cert.X509CertSelector;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@ -402,7 +403,8 @@ class ReverseBuilder extends Builder {
|
||||
*/
|
||||
if ((currentState.remainingCACerts <= 0) && !X509CertImpl.isSelfIssued(cert)) {
|
||||
throw new CertPathValidatorException
|
||||
("pathLenConstraint violated, path too long");
|
||||
("pathLenConstraint violated, path too long", null,
|
||||
null, -1, PKIXReason.PATH_TOO_LONG);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -438,7 +440,8 @@ class ReverseBuilder extends Builder {
|
||||
try {
|
||||
if (!currentState.nc.verify(cert)){
|
||||
throw new CertPathValidatorException
|
||||
("name constraints check failed");
|
||||
("name constraints check failed", null, null, -1,
|
||||
PKIXReason.INVALID_NAME);
|
||||
}
|
||||
} catch (IOException ioe){
|
||||
throw new CertPathValidatorException(ioe);
|
||||
@ -483,7 +486,9 @@ class ReverseBuilder extends Builder {
|
||||
unresolvedCritExts.remove(PKIXExtensions.ExtendedKeyUsage_Id.toString());
|
||||
|
||||
if (!unresolvedCritExts.isEmpty())
|
||||
throw new CertificateException("Unrecognized critical extension(s)");
|
||||
throw new CertPathValidatorException
|
||||
("Unrecognized critical extension(s)", null, null, -1,
|
||||
PKIXReason.UNRECOGNIZED_CRIT_EXT);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2000-2008 Sun Microsystems, Inc. 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
|
||||
@ -30,6 +30,9 @@ import java.security.GeneralSecurityException;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.Principal;
|
||||
import java.security.PublicKey;
|
||||
import java.security.cert.*;
|
||||
import java.security.cert.PKIXReason;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@ -39,10 +42,6 @@ import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Set;
|
||||
|
||||
import java.security.cert.*;
|
||||
import java.security.interfaces.DSAPublicKey;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
|
||||
import sun.security.x509.X500Name;
|
||||
@ -565,8 +564,9 @@ public final class SunCertPathBuilder extends CertPathBuilderSpi {
|
||||
(PKIXExtensions.ExtendedKeyUsage_Id.toString());
|
||||
|
||||
if (!unresCritExts.isEmpty()) {
|
||||
throw new CertPathValidatorException("unrecognized "
|
||||
+ "critical extension(s)");
|
||||
throw new CertPathValidatorException
|
||||
("unrecognized critical extension(s)", null,
|
||||
null, -1, PKIXReason.UNRECOGNIZED_CRIT_EXT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,18 +30,15 @@ import java.awt.event.*;
|
||||
import java.beans.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Array;
|
||||
import java.text.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.accessibility.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.event.*;
|
||||
import javax.swing.filechooser.*;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
|
||||
import com.sun.tools.jconsole.JConsoleContext;
|
||||
import com.sun.tools.jconsole.JConsoleContext.ConnectionState;
|
||||
|
||||
import static com.sun.tools.jconsole.JConsoleContext.ConnectionState.*;
|
||||
|
||||
@ -130,6 +127,7 @@ public class Plotter extends JComponent
|
||||
private int bottomMargin = 45;
|
||||
private int leftMargin = 65;
|
||||
private int rightMargin = 70;
|
||||
private final boolean displayLegend;
|
||||
|
||||
public Plotter() {
|
||||
this(Unit.NONE, 0);
|
||||
@ -139,15 +137,21 @@ public class Plotter extends JComponent
|
||||
this(unit, 0);
|
||||
}
|
||||
|
||||
public Plotter(Unit unit, int decimals) {
|
||||
this(unit,decimals,true);
|
||||
}
|
||||
|
||||
// Note: If decimals > 0 then values must be decimally shifted left
|
||||
// that many places, i.e. multiplied by Math.pow(10.0, decimals).
|
||||
public Plotter(Unit unit, int decimals) {
|
||||
public Plotter(Unit unit, int decimals, boolean displayLegend) {
|
||||
this.displayLegend = displayLegend;
|
||||
setUnit(unit);
|
||||
setDecimals(decimals);
|
||||
|
||||
enableEvents(AWTEvent.MOUSE_EVENT_MASK);
|
||||
|
||||
addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(MouseEvent e) {
|
||||
if (getParent() instanceof PlotterPanel) {
|
||||
getParent().requestFocusInWindow();
|
||||
@ -240,6 +244,7 @@ public class Plotter extends JComponent
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public JPopupMenu getComponentPopupMenu() {
|
||||
if (popupMenu == null) {
|
||||
popupMenu = new JPopupMenu(Resources.getText("Chart:"));
|
||||
@ -330,6 +335,7 @@ public class Plotter extends JComponent
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
|
||||
@ -670,7 +676,7 @@ public class Plotter extends JComponent
|
||||
curValue += "%";
|
||||
}
|
||||
int valWidth = fm.stringWidth(curValue);
|
||||
String legend = seq.name;
|
||||
String legend = (displayLegend?seq.name:"");
|
||||
int legendWidth = fm.stringWidth(legend);
|
||||
if (checkRightMargin(valWidth) || checkRightMargin(legendWidth)) {
|
||||
// Wait for next repaint
|
||||
@ -986,10 +992,12 @@ public class Plotter extends JComponent
|
||||
}
|
||||
|
||||
private static class SaveDataFileChooser extends JFileChooser {
|
||||
private static final long serialVersionUID = -5182890922369369669L;
|
||||
SaveDataFileChooser() {
|
||||
setFileFilter(new FileNameExtensionFilter("CSV file", "csv"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void approveSelection() {
|
||||
File file = getSelectedFile();
|
||||
if (file != null) {
|
||||
@ -1034,6 +1042,7 @@ public class Plotter extends JComponent
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessibleContext getAccessibleContext() {
|
||||
if (accessibleContext == null) {
|
||||
accessibleContext = new AccessiblePlotter();
|
||||
@ -1042,10 +1051,12 @@ public class Plotter extends JComponent
|
||||
}
|
||||
|
||||
protected class AccessiblePlotter extends AccessibleJComponent {
|
||||
private static final long serialVersionUID = -3847205410473510922L;
|
||||
protected AccessiblePlotter() {
|
||||
setAccessibleName(getText("Plotter.accessibleName"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAccessibleName() {
|
||||
String name = super.getAccessibleName();
|
||||
|
||||
@ -1076,6 +1087,7 @@ public class Plotter extends JComponent
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AccessibleRole getAccessibleRole() {
|
||||
return AccessibleRole.CANVAS;
|
||||
}
|
||||
|
||||
@ -872,8 +872,8 @@ public class XMBeanAttributes extends XTable {
|
||||
MaximizedCellRenderer(Component comp) {
|
||||
this.comp = comp;
|
||||
Dimension d = comp.getPreferredSize();
|
||||
if (d.getHeight() > 200) {
|
||||
comp.setPreferredSize(new Dimension((int) d.getWidth(), 200));
|
||||
if (d.getHeight() > 220) {
|
||||
comp.setPreferredSize(new Dimension((int) d.getWidth(), 220));
|
||||
}
|
||||
}
|
||||
@Override
|
||||
|
||||
@ -34,7 +34,7 @@ public class XPlotter extends Plotter {
|
||||
JTable table;
|
||||
public XPlotter(JTable table,
|
||||
Plotter.Unit unit) {
|
||||
super(unit);
|
||||
super(unit,0,false);
|
||||
this.table = table;
|
||||
}
|
||||
@Override
|
||||
|
||||
@ -27,14 +27,10 @@ package sun.tools.jconsole.inspector;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.Timer;
|
||||
|
||||
import javax.management.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
import sun.tools.jconsole.*;
|
||||
|
||||
@ -127,6 +123,7 @@ public class XPlottingViewer extends PlotterPanel implements ActionListener {
|
||||
setBackground(g.getColor());
|
||||
plotter.paintComponent(g);
|
||||
}*/
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
plotterCache.remove(key);
|
||||
Timer t = timerCache.remove(key);
|
||||
@ -141,9 +138,11 @@ public class XPlottingViewer extends PlotterPanel implements ActionListener {
|
||||
JTable table) {
|
||||
final Plotter plotter = new XPlotter(table, Plotter.Unit.NONE) {
|
||||
Dimension prefSize = new Dimension(400, 170);
|
||||
@Override
|
||||
public Dimension getPreferredSize() {
|
||||
return prefSize;
|
||||
}
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
return prefSize;
|
||||
}
|
||||
@ -183,42 +182,40 @@ public class XPlottingViewer extends PlotterPanel implements ActionListener {
|
||||
return plotter;
|
||||
}
|
||||
|
||||
//Create Plotter display
|
||||
private void setupDisplay(Plotter plotter) {
|
||||
//setLayout(new GridLayout(2,0));
|
||||
GridBagLayout gbl = new GridBagLayout();
|
||||
setLayout(gbl);
|
||||
final JPanel buttonPanel = new JPanel();
|
||||
final GridBagLayout gbl = new GridBagLayout();
|
||||
buttonPanel.setLayout(gbl);
|
||||
setLayout(new BorderLayout());
|
||||
plotButton = new JButton(Resources.getText("Discard chart"));
|
||||
plotButton.addActionListener(this);
|
||||
plotButton.setEnabled(true);
|
||||
|
||||
// Add the display to the top four cells
|
||||
GridBagConstraints buttonConstraints = new GridBagConstraints();
|
||||
buttonConstraints.gridx = 0;
|
||||
buttonConstraints.gridy = 0;
|
||||
buttonConstraints.fill = GridBagConstraints.VERTICAL;
|
||||
buttonConstraints.anchor = GridBagConstraints.CENTER;
|
||||
gbl.setConstraints(plotButton, buttonConstraints);
|
||||
add(plotButton);
|
||||
|
||||
GridBagConstraints plotterConstraints = new GridBagConstraints();
|
||||
plotterConstraints.gridx = 0;
|
||||
plotterConstraints.gridy = 1;
|
||||
plotterConstraints.weightx = 1;
|
||||
//plotterConstraints.gridwidth = (int) plotter.getPreferredSize().getWidth();
|
||||
//plotterConstraints.gridheight = (int) plotter.getPreferredSize().getHeight();
|
||||
plotterConstraints.fill = GridBagConstraints.VERTICAL;
|
||||
gbl.setConstraints(plotter, plotterConstraints);
|
||||
|
||||
|
||||
//bordered = new JPanel();
|
||||
//bordered.setPreferredSize(new Dimension(400, 250));
|
||||
//bordered.add(plotButton);
|
||||
//bordered.add(plotter);
|
||||
|
||||
//add(bordered);
|
||||
buttonPanel.add(plotButton);
|
||||
|
||||
if (attributeName != null && attributeName.length()!=0) {
|
||||
final JPanel plotterLabelPanel = new JPanel();
|
||||
final JLabel label = new JLabel(attributeName);
|
||||
final GridBagLayout gbl2 = new GridBagLayout();
|
||||
plotterLabelPanel.setLayout(gbl2);
|
||||
final GridBagConstraints labelConstraints = new GridBagConstraints();
|
||||
labelConstraints.gridx = 0;
|
||||
labelConstraints.gridy = 0;
|
||||
labelConstraints.fill = GridBagConstraints.VERTICAL;
|
||||
labelConstraints.anchor = GridBagConstraints.CENTER;
|
||||
labelConstraints.ipady = 10;
|
||||
gbl2.setConstraints(label, labelConstraints);
|
||||
plotterLabelPanel.add(label);
|
||||
add(plotterLabelPanel, BorderLayout.NORTH);
|
||||
}
|
||||
setPlotter(plotter);
|
||||
add(buttonPanel, BorderLayout.SOUTH);
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 1995-2006 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 1995-2008 Sun Microsystems, Inc. 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
|
||||
@ -722,16 +722,22 @@ ZIP_Put_In_Cache(const char *name, ZFILE zfd, char **pmsg, jlong lastModified)
|
||||
}
|
||||
|
||||
len = zip->len = ZFILE_Lseek(zfd, 0, SEEK_END);
|
||||
if (len == -1) {
|
||||
if (pmsg && JVM_GetLastErrorString(errbuf, sizeof(errbuf)) > 0)
|
||||
*pmsg = errbuf;
|
||||
if (len <= 0) {
|
||||
if (len == 0) { /* zip file is empty */
|
||||
if (pmsg) {
|
||||
*pmsg = "zip file is empty";
|
||||
}
|
||||
} else { /* error */
|
||||
if (pmsg && JVM_GetLastErrorString(errbuf, sizeof(errbuf)) > 0)
|
||||
*pmsg = errbuf;
|
||||
}
|
||||
ZFILE_Close(zfd);
|
||||
freeZip(zip);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
zip->zfd = zfd;
|
||||
if (readCEN(zip, -1) <= 0) {
|
||||
if (readCEN(zip, -1) < 0) {
|
||||
/* An error occurred while trying to read the zip file */
|
||||
if (pmsg != 0) {
|
||||
/* Set the zip error message */
|
||||
@ -947,10 +953,15 @@ jzentry *
|
||||
ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
|
||||
{
|
||||
unsigned int hsh = hash(name);
|
||||
jint idx = zip->table[hsh % zip->tablelen];
|
||||
jzentry *ze;
|
||||
jint idx;
|
||||
jzentry *ze = 0;
|
||||
|
||||
ZIP_Lock(zip);
|
||||
if (zip->total == 0) {
|
||||
goto Finally;
|
||||
}
|
||||
|
||||
idx = zip->table[hsh % zip->tablelen];
|
||||
|
||||
/*
|
||||
* This while loop is an optimization where a double lookup
|
||||
@ -1025,6 +1036,7 @@ ZIP_GetEntry(jzfile *zip, char *name, jint ulen)
|
||||
ulen = 0;
|
||||
}
|
||||
|
||||
Finally:
|
||||
ZIP_Unlock(zip);
|
||||
return ze;
|
||||
}
|
||||
|
||||
@ -41,8 +41,7 @@ import java.util.*;
|
||||
/********** target program **********/
|
||||
|
||||
class ClassesByName2Targ {
|
||||
public static void ready() {
|
||||
System.out.println("Ready!");
|
||||
static void bkpt() {
|
||||
}
|
||||
|
||||
public static void main(String[] args){
|
||||
@ -74,22 +73,24 @@ class ClassesByName2Targ {
|
||||
}
|
||||
};
|
||||
|
||||
ready();
|
||||
|
||||
two.start();
|
||||
one.start();
|
||||
zero.start();
|
||||
|
||||
try {
|
||||
zero.join();
|
||||
System.out.println("zero joined");
|
||||
one.join();
|
||||
System.out.println("one joined");
|
||||
two.join();
|
||||
System.out.println("two joined");
|
||||
} catch (InterruptedException iex) {
|
||||
iex.printStackTrace();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
bkpt();
|
||||
System.out.println("Goodbye from ClassesByName2Targ!");
|
||||
}
|
||||
}
|
||||
@ -97,29 +98,64 @@ class ClassesByName2Targ {
|
||||
/********** test program **********/
|
||||
|
||||
public class ClassesByName2Test extends TestScaffold {
|
||||
volatile boolean stop = false;
|
||||
|
||||
ClassesByName2Test (String args[]) {
|
||||
super(args);
|
||||
}
|
||||
|
||||
public void breakpointReached(BreakpointEvent event) {
|
||||
System.out.println("Got BreakpointEvent: " + event);
|
||||
stop = true;
|
||||
}
|
||||
|
||||
public void eventSetComplete(EventSet set) {
|
||||
// Don't resume.
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
new ClassesByName2Test(args).startTests();
|
||||
}
|
||||
|
||||
protected void runTests() throws Exception {
|
||||
/*
|
||||
* Get to the top of ready()
|
||||
*/
|
||||
startTo("ClassesByName2Targ", "ready", "()V");
|
||||
void breakpointAtMethod(ReferenceType ref, String methodName)
|
||||
throws Exception {
|
||||
List meths = ref.methodsByName(methodName);
|
||||
if (meths.size() != 1) {
|
||||
throw new Exception("test error: should be one " +
|
||||
methodName);
|
||||
}
|
||||
Method meth = (Method)meths.get(0);
|
||||
BreakpointRequest bkptReq = vm().eventRequestManager().
|
||||
createBreakpointRequest(meth.location());
|
||||
bkptReq.enable();
|
||||
try {
|
||||
addListener (this);
|
||||
} catch (Exception ex){
|
||||
ex.printStackTrace();
|
||||
failure("failure: Could not add listener");
|
||||
throw new Exception("ClassesByname2Test: failed");
|
||||
}
|
||||
}
|
||||
|
||||
protected void runTests() throws Exception {
|
||||
BreakpointEvent bpe = startToMain("ClassesByName2Targ");
|
||||
|
||||
/*
|
||||
Bug 6263966 - Don't just resume because the debuggee can
|
||||
complete and disconnect while the following loop is
|
||||
accessing it.
|
||||
*/
|
||||
breakpointAtMethod(bpe.location().declaringType(), "bkpt");
|
||||
vm().resume();
|
||||
|
||||
int i = 0;
|
||||
while (i < 8 && !vmDisconnected) {
|
||||
i++;
|
||||
/* The test of 'stop' is so that we stop when the debuggee hits
|
||||
the bkpt. The 150 is so we stop if the debuggee
|
||||
is slow (eg, -Xcomp -server) - we don't want to
|
||||
spend all day waiting for it to get to the bkpt.
|
||||
*/
|
||||
for (int i = 0; i < 150 && !stop; i++) {
|
||||
List all = vm().allClasses();
|
||||
System.out.println("");
|
||||
System.out.println("++++ Lookup number: " + i + ". allClasses() returned " +
|
||||
System.out.println("\n++++ Lookup number: " + i + ". allClasses() returned " +
|
||||
all.size() + " classes.");
|
||||
for (Iterator it = all.iterator(); it.hasNext(); ) {
|
||||
ReferenceType cls = (ReferenceType)it.next();
|
||||
@ -135,9 +171,8 @@ public class ClassesByName2Test extends TestScaffold {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Doing vm().exit(0) instead of listenUntilVMDisconnect()
|
||||
// speeds up the test up by more than 50% in -server -Xcomp (solsparc32-fastdebug)
|
||||
// In case of a slow debuggee, we don't want to resume the debuggee and wait
|
||||
// for it to complete.
|
||||
vm().exit(0);
|
||||
|
||||
/*
|
||||
|
||||
106
jdk/test/com/sun/net/httpserver/bugs/B6744329.java
Normal file
106
jdk/test/com/sun/net/httpserver/bugs/B6744329.java
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright 2005-2006 Sun Microsystems, Inc. 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.
|
||||
*
|
||||
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug B6744329
|
||||
* @summary Exception in light weight Http server
|
||||
*/
|
||||
|
||||
import com.sun.net.httpserver.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.security.*;
|
||||
import java.security.cert.*;
|
||||
import javax.net.ssl.*;
|
||||
|
||||
public class B6744329 {
|
||||
|
||||
public static void main (String[] args) throws Exception {
|
||||
Handler handler = new Handler();
|
||||
InetSocketAddress addr = new InetSocketAddress (0);
|
||||
HttpServer server = HttpServer.create (addr, 0);
|
||||
HttpContext ctx = server.createContext ("/test", handler);
|
||||
ExecutorService executor = Executors.newCachedThreadPool();
|
||||
server.setExecutor (executor);
|
||||
server.start ();
|
||||
|
||||
URL url = new URL ("http://localhost:"+server.getAddress().getPort()+"/test/foo.html");
|
||||
HttpURLConnection urlc = (HttpURLConnection)url.openConnection ();
|
||||
try {
|
||||
InputStream is = urlc.getInputStream();
|
||||
int c = 0;
|
||||
while (is.read()!= -1) {
|
||||
c ++;
|
||||
}
|
||||
System.out.println ("OK");
|
||||
} catch (IOException e) {
|
||||
System.out.println ("exception");
|
||||
error = true;
|
||||
}
|
||||
server.stop(2);
|
||||
executor.shutdown();
|
||||
if (error) {
|
||||
throw new RuntimeException ("Test failed");
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean error = false;
|
||||
|
||||
/* this must be the same size as in ChunkedOutputStream.java
|
||||
*/
|
||||
final static int CHUNK_SIZE = 4096;
|
||||
|
||||
static class Handler implements HttpHandler {
|
||||
int invocation = 1;
|
||||
public void handle (HttpExchange t)
|
||||
throws IOException
|
||||
{
|
||||
InputStream is = t.getRequestBody();
|
||||
Headers map = t.getRequestHeaders();
|
||||
Headers rmap = t.getResponseHeaders();
|
||||
while (is.read () != -1) ;
|
||||
is.close();
|
||||
/* chunked response */
|
||||
t.sendResponseHeaders (200, 0);
|
||||
OutputStream os = t.getResponseBody();
|
||||
byte[] first = new byte [CHUNK_SIZE * 2];
|
||||
byte[] second = new byte [2];
|
||||
os.write (first);
|
||||
os.write ('x');
|
||||
os.write ('x');
|
||||
/* An index out of bounds exception will be thrown
|
||||
* below, which is caught by server, and connection
|
||||
* will be closed. resulting in IOException to client
|
||||
* - if bug present
|
||||
*/
|
||||
os.write ('x');
|
||||
os.write ('x');
|
||||
os.write ('x');
|
||||
t.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -24,7 +24,7 @@
|
||||
/**
|
||||
* @test
|
||||
* @summary Unit test for java.net.HttpCookie
|
||||
* @bug 6244040 6277796 6277801 6277808 6294071
|
||||
* @bug 6244040 6277796 6277801 6277808 6294071 6692802
|
||||
* @author Edward Wang
|
||||
*/
|
||||
|
||||
@ -178,6 +178,19 @@ public class TestHttpCookie {
|
||||
}
|
||||
TestHttpCookie port(String p) { return port(0, p); }
|
||||
|
||||
// check http only
|
||||
TestHttpCookie httpOnly(int index, boolean b) {
|
||||
HttpCookie cookie = cookies.get(index);
|
||||
if (cookie == null || b != cookie.isHttpOnly()) {
|
||||
raiseError("HttpOnly", String.valueOf(cookie.isHttpOnly()), String.valueOf(b));
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
TestHttpCookie httpOnly(boolean b) {
|
||||
return httpOnly(0, b);
|
||||
}
|
||||
|
||||
// check equality
|
||||
static void eq(HttpCookie ck1, HttpCookie ck2, boolean same) {
|
||||
testCount++;
|
||||
@ -362,6 +375,10 @@ public class TestHttpCookie {
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
// expected exception; no-op
|
||||
}
|
||||
|
||||
// CR 6692802: HttpOnly flag
|
||||
test("set-cookie: CUSTOMER=WILE_E_COYOTE;HttpOnly").httpOnly(true);
|
||||
test("set-cookie: CUSTOMER=WILE_E_COYOTE").httpOnly(false);
|
||||
}
|
||||
|
||||
static void header(String prompt) {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2002-2008 Sun Microsystems, Inc. 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
|
||||
@ -34,6 +34,7 @@ import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.security.cert.*;
|
||||
import java.security.cert.PKIXReason;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -69,6 +70,9 @@ public final class ValidateCertPath {
|
||||
validate(path, params);
|
||||
throw new Exception("Successfully validated invalid path.");
|
||||
} catch (CertPathValidatorException e) {
|
||||
if (e.getReason() != PKIXReason.INVALID_NAME) {
|
||||
throw new Exception("unexpected reason: " + e.getReason());
|
||||
}
|
||||
System.out.println("Path rejected as expected: " + e);
|
||||
}
|
||||
}
|
||||
@ -86,14 +90,14 @@ public final class ValidateCertPath {
|
||||
args = new String[] {"jane2jane.cer", "jane2steve.cer", "steve2tom.cer"};
|
||||
|
||||
TrustAnchor anchor = new TrustAnchor(getCertFromFile(args[0]), null);
|
||||
List list = new ArrayList();
|
||||
List<X509Certificate> list = new ArrayList<X509Certificate>();
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
list.add(0, getCertFromFile(args[i]));
|
||||
}
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X509");
|
||||
path = cf.generateCertPath(list);
|
||||
|
||||
Set anchors = Collections.singleton(anchor);
|
||||
Set<TrustAnchor> anchors = Collections.singleton(anchor);
|
||||
params = new PKIXParameters(anchors);
|
||||
params.setRevocationEnabled(false);
|
||||
}
|
||||
|
||||
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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.
|
||||
*
|
||||
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6465942
|
||||
* @summary unit test for CertPathValidatorException.Reason
|
||||
*/
|
||||
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.CertPathValidatorException.BasicReason;
|
||||
|
||||
public class ReasonTest {
|
||||
private static volatile boolean failed = false;
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
// check that getReason returns UNSPECIFIED if reason not specified
|
||||
CertPathValidatorException cpve = new CertPathValidatorException("abc");
|
||||
if (cpve.getReason() != BasicReason.UNSPECIFIED) {
|
||||
failed = true;
|
||||
System.err.println("FAILED: unexpected reason: " + cpve.getReason());
|
||||
}
|
||||
|
||||
// check that getReason returns specified reason
|
||||
cpve = new CertPathValidatorException
|
||||
("abc", null, null, -1, BasicReason.REVOKED);
|
||||
if (cpve.getReason() != BasicReason.REVOKED) {
|
||||
failed = true;
|
||||
System.err.println("FAILED: unexpected reason: " + cpve.getReason());
|
||||
}
|
||||
|
||||
// check that ctor throws NPE when reason is null
|
||||
try {
|
||||
cpve = new CertPathValidatorException("abc", null, null, -1, null);
|
||||
failed = true;
|
||||
System.err.println("ctor did not throw NPE for null reason");
|
||||
} catch (Exception e) {
|
||||
if (!(e instanceof NullPointerException)) {
|
||||
failed = true;
|
||||
System.err.println("FAILED: unexpected exception: " + e);
|
||||
}
|
||||
}
|
||||
if (failed) {
|
||||
throw new Exception("Some tests FAILED");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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.
|
||||
*
|
||||
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6465942
|
||||
* @summary Test deserialization of CertPathValidatorException
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
//import java.io.FileOutputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.CertPath;
|
||||
import java.security.cert.CertPathValidatorException;
|
||||
import java.security.cert.CertPathValidatorException.BasicReason;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* This class tests to see if CertPathValidatorException can be serialized and
|
||||
* deserialized properly.
|
||||
*/
|
||||
public class Serial {
|
||||
private static volatile boolean failed = false;
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
File f = new File(System.getProperty("test.src", "."), "cert_file");
|
||||
FileInputStream fis = new FileInputStream(f);
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||
Certificate c = cf.generateCertificate(fis);
|
||||
fis.close();
|
||||
CertPath cp = cf.generateCertPath(Collections.singletonList(c));
|
||||
|
||||
CertPathValidatorException cpve1 =
|
||||
new CertPathValidatorException
|
||||
("Test", new Exception("Expired"), cp, 0, BasicReason.EXPIRED);
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
// FileOutputStream fos = new FileOutputStream("jdk7.serial");
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
// ObjectOutputStream foos = new ObjectOutputStream(fos);
|
||||
oos.writeObject(cpve1);
|
||||
// foos.writeObject(cpve1);
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
ObjectInputStream ois = new ObjectInputStream(bais);
|
||||
CertPathValidatorException cpve2 =
|
||||
(CertPathValidatorException) ois.readObject();
|
||||
check(!cpve1.getMessage().equals(cpve2.getMessage()),
|
||||
"CertPathValidatorException messages not equal");
|
||||
check(!cpve1.getCause().getMessage().equals(cpve2.getCause().getMessage()),
|
||||
"CertPathValidatorException causes not equal");
|
||||
check(!cpve1.getCertPath().equals(cpve2.getCertPath()),
|
||||
"CertPathValidatorException certpaths not equal");
|
||||
check(cpve1.getIndex() != cpve2.getIndex(),
|
||||
"CertPathValidatorException indexes not equal");
|
||||
check(cpve1.getReason() != cpve2.getReason(),
|
||||
"CertPathValidatorException reasons not equal");
|
||||
oos.close();
|
||||
ois.close();
|
||||
|
||||
f = new File(System.getProperty("test.src", "."), "jdk6.serial");
|
||||
fis = new FileInputStream(f);
|
||||
ois = new ObjectInputStream(fis);
|
||||
cpve2 = (CertPathValidatorException) ois.readObject();
|
||||
check(!cpve1.getMessage().equals(cpve2.getMessage()),
|
||||
"CertPathValidatorException messages not equal");
|
||||
check(!cpve1.getCause().getMessage().equals(cpve2.getCause().getMessage()),
|
||||
"CertPathValidatorException causes not equal");
|
||||
check(!cpve1.getCertPath().equals(cpve2.getCertPath()),
|
||||
"CertPathValidatorException certpaths not equal");
|
||||
check(cpve1.getIndex() != cpve2.getIndex(),
|
||||
"CertPathValidatorException indexes not equal");
|
||||
// System.out.println(cpve2.getReason());
|
||||
check(cpve2.getReason() != BasicReason.UNSPECIFIED,
|
||||
"CertPathValidatorException reasons not equal");
|
||||
oos.close();
|
||||
ois.close();
|
||||
if (failed) {
|
||||
throw new Exception("Some tests FAILED");
|
||||
}
|
||||
}
|
||||
|
||||
private static void check(boolean expr, String message) {
|
||||
if (expr) {
|
||||
failed = true;
|
||||
System.err.println("FAILED: " + message);
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
jdk/test/java/security/cert/CertPathValidatorException/cert_file
Normal file
BIN
jdk/test/java/security/cert/CertPathValidatorException/cert_file
Normal file
Binary file not shown.
Binary file not shown.
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* Copyright 2001-2008 Sun Microsystems, Inc. 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
|
||||
@ -74,6 +74,10 @@ public class GetPolicyQualifiers {
|
||||
throw new Exception("Validation of CertPath containing critical " +
|
||||
"qualifiers should have failed when policyQualifiersRejected " +
|
||||
"flag is true");
|
||||
} catch (CertPathValidatorException cpve) {}
|
||||
} catch (CertPathValidatorException cpve) {
|
||||
if (cpve.getReason() != PKIXReason.INVALID_POLICY) {
|
||||
throw new Exception("unexpected reason: " + cpve.getReason());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
147
jdk/test/java/util/zip/TestEmptyZip.java
Normal file
147
jdk/test/java/util/zip/TestEmptyZip.java
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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.
|
||||
*
|
||||
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/* @test
|
||||
* @bug 6334003 6440786
|
||||
* @summary Test ability to write and read zip files that have no entries.
|
||||
* @author Dave Bristor
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
public class TestEmptyZip {
|
||||
public static void realMain(String[] args) throws Throwable {
|
||||
String zipName = "foo.zip";
|
||||
File f = new File(System.getProperty("test.scratch", "."), zipName);
|
||||
if (f.exists() && !f.delete()) {
|
||||
throw new Exception("failed to delete " + zipName);
|
||||
}
|
||||
|
||||
// Verify 0-length file cannot be read
|
||||
f.createNewFile();
|
||||
ZipFile zf = null;
|
||||
try {
|
||||
zf = new ZipFile(f);
|
||||
fail();
|
||||
} catch (Exception ex) {
|
||||
check(ex.getMessage().contains("zip file is empty"));
|
||||
} finally {
|
||||
if (zf != null) {
|
||||
zf.close();
|
||||
}
|
||||
}
|
||||
|
||||
ZipInputStream zis = null;
|
||||
try {
|
||||
zis = new ZipInputStream(new FileInputStream(f));
|
||||
ZipEntry ze = zis.getNextEntry();
|
||||
check(ze == null);
|
||||
} catch (Exception ex) {
|
||||
unexpected(ex);
|
||||
} finally {
|
||||
if (zis != null) {
|
||||
zis.close();
|
||||
}
|
||||
}
|
||||
|
||||
f.delete();
|
||||
|
||||
// Verify 0-entries file can be written
|
||||
write(f);
|
||||
|
||||
// Verify 0-entries file can be read
|
||||
readFile(f);
|
||||
readStream(f);
|
||||
|
||||
f.delete();
|
||||
}
|
||||
|
||||
static void write(File f) throws Exception {
|
||||
ZipOutputStream zos = null;
|
||||
try {
|
||||
zos = new ZipOutputStream(new FileOutputStream(f));
|
||||
zos.finish();
|
||||
zos.close();
|
||||
pass();
|
||||
} catch (Exception ex) {
|
||||
unexpected(ex);
|
||||
} finally {
|
||||
if (zos != null) {
|
||||
zos.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void readFile(File f) throws Exception {
|
||||
ZipFile zf = null;
|
||||
try {
|
||||
zf = new ZipFile(f);
|
||||
|
||||
Enumeration e = zf.entries();
|
||||
while (e.hasMoreElements()) {
|
||||
ZipEntry entry = (ZipEntry) e.nextElement();
|
||||
fail();
|
||||
}
|
||||
zf.close();
|
||||
pass();
|
||||
} catch (Exception ex) {
|
||||
unexpected(ex);
|
||||
} finally {
|
||||
if (zf != null) {
|
||||
zf.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void readStream(File f) throws Exception {
|
||||
ZipInputStream zis = null;
|
||||
try {
|
||||
zis = new ZipInputStream(new FileInputStream(f));
|
||||
ZipEntry ze = zis.getNextEntry();
|
||||
check(ze == null);
|
||||
byte[] buf = new byte[1024];
|
||||
check(zis.read(buf, 0, 1024) == -1);
|
||||
} finally {
|
||||
if (zis != null) {
|
||||
zis.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------- Infrastructure ---------------------------
|
||||
static volatile int passed = 0, failed = 0;
|
||||
static boolean pass() {passed++; return true;}
|
||||
static boolean fail() {failed++; Thread.dumpStack(); return false;}
|
||||
static boolean fail(String msg) {System.out.println(msg); return fail();}
|
||||
static void unexpected(Throwable t) {failed++; t.printStackTrace();}
|
||||
static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;}
|
||||
static boolean equal(Object x, Object y) {
|
||||
if (x == null ? y == null : x.equals(y)) return pass();
|
||||
else return fail(x + " not equal to " + y);}
|
||||
public static void main(String[] args) throws Throwable {
|
||||
try {realMain(args);} catch (Throwable t) {unexpected(t);}
|
||||
System.out.println("\nPassed = " + passed + " failed = " + failed);
|
||||
if (failed > 0) throw new AssertionError("Some tests failed");}
|
||||
}
|
||||
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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.
|
||||
*
|
||||
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6669137
|
||||
* @summary Test the constructors of InstanceNotFoundExceptionTest.
|
||||
* @author Daniel Fuchs
|
||||
* @compile InstanceNotFoundExceptionTest.java
|
||||
* @run main InstanceNotFoundExceptionTest
|
||||
*/
|
||||
|
||||
import javax.management.InstanceNotFoundException;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
public class InstanceNotFoundExceptionTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
final InstanceNotFoundException x =
|
||||
new InstanceNotFoundException();
|
||||
System.out.println("InstanceNotFoundException(): "+x.getMessage());
|
||||
|
||||
final String msg = "who is toto?";
|
||||
final InstanceNotFoundException x2 =
|
||||
new InstanceNotFoundException(msg);
|
||||
if (!msg.equals(x2.getMessage()))
|
||||
throw new Exception("Bad message: expected "+msg+
|
||||
", got "+x2.getMessage());
|
||||
System.out.println("InstanceNotFoundException(" +
|
||||
msg+"): "+x2.getMessage());
|
||||
|
||||
final InstanceNotFoundException x3 =
|
||||
new InstanceNotFoundException((String)null);
|
||||
if (x3.getMessage() != null)
|
||||
throw new Exception("Bad message: expected "+null+
|
||||
", got "+x3.getMessage());
|
||||
System.out.println("InstanceNotFoundException((String)null): "+
|
||||
x3.getMessage());
|
||||
|
||||
final ObjectName n = new ObjectName("who is toto?:type=msg");
|
||||
final InstanceNotFoundException x4 =
|
||||
new InstanceNotFoundException(n);
|
||||
if (!String.valueOf(n).equals(x4.getMessage()))
|
||||
throw new Exception("Bad message: expected "+n+
|
||||
", got "+x4.getMessage());
|
||||
System.out.println("InstanceNotFoundException(" +
|
||||
n+"): "+x4.getMessage());
|
||||
|
||||
final InstanceNotFoundException x5 =
|
||||
new InstanceNotFoundException((ObjectName)null);
|
||||
if (!String.valueOf((ObjectName)null).equals(x5.getMessage()))
|
||||
throw new Exception("Bad message: expected " +
|
||||
String.valueOf((ObjectName)null)+" got "+x5.getMessage());
|
||||
System.out.println("InstanceNotFoundException((ObjectName)null): "+
|
||||
x5.getMessage());
|
||||
}
|
||||
}
|
||||
@ -25,6 +25,7 @@
|
||||
* @test
|
||||
* @summary Test named MBeanServers.
|
||||
* @author Daniel Fuchs
|
||||
* @bug 6299231
|
||||
* @run clean NamedMBeanServerTest
|
||||
* @run build NamedMBeanServerTest
|
||||
* @run main NamedMBeanServerTest
|
||||
|
||||
175
jdk/test/javax/management/ObjectName/ValueOfTest.java
Normal file
175
jdk/test/javax/management/ObjectName/ValueOfTest.java
Normal file
@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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.
|
||||
*
|
||||
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6734813
|
||||
* @summary Test the ObjectName.valueOf methods
|
||||
* @author Eamonn McManus
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Hashtable;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
public class ValueOfTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
// Calls that should work
|
||||
testPositive("d:foo=bar,baz=buh");
|
||||
testPositive("foo", "bar", "baz");
|
||||
Hashtable<String, String> h = new Hashtable<String, String>();
|
||||
h.put("foo", "bar");
|
||||
h.put("baz", "buh");
|
||||
testPositive("domain", h);
|
||||
|
||||
// Calls that should not work
|
||||
testNegative("d");
|
||||
testNegative("d:");
|
||||
testNegative("d::foo=bar");
|
||||
testNegative("d:", "foo", "bar");
|
||||
testNegative("d", "foo=", "bar");
|
||||
testNegative("d:", h);
|
||||
testNegative("d", new Hashtable<String, String>());
|
||||
}
|
||||
|
||||
private static void testPositive(Object... args) throws Exception {
|
||||
Method valueOf = valueOfMethod(args);
|
||||
Method getInstance = getInstanceMethod(args);
|
||||
Constructor<?> constructor = constructor(args);
|
||||
|
||||
Object valueOfValue = valueOf.invoke(null, args);
|
||||
Object getInstanceValue = getInstance.invoke(null, args);
|
||||
Object constructorValue = constructor.newInstance(args);
|
||||
|
||||
String argString =
|
||||
Arrays.toString(args).replace('[', '(').replace(']', ')');
|
||||
|
||||
if (!valueOfValue.equals(getInstanceValue)) {
|
||||
throw new Exception(
|
||||
"valueOf" + argString + " differs from getInstance" +
|
||||
argString);
|
||||
}
|
||||
|
||||
if (!valueOfValue.equals(constructorValue)) {
|
||||
throw new Exception(
|
||||
"valueOf" + argString + " differs from new ObjectName " +
|
||||
argString);
|
||||
}
|
||||
|
||||
System.out.println("OK: valueOf" + argString);
|
||||
}
|
||||
|
||||
private static void testNegative(Object... args) throws Exception {
|
||||
Method valueOf = valueOfMethod(args);
|
||||
Method getInstance = getInstanceMethod(args);
|
||||
|
||||
String argString =
|
||||
Arrays.toString(args).replace('[', '(').replace(']', ')');
|
||||
|
||||
final Throwable valueOfException;
|
||||
try {
|
||||
valueOf.invoke(null, args);
|
||||
throw new Exception("valueOf" + argString + " did not fail but should");
|
||||
} catch (InvocationTargetException e) {
|
||||
valueOfException = e.getCause();
|
||||
}
|
||||
if (!(valueOfException instanceof IllegalArgumentException)) {
|
||||
throw new Exception(
|
||||
"valueOf" + argString + " threw " +
|
||||
valueOfException.getClass().getName() + " instead of " +
|
||||
"IllegalArgumentException", valueOfException);
|
||||
}
|
||||
|
||||
final Throwable valueOfCause = valueOfException.getCause();
|
||||
if (!(valueOfCause instanceof MalformedObjectNameException)) {
|
||||
throw new Exception(
|
||||
"valueOf" + argString + " threw exception with wrong " +
|
||||
"type of cause", valueOfCause);
|
||||
}
|
||||
|
||||
if (!valueOfException.getMessage().equals(valueOfCause.getMessage())) {
|
||||
// The IllegalArgumentException should have the same message as
|
||||
// the MalformedObjectNameException it wraps.
|
||||
// This isn't specified but is desirable.
|
||||
throw new Exception(
|
||||
"valueOf" + argString + ": message in wrapping " +
|
||||
"IllegalArgumentException (" + valueOfException.getMessage() +
|
||||
") differs from message in wrapped " +
|
||||
"MalformedObjectNameException (" + valueOfCause.getMessage() +
|
||||
")");
|
||||
}
|
||||
|
||||
final Throwable getInstanceException;
|
||||
try {
|
||||
getInstance.invoke(null, args);
|
||||
throw new Exception("getInstance" + argString + " did not fail but should");
|
||||
} catch (InvocationTargetException e) {
|
||||
getInstanceException = e.getCause();
|
||||
}
|
||||
if (!(getInstanceException instanceof MalformedObjectNameException)) {
|
||||
throw new Exception(
|
||||
"getInstance" + argString + " threw wrong exception",
|
||||
getInstanceException);
|
||||
}
|
||||
|
||||
if (!valueOfException.getMessage().equals(getInstanceException.getMessage())) {
|
||||
// Again this is not specified.
|
||||
throw new Exception(
|
||||
"Exception message from valueOf" + argString + " (" +
|
||||
valueOfException.getMessage() + ") differs from message " +
|
||||
"from getInstance" + argString + " (" +
|
||||
getInstanceException.getMessage() + ")");
|
||||
}
|
||||
|
||||
System.out.println("OK (correct exception): valueOf" + argString);
|
||||
}
|
||||
|
||||
private static Method valueOfMethod(Object[] args) throws Exception {
|
||||
return method("valueOf", args);
|
||||
}
|
||||
|
||||
private static Method getInstanceMethod(Object[] args) throws Exception {
|
||||
return method("getInstance", args);
|
||||
}
|
||||
|
||||
private static Method method(String name, Object[] args) throws Exception {
|
||||
Class<?>[] argTypes = argTypes(args);
|
||||
return ObjectName.class.getMethod(name, argTypes);
|
||||
}
|
||||
|
||||
private static Constructor<?> constructor(Object[] args) throws Exception {
|
||||
Class<?>[] argTypes = argTypes(args);
|
||||
return ObjectName.class.getConstructor(argTypes);
|
||||
}
|
||||
|
||||
private static Class<?>[] argTypes(Object[] args) {
|
||||
Class<?>[] argTypes = new Class<?>[args.length];
|
||||
for (int i = 0; i < args.length; i++)
|
||||
argTypes[i] = args[i].getClass();
|
||||
return argTypes;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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.
|
||||
*
|
||||
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6747411
|
||||
* @summary Check that EventClient instances don't leak threads.
|
||||
* @author Eamonn McManus
|
||||
*/
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.ThreadInfo;
|
||||
import java.lang.management.ThreadMXBean;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.MBeanServerDelegate;
|
||||
import javax.management.MBeanServerNotification;
|
||||
import javax.management.Notification;
|
||||
import javax.management.NotificationFilter;
|
||||
import javax.management.NotificationListener;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.event.EventClient;
|
||||
import javax.management.remote.JMXConnector;
|
||||
import javax.management.remote.JMXConnectorFactory;
|
||||
import javax.management.remote.JMXConnectorServer;
|
||||
import javax.management.remote.JMXConnectorServerFactory;
|
||||
import javax.management.remote.JMXServiceURL;
|
||||
|
||||
public class EventClientThreadTest {
|
||||
private static final int MAX_TIME_SECONDS = 20;
|
||||
|
||||
private static final BlockingQueue<Notification> queue =
|
||||
new ArrayBlockingQueue(100);
|
||||
|
||||
private static final NotificationListener queueListener =
|
||||
new NotificationListener() {
|
||||
public void handleNotification(Notification notification,
|
||||
Object handback) {
|
||||
queue.add(notification);
|
||||
}
|
||||
};
|
||||
|
||||
private static final NotificationFilter dummyFilter =
|
||||
new NotificationFilter() {
|
||||
public boolean isNotificationEnabled(Notification notification) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
long start = System.currentTimeMillis();
|
||||
long deadline = start + MAX_TIME_SECONDS * 1000;
|
||||
|
||||
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
|
||||
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi://");
|
||||
JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(
|
||||
url, null, mbs);
|
||||
cs.start();
|
||||
JMXServiceURL addr = cs.getAddress();
|
||||
JMXConnector cc = JMXConnectorFactory.connect(addr);
|
||||
MBeanServerConnection mbsc = cc.getMBeanServerConnection();
|
||||
|
||||
ThreadMXBean threads = ManagementFactory.getThreadMXBean();
|
||||
|
||||
System.out.println("Opening and closing some EventClients...");
|
||||
// If we create a connection, then create and destroy EventClients
|
||||
// over it, then close it, there should be no "JMX *" threads left.
|
||||
for (int i = 0; i < 5; i++)
|
||||
test(mbsc);
|
||||
|
||||
cc.close();
|
||||
|
||||
showTime("opening and closing initial EventClients", start);
|
||||
|
||||
Set<String> jmxThreads = threadsMatching("JMX .*");
|
||||
while (!jmxThreads.isEmpty() && System.currentTimeMillis() < deadline) {
|
||||
Set<String> jmxThreadsNow = threadsMatching("JMX .*");
|
||||
Set<String> gone = new TreeSet<String>(jmxThreads);
|
||||
gone.removeAll(jmxThreadsNow);
|
||||
for (String s : gone)
|
||||
showTime("expiry of \"" + s + "\"", start);
|
||||
jmxThreads = jmxThreadsNow;
|
||||
Thread.sleep(10);
|
||||
}
|
||||
if (System.currentTimeMillis() >= deadline) {
|
||||
showThreads(threads);
|
||||
throw new Exception("Timed out waiting for JMX threads to expire");
|
||||
}
|
||||
|
||||
showTime("waiting for JMX threads to expire", start);
|
||||
|
||||
System.out.println("TEST PASSED");
|
||||
}
|
||||
|
||||
static void showThreads(ThreadMXBean threads) throws Exception {
|
||||
long[] ids = threads.getAllThreadIds();
|
||||
for (long id : ids) {
|
||||
ThreadInfo ti = threads.getThreadInfo(id);
|
||||
String name = (ti == null) ? "(defunct)" : ti.getThreadName();
|
||||
System.out.printf("%4d %s\n", id, name);
|
||||
}
|
||||
}
|
||||
|
||||
static void showTime(String what, long start) {
|
||||
long elapsed = System.currentTimeMillis() - start;
|
||||
System.out.printf("Time after %s: %.3f s\n", what, elapsed / 1000.0);
|
||||
}
|
||||
|
||||
static Set<String> threadsMatching(String pattern) {
|
||||
Set<String> matching = new TreeSet<String>();
|
||||
ThreadMXBean threads = ManagementFactory.getThreadMXBean();
|
||||
long[] ids = threads.getAllThreadIds();
|
||||
for (long id : ids) {
|
||||
ThreadInfo ti = threads.getThreadInfo(id);
|
||||
String name = (ti == null) ? "(defunct)" : ti.getThreadName();
|
||||
if (name.matches(pattern))
|
||||
matching.add(name);
|
||||
}
|
||||
return matching;
|
||||
}
|
||||
|
||||
static void test(MBeanServerConnection mbsc) throws Exception {
|
||||
final ObjectName delegateName = MBeanServerDelegate.DELEGATE_NAME;
|
||||
final ObjectName testName = new ObjectName("test:type=Test");
|
||||
EventClient ec = new EventClient(mbsc);
|
||||
ec.addNotificationListener(delegateName, queueListener, null, null);
|
||||
mbsc.createMBean(MBeanServerDelegate.class.getName(), testName);
|
||||
mbsc.unregisterMBean(testName);
|
||||
final String[] expectedTypes = {
|
||||
MBeanServerNotification.REGISTRATION_NOTIFICATION,
|
||||
MBeanServerNotification.UNREGISTRATION_NOTIFICATION,
|
||||
};
|
||||
for (String s : expectedTypes) {
|
||||
Notification n = queue.poll(3, TimeUnit.SECONDS);
|
||||
if (n == null)
|
||||
throw new Exception("Timed out waiting for notif: " + s);
|
||||
if (!(n instanceof MBeanServerNotification))
|
||||
throw new Exception("Got notif of wrong class: " + n.getClass());
|
||||
if (!n.getType().equals(s)) {
|
||||
throw new Exception("Got notif of wrong type: " + n.getType() +
|
||||
" (expecting " + s + ")");
|
||||
}
|
||||
}
|
||||
ec.removeNotificationListener(delegateName, queueListener);
|
||||
|
||||
ec.addNotificationListener(delegateName, queueListener, dummyFilter, "foo");
|
||||
ec.removeNotificationListener(delegateName, queueListener, dummyFilter, "foo");
|
||||
|
||||
ec.close();
|
||||
}
|
||||
}
|
||||
@ -27,6 +27,7 @@
|
||||
* @summary Check that a lock is not held when a LeaseManager expires.
|
||||
* @author Eamonn McManus
|
||||
* @compile -XDignore.symbol.file=true LeaseManagerDeadlockTest.java
|
||||
* @run main LeaseManagerDeadlockTest
|
||||
*/
|
||||
|
||||
import com.sun.jmx.event.LeaseManager;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/*/*
|
||||
/*
|
||||
* Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
|
||||
125
jdk/test/javax/management/eventService/SubUnsubTest.java
Normal file
125
jdk/test/javax/management/eventService/SubUnsubTest.java
Normal file
@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright 2008 Sun Microsystems, Inc. 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.
|
||||
*
|
||||
* 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test SubUnsubTest
|
||||
* @bug 6736611
|
||||
* @summary Test not to remove other listeners when calling unsubscribe
|
||||
* @author Shanliang JIANG
|
||||
* @run clean SubUnsubTest
|
||||
* @run build SubUnsubTest
|
||||
* @run main SubUnsubTest
|
||||
*/
|
||||
|
||||
import java.lang.management.ManagementFactory;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.Notification;
|
||||
import javax.management.NotificationFilter;
|
||||
import javax.management.NotificationBroadcasterSupport;
|
||||
import javax.management.NotificationListener;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.event.EventSubscriber;
|
||||
import javax.management.event.EventClient;
|
||||
public class SubUnsubTest {
|
||||
private static class CountListener implements NotificationListener {
|
||||
volatile int count;
|
||||
|
||||
public void handleNotification(Notification n, Object h) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
public static interface SenderMBean {}
|
||||
|
||||
public static class Sender extends NotificationBroadcasterSupport
|
||||
implements SenderMBean {
|
||||
void send() {
|
||||
Notification n = new Notification("type", this, 1L);
|
||||
sendNotification(n);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Testing EventSubscriber-unsubscribe method.");
|
||||
|
||||
MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
|
||||
ObjectName name1 = new ObjectName("d:type=Sender,id=1");
|
||||
ObjectName name2 = new ObjectName("d:type=Sender,id=2");
|
||||
ObjectName pattern = new ObjectName("d:type=Sender,*");
|
||||
Sender sender1 = new Sender();
|
||||
Sender sender2 = new Sender();
|
||||
mbs.registerMBean(sender1, name1);
|
||||
mbs.registerMBean(sender2, name2);
|
||||
|
||||
EventSubscriber sub = EventSubscriber.getEventSubscriber(mbs);
|
||||
|
||||
System.out.println("Single subscribe covering both MBeans");
|
||||
CountListener listener = new CountListener();
|
||||
|
||||
System.out.println("Subscribing and adding listeners ...");
|
||||
sub.subscribe(pattern, listener, null, null);
|
||||
sub.subscribe(name2, listener, null, null);
|
||||
mbs.addNotificationListener(name2, listener, null, null);
|
||||
|
||||
sender1.send();
|
||||
sender2.send();
|
||||
if (listener.count != 4) {
|
||||
throw new RuntimeException("Do not receive all notifications: "+
|
||||
"Expect 4, got "+listener.count);
|
||||
}
|
||||
|
||||
System.out.println("Unsubscribe the listener with the pattern.");
|
||||
sub.unsubscribe(pattern, listener);
|
||||
listener.count = 0;
|
||||
sender1.send();
|
||||
sender2.send();
|
||||
if (listener.count != 2) {
|
||||
throw new RuntimeException("The method unsubscribe removes wrong listeners.");
|
||||
}
|
||||
|
||||
System.out.println("Unsubscribe the listener with the ObjectName.");
|
||||
sub.unsubscribe(name2, listener);
|
||||
listener.count = 0;
|
||||
sender1.send();
|
||||
sender2.send();
|
||||
if (listener.count != 1) {
|
||||
throw new RuntimeException("The method unsubscribe removes wrong listeners.");
|
||||
}
|
||||
|
||||
System.out.println("Subscribe twice to same MBean with same listener " +
|
||||
"but different handback.");
|
||||
sub.subscribe(name1, listener, null, new Object());
|
||||
sub.subscribe(name1, listener, null, new Object());
|
||||
listener.count = 0;
|
||||
|
||||
sub.unsubscribe(name1, listener);
|
||||
sender1.send();
|
||||
if (listener.count > 0) {
|
||||
throw new RuntimeException("EventSubscriber: the method unsubscribe" +
|
||||
" does not remove a listener which was subscribed 2 times.");
|
||||
}
|
||||
|
||||
System.out.println("Bye bye!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -23,6 +23,7 @@
|
||||
/*
|
||||
*
|
||||
* @test DomainCreationTest.java
|
||||
* @bug 5072476
|
||||
* @summary Test the creation and registration of JMXDomain instances.
|
||||
* @author Daniel Fuchs
|
||||
* @run clean DomainCreationTest Wombat WombatMBean
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
* @summary Check -Djmx.remote.use.event.service=true and
|
||||
* -Djmx.remote.delegate.event.service
|
||||
* @author Daniel Fuchs
|
||||
* @bug 5072476 5108776
|
||||
* @run clean EventWithNamespaceTest EventWithNamespaceControlTest
|
||||
* Wombat WombatMBean JMXRemoteTargetNamespace
|
||||
* NamespaceController NamespaceControllerMBean
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
/*
|
||||
*
|
||||
* @test EventWithNamespaceTest.java 1.8
|
||||
* @bug 6539857
|
||||
* @bug 6539857 5072476 5108776
|
||||
* @summary General Namespace & Notifications test.
|
||||
* @author Daniel Fuchs
|
||||
* @run clean EventWithNamespaceTest Wombat WombatMBean
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
* @summary Test that you can export a single namespace through a
|
||||
* JMXConnectorServer.
|
||||
* @author Daniel Fuchs
|
||||
* @bug 5072476
|
||||
* @run clean ExportNamespaceTest Wombat WombatMBean
|
||||
* @run build ExportNamespaceTest Wombat WombatMBean
|
||||
* @run main ExportNamespaceTest
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
/*
|
||||
*
|
||||
* @test JMXDomainTest.java
|
||||
* @bug 5072476
|
||||
* @summary Basic test for JMXDomain.
|
||||
* @author Daniel Fuchs
|
||||
* @run clean JMXDomainTest Wombat WombatMBean
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user