# HG changeset patch # User tbell # Date 1222148251 25200 # Node ID b23505b07d80ce1b8bc51d76bd1a72bf60467004 # Parent d718a441936196b93d8bc9f084933af9a4c2a350# Parent f58e00230694699bded139e523c9f7ebe598f00f Merge diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java --- a/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/event/LeaseManager.java Mon Sep 22 22:37:31 2008 -0700 @@ -27,7 +27,6 @@ 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 @@ scheduled = null; } callback.run(); + executor.shutdown(); } } @@ -131,6 +131,13 @@ 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 @@ 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"); diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/event/RepeatedSingletonJob.java --- a/jdk/src/share/classes/com/sun/jmx/event/RepeatedSingletonJob.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/event/RepeatedSingletonJob.java Mon Sep 22 22:37:31 2008 -0700 @@ -95,7 +95,9 @@ 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); diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java --- a/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java Mon Sep 22 22:37:31 2008 -0700 @@ -613,8 +613,7 @@ List result = new ArrayList(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 @@ 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 @@ private void addJMXNamespace(JMXNamespace namespace, final ObjectName logicalName, final Queue postQueue) { - dispatcher.addNamespace(logicalName, namespace, postQueue); + dispatcher.addInterceptorFor(logicalName, namespace, postQueue); } /** @@ -2035,7 +2034,7 @@ private void removeJMXNamespace(JMXNamespace namespace, final ObjectName logicalName, final Queue postQueue) { - dispatcher.removeNamespace(logicalName, namespace, postQueue); + dispatcher.removeInterceptorFor(logicalName, namespace, postQueue); } /** diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/interceptor/DispatchInterceptor.java --- a/jdk/src/share/classes/com/sun/jmx/interceptor/DispatchInterceptor.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DispatchInterceptor.java Mon Sep 22 22:37:31 2008 -0700 @@ -194,7 +194,7 @@ // 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 @@ // 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 postRegisterQueue) { final String key = getHandlerKey(name); validateHandlerNameFor(key,name); @@ -298,7 +298,7 @@ // 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 postDeregisterQueue) { final String key = getHandlerKey(name); final T ns; @@ -330,7 +330,7 @@ } // 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 @@ } // 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 @@ } // 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 @@ } // 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 @@ } // 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 queryMBeans(ObjectName name, QueryExp query) { - final QueryInterceptor mbs = + public final Set 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 queryNames(ObjectName name, QueryExp query) { - final QueryInterceptor mbs = + public final Set 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 @@ } // 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 @@ } // 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 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 @@ // 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); } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/interceptor/DomainDispatchInterceptor.java --- a/jdk/src/share/classes/com/sun/jmx/interceptor/DomainDispatchInterceptor.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DomainDispatchInterceptor.java Mon Sep 22 22:37:31 2008 -0700 @@ -75,7 +75,7 @@ private final DomainDispatchInterceptor parent; AggregatingQueryInterceptor(DomainDispatchInterceptor dispatcher) { - super(dispatcher.localNamespace); + super(dispatcher.nextInterceptor); parent = dispatcher; } @@ -91,9 +91,8 @@ // Add all matching MBeans from local namespace. final Set 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 @@ } } - private final DefaultMBeanServerInterceptor localNamespace; + private final DefaultMBeanServerInterceptor nextInterceptor; private final String mbeanServerName; private final MBeanServerDelegate delegate; @@ -165,7 +164,7 @@ 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 @@ @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 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 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); } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java Mon Sep 22 22:37:31 2008 -0700 @@ -1172,10 +1172,10 @@ final Class 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 annotatedConstrList = newList(); + List> annotatedConstrList = newList(); for (Constructor constr : constrs) { if (Modifier.isPublic(constr.getModifiers()) && constr.getAnnotation(propertyNamesClass) != null) @@ -1206,7 +1206,7 @@ // Also remember the set of properties in that constructor // so we can test unambiguity. Set getterIndexSets = newSet(); - for (Constructor constr : annotatedConstrList) { + for (Constructor constr : annotatedConstrList) { String[] propertyNames = constr.getAnnotation(propertyNamesClass).value(); @@ -1363,10 +1363,10 @@ } 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; diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java Mon Sep 22 22:37:31 2008 -0700 @@ -623,7 +623,7 @@ } 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"; diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java Mon Sep 22 22:37:31 2008 -0700 @@ -396,7 +396,7 @@ // 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) diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java --- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java Mon Sep 22 22:37:31 2008 -0700 @@ -57,7 +57,8 @@ 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 Map newMap() { @@ -109,14 +110,6 @@ return new ArrayList(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 @@ * 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 @@ "\"-\" 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 @@ } // 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()); } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java --- a/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/namespace/DomainInterceptor.java Mon Sep 22 22:37:31 2008 -0700 @@ -85,7 +85,7 @@ 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 @@ 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 @@ super(handler); this.domainName = domainName; this.serverName = serverName; + ALL = ObjectName.valueOf(domainName+":*"); } @Override @@ -118,27 +119,27 @@ ", 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 @@ if (l == null) return; mbsListener = null; } - getNamespace().removeMBeanServerNotificationListener(l); + getHandlerInterceptorMBean().removeMBeanServerNotificationListener(l); } - public void addPostRegisterTask(Queue queue, + public final void addPostRegisterTask(Queue queue, final MBeanServerDelegate delegate) { if (queue == null) throw new IllegalArgumentException("task queue must not be null"); @@ -158,14 +159,15 @@ 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 queue, + public final void addPostDeregisterTask(Queue queue, final MBeanServerDelegate delegate) { if (queue == null) throw new IllegalArgumentException("task queue must not be null"); @@ -174,17 +176,18 @@ 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 @@ return targetName; } + // No name conversion for JMXDomains... @Override protected ObjectName toTarget(ObjectName sourceName) { return sourceName; @@ -255,16 +259,16 @@ 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 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 @@ 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 empty = Collections.emptySet(); - return empty; } @Override @@ -306,7 +307,7 @@ // in the domain. @Override public Integer getMBeanCount() { - return getNamespace().getMBeanCount(); + return getHandlerInterceptorMBean().getMBeanCount(); } private boolean checkOn() { @@ -320,8 +321,8 @@ @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 @@ 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 @@ 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 @@ int count=0; for (int i=0;i * This API is a Sun internal API and is subject to changes without notice. *

@@ -90,6 +90,12 @@ 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 @@ 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 @@ 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 @@ } } - // 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 @@ } } - // 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 @@ } } - // 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 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 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 @@ 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 @@ } } - // 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 @@ } } - // 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 @@ } } - // 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 @@ } } - // 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 @@ } } - // From MBeanServer: catch & handles IOException + // From MBeanServerConnection: catch & handles IOException @Override public boolean isRegistered(ObjectName name) { try { @@ -372,41 +405,44 @@ } } - // 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 @@ 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 @@ } } - // 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 @@ 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 @@ } } - // 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 @@ "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 //}. + * @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 //}. + * @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 //}. + * @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 //}. + * @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. + *

+ * 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); + } + + + } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/namespace/JMXNamespaceUtils.java --- a/jdk/src/share/classes/com/sun/jmx/namespace/JMXNamespaceUtils.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/namespace/JMXNamespaceUtils.java Mon Sep 22 22:37:31 2008 -0700 @@ -29,7 +29,6 @@ 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.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 @@ return new WeakHashMap(); } - /** 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 Map filterMap(Map map, K... keys) { - final Map filtered; - filtered=new HashMap(map); - for (K key : keys) { - filtered.remove(key); - } - return unmodifiableMap(filtered); - } - // returns un unmodifiable view of a map. public static Map unmodifiableMap(Map aMap) { if (aMap == null || aMap.isEmpty()) diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java --- a/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/namespace/NamespaceInterceptor.java Mon Sep 22 22:37:31 2008 -0700 @@ -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 @@ */ public class NamespaceInterceptor extends HandlerInterceptor { - /** - * 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; @@ -69,21 +56,6 @@ 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 */ public NamespaceInterceptor( @@ -104,164 +76,6 @@ ", 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 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 @@ * (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 @@ return super.source(); } - /** - * Calls {@link MBeanServerConnection#queryNames queryNames} - * on the underlying - * {@link #getMBeanServerConnection MBeanServerConnection}. - **/ - @Override - public final Set 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 { diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/namespace/RoutingConnectionProxy.java --- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingConnectionProxy.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingConnectionProxy.java Mon Sep 22 22:37:31 2008 -0700 @@ -45,6 +45,9 @@ *

* @since 1.7 */ +// See class hierarchy and detailled explanations in RoutingProxy in this +// package. +// public class RoutingConnectionProxy extends RoutingProxy { @@ -93,40 +96,28 @@ targetNs+"\", "+forwardsContext+")"; } + static final RoutingProxyFactory + + FACTORY = new RoutingProxyFactory + () { + + 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); } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java --- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingMBeanServerConnection.java Mon Sep 22 22:37:31 2008 -0700 @@ -83,18 +83,32 @@ } /** - * 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 @@ 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 //}. - * @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 //}. - * @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 //}. - * @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 @@ IOException { final ObjectName sourceName = toSourceOrRuntime(name); try { - check(name, operationName, "invoke"); final Object result = source().invoke(sourceName,operationName,params, signature); @@ -249,7 +189,6 @@ IOException { final ObjectName sourceName = toSourceOrRuntime(name); try { - check(name, null, "unregisterMBean"); source().unregisterMBean(sourceName); } catch (RuntimeException ex) { throw makeCompliantRuntimeException(ex); @@ -262,7 +201,6 @@ 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 @@ 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 @@ 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 @@ // 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 //}. - * @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 @@ 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 @@ 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 @@ if (name == null) name=ObjectName.WILDCARD; final ObjectName sourceName = toSourceOrRuntime(name); try { - checkPattern(name,null,"queryNames"); final Set tmp = source().queryNames(sourceName,query); final Set out = processOutputNames(tmp); //System.err.println("queryNames: out: "+out); @@ -540,7 +442,6 @@ 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 @@ 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 @@ 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 @@ IOException { final ObjectName sourceName = toSourceOrRuntime(name); try { - check(name,null,"removeNotificationListener"); source().removeNotificationListener(sourceName,listener,filter, handback); } catch (RuntimeException ex) { @@ -600,7 +498,6 @@ IOException { final ObjectName sourceName = toSourceOrRuntime(name); try { - check(name,null,"removeNotificationListener"); source().removeNotificationListener(sourceName,listener, filter,handback); } catch (RuntimeException ex) { @@ -616,7 +513,6 @@ // 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 @@ // 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. - *

- * 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 @@ } } + /** + * 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; + } + } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/namespace/RoutingProxy.java --- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingProxy.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingProxy.java Mon Sep 22 22:37:31 2008 -0700 @@ -30,31 +30,110 @@ 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: - *

{@link RoutingConnectionProxy}: to cd in an MBeanServerConnection.

- *

{@link RoutingServerProxy}: to cd in an MBeanServer.

+ *

{@link RoutingConnectionProxy}: to narrow down into an + * MBeanServerConnection.

+ *

{@link RoutingServerProxy}: to narrow down into an MBeanServer.

+ * + *

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).

+ * + *

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.

+ * *

* This API is a Sun internal API and is subject to changes without notice. *

* @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 'to add' +// +// For a RoutingProxy used in a ClientContext operation, we have: +// targetNs= // 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 extends RoutingMBeanServerConnection { @@ -179,17 +258,11 @@ 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 @@ (" mounted on targetNs="+targetNs)); } + // Creates an instance of a subclass 'R' of RoutingProxy + // RoutingServerProxy and RoutingConnectionProxy have their own factory + // instance. + static interface RoutingProxyFactory> { + 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 > + R cd(Class routingProxyClass, + RoutingProxyFactory 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); + } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/namespace/RoutingServerProxy.java --- a/jdk/src/share/classes/com/sun/jmx/namespace/RoutingServerProxy.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/namespace/RoutingServerProxy.java Mon Sep 22 22:37:31 2008 -0700 @@ -69,6 +69,9 @@ * * @since 1.7 */ +// See class hierarchy and detailled explanations in RoutingProxy in this +// package. +// public class RoutingServerProxy extends RoutingProxy implements MBeanServer { @@ -564,39 +567,24 @@ } } + static final RoutingProxyFactory + FACTORY = new RoutingProxyFactory() { + + 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); } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java --- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientCommunicatorAdmin.java Mon Sep 22 22:37:31 2008 -0700 @@ -32,13 +32,15 @@ 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 diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java --- a/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java Mon Sep 22 22:37:31 2008 -0700 @@ -290,28 +290,6 @@ 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 @@ 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 @@ 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 @@ 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); } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/java/lang/AbstractStringBuilder.java --- a/jdk/src/share/classes/java/lang/AbstractStringBuilder.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/java/lang/AbstractStringBuilder.java Mon Sep 22 22:37:31 2008 -0700 @@ -42,7 +42,7 @@ /** * The value is used for character storage. */ - char value[]; + char[] value; /** * The count is the number of characters used. @@ -333,8 +333,7 @@ * dst.length * */ - 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 @@ } /** - * Appends the string representation of the Object - * argument. + * Appends the string representation of the {@code Object} argument. *

- * The argument is converted to a string as if by the method - * String.valueOf, 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 Object. + * @param obj an {@code Object}. * @return a reference to this object. */ public AbstractStringBuilder append(Object obj) { @@ -383,17 +382,17 @@ /** * Appends the specified string to this character sequence. *

- * The characters of the String 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 str is null, then the four - * characters "null" are appended. + * argument. If {@code str} is {@code null}, then the four + * characters {@code "null"} are appended. *

* Let n be the length of this character sequence just prior to - * execution of the append method. Then the character at + * execution of the {@code append} method. Then the character at * index k in the new character sequence is equal to the character * at index k in the old character sequence, if k is less * than n; otherwise, it is equal to the character at index - * k-n in the argument str. + * k-n in the argument {@code str}. * * @param str a string. * @return a reference to this object. @@ -435,33 +434,33 @@ } /** - * Appends a subsequence of the specified CharSequence to this + * Appends a subsequence of the specified {@code CharSequence} to this * sequence. *

- * Characters of the argument s, starting at - * index start, are appended, in order, to the contents of - * this sequence up to the (exclusive) index end. The length - * of this sequence is increased by the value of end - start. + * 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}. *

* Let n be the length of this character sequence just prior to - * execution of the append method. Then the character at + * execution of the {@code append} method. Then the character at * index k in this character sequence becomes equal to the * character at index k in this sequence, if k is less than * n; otherwise, it is equal to the character at index - * k+start-n in the argument s. + * k+start-n in the argument {@code s}. *

- * If s is null, 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 "null". + * 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 - * start or end are negative, or - * start is greater than end or - * end is greater than s.length() + * {@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 @@ } /** - * Appends the string representation of the char array + * Appends the string representation of the {@code char} array * argument to this sequence. *

* 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. *

- * 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 @@ /** * Appends the string representation of a subarray of the - * char array argument to this sequence. + * {@code char} array argument to this sequence. *

- * Characters of the char array str, starting at - * index offset, 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 len. + * by the value of {@code len}. *

- * 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 char to append. - * @param len the number of chars 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 @@ } /** - * Appends the string representation of the boolean + * Appends the string representation of the {@code boolean} * argument to the sequence. *

- * The argument is converted to a string as if by the method - * String.valueOf, 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 boolean. + * @param b a {@code boolean}. * @return a reference to this object. */ public AbstractStringBuilder append(boolean b) { @@ -569,18 +572,18 @@ } /** - * Appends the string representation of the char + * Appends the string representation of the {@code char} * argument to this sequence. *

* The argument is appended to the contents of this sequence. - * The length of this sequence increases by 1. + * The length of this sequence increases by {@code 1}. *

- * 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 char. + * @param c a {@code char}. * @return a reference to this object. */ public AbstractStringBuilder append(char c) { @@ -592,14 +595,15 @@ } /** - * Appends the string representation of the int + * Appends the string representation of the {@code int} * argument to this sequence. *

- * The argument is converted to a string as if by the method - * String.valueOf, 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 int. + * @param i an {@code int}. * @return a reference to this object. */ public AbstractStringBuilder append(int i) { @@ -618,14 +622,15 @@ } /** - * Appends the string representation of the long + * Appends the string representation of the {@code long} * argument to this sequence. *

- * The argument is converted to a string as if by the method - * String.valueOf, 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 long. + * @param l a {@code long}. * @return a reference to this object. */ public AbstractStringBuilder append(long l) { @@ -644,14 +649,15 @@ } /** - * Appends the string representation of the float + * Appends the string representation of the {@code float} * argument to this sequence. *

- * The argument is converted to a string as if by the method - * String.valueOf, 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 float. + * @param f a {@code float}. * @return a reference to this object. */ public AbstractStringBuilder append(float f) { @@ -660,14 +666,15 @@ } /** - * Appends the string representation of the double + * Appends the string representation of the {@code double} * argument to this sequence. *

- * The argument is converted to a string as if by the method - * String.valueOf, 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 double. + * @param d a {@code double}. * @return a reference to this object. */ public AbstractStringBuilder append(double d) { @@ -677,17 +684,17 @@ /** * Removes the characters in a substring of this sequence. - * The substring begins at the specified start and extends to - * the character at index end - 1 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 - * start is equal to end, 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 start - * is negative, greater than length(), or - * greater than end. + * @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 @@ } /** - * Appends the string representation of the codePoint + * Appends the string representation of the {@code codePoint} * argument to this sequence. * *

The argument is appended to the contents of this sequence. @@ -713,15 +720,15 @@ * {@link Character#charCount(int) Character.charCount(codePoint)}. * *

The overall effect is exactly as if the argument were - * converted to a char 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 - * codePoint 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 @@ } /** - * Inserts the string representation of a subarray of the str + * Inserts the string representation of a subarray of the {@code str} * array argument into this sequence. The subarray begins at the - * specified offset and extends len chars. + * 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 index. The length of this - * sequence increases by len chars. + * 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 char array. - * @param offset the index of the first char 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 chars in the subarray to + * @param len the number of {@code char}s in the subarray to * be inserted. * @return This object - * @throws StringIndexOutOfBoundsException if index - * is negative or greater than length(), or - * offset or len are negative, or - * (offset+len) is greater than - * str.length. + * @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 @@ } /** - * Inserts the string representation of the Object + * Inserts the string representation of the {@code Object} * argument into this character sequence. *

- * The second argument is converted to a string as if by the method - * String.valueOf, 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. *

- * The offset argument must be greater than or equal to - * 0, 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 Object. + * @param obj an {@code Object}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ @@ -942,28 +950,28 @@ /** * Inserts the string into this character sequence. *

- * The characters of the String 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 - * str is null, then the four characters - * "null" are inserted into this sequence. + * {@code str} is {@code null}, then the four characters + * {@code "null"} are inserted into this sequence. *

* The character at index k in the new character sequence is * equal to: *

    *
  • the character at index k in the old character sequence, if - * k is less than offset - *
  • the character at index k-offset in the - * argument str, if k is not less than - * offset but is less than offset+str.length() - *
  • the character at index k-str.length() in the + * k is less than {@code offset} + *
  • the character at index k{@code -offset} in the + * argument {@code str}, if k is not less than + * {@code offset} but is less than {@code offset+str.length()} + *
  • the character at index k{@code -str.length()} in the * old character sequence, if k is not less than - * offset+str.length() + * {@code offset+str.length()} *

- * The offset argument must be greater than or equal to - * 0, 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 @@ } /** - * Inserts the string representation of the char array + * Inserts the string representation of the {@code char} array * argument into this sequence. *

* The characters of the array argument are inserted into the * contents of this sequence at the position indicated by - * offset. The length of this sequence increases by + * {@code offset}. The length of this sequence increases by * the length of the argument. *

- * 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 - * offset. + * 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. + *

+ * 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 @@ } /** - * Inserts the specified CharSequence into this sequence. + * Inserts the specified {@code CharSequence} into this sequence. *

- * The characters of the CharSequence 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. *

* 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. * - *

If s is null, then the four characters - * "null" are inserted into this sequence. + *

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 @@ } /** - * Inserts a subsequence of the specified CharSequence into + * Inserts a subsequence of the specified {@code CharSequence} into * this sequence. *

- * The subsequence of the argument s specified by - * start and end 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 end - start. + * sequence is increased by {@code end - start}. *

* The character at index k in this sequence becomes equal to: *

    *
  • the character at index k in this sequence, if - * k is less than dstOffset - *
  • the character at index k+start-dstOffset in - * the argument s, if k is greater than or equal to - * dstOffset but is less than dstOffset+end-start - *
  • the character at index k-(end-start) in this + * k is less than {@code dstOffset} + *
  • the character at index k{@code +start-dstOffset} in + * the argument {@code s}, if k is greater than or equal to + * {@code dstOffset} but is less than {@code dstOffset+end-start} + *
  • the character at index k{@code -(end-start)} in this * sequence, if k is greater than or equal to - * dstOffset+end-start + * {@code dstOffset+end-start} *

- * The dstOffset argument must be greater than or equal to - * 0, 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. *

The start argument must be nonnegative, and not greater than - * end. + * {@code end}. *

The end argument must be greater than or equal to - * start, and less than or equal to the length of s. + * {@code start}, and less than or equal to the length of s. * - *

If s is null, then this method inserts + *

If {@code s} is {@code null}, then this method inserts * characters as if the s parameter was a sequence containing the four - * characters "null". + * 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 dstOffset - * is negative or greater than this.length(), or - * start or end are negative, or - * start is greater than end or - * end is greater than s.length() + * @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 @@ } /** - * Inserts the string representation of the boolean + * Inserts the string representation of the {@code boolean} * argument into this sequence. *

- * The second argument is converted to a string as if by the method - * String.valueOf, 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. *

- * The offset argument must be greater than or equal to - * 0, 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 boolean. + * @param b a {@code boolean}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ @@ -1137,25 +1151,21 @@ } /** - * Inserts the string representation of the char + * Inserts the string representation of the {@code char} * argument into this sequence. *

- * The second argument is inserted into the contents of this sequence - * at the position indicated by offset. 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. *

- * 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 - * offset. - *

- * The offset argument must be greater than or equal to - * 0, 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 char. + * @param c a {@code char}. * @return a reference to this object. * @throws IndexOutOfBoundsException if the offset is invalid. */ @@ -1170,20 +1180,21 @@ } /** - * Inserts the string representation of the second int + * Inserts the string representation of the second {@code int} * argument into this sequence. *

- * The second argument is converted to a string as if by the method - * String.valueOf, 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. *

- * The offset argument must be greater than or equal to - * 0, 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 int. + * @param i an {@code int}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ @@ -1192,20 +1203,21 @@ } /** - * Inserts the string representation of the long + * Inserts the string representation of the {@code long} * argument into this sequence. *

- * The second argument is converted to a string as if by the method - * String.valueOf, and the characters of that - * string are then inserted into this sequence at the position - * indicated by offset. + * 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. *

- * The offset argument must be greater than or equal to - * 0, 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 long. + * @param l a {@code long}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ @@ -1214,20 +1226,21 @@ } /** - * Inserts the string representation of the float + * Inserts the string representation of the {@code float} * argument into this sequence. *

- * The second argument is converted to a string as if by the method - * String.valueOf, 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. *

- * The offset argument must be greater than or equal to - * 0, 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 float. + * @param f a {@code float}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ @@ -1236,20 +1249,21 @@ } /** - * Inserts the string representation of the double + * Inserts the string representation of the {@code double} * argument into this sequence. *

- * The second argument is converted to a string as if by the method - * String.valueOf, 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. *

- * The offset argument must be greater than or equal to - * 0, 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 double. + * @param d a {@code double}. * @return a reference to this object. * @throws StringIndexOutOfBoundsException if the offset is invalid. */ diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/java/lang/StringBuffer.java --- a/jdk/src/share/classes/java/lang/StringBuffer.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/java/lang/StringBuffer.java Mon Sep 22 22:37:31 2008 -0700 @@ -212,7 +212,7 @@ * @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 @@ 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 @@ 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 @@ 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 @@ 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 @@ * @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 @@ /** * @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 @@ /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see #length() */ public synchronized StringBuffer insert(int offset, String str) { super.insert(offset, str); @@ -467,7 +442,7 @@ /** * @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 @@ /** * @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 @@ /** * @throws IndexOutOfBoundsException {@inheritDoc} - * @see #length() */ public synchronized StringBuffer insert(int offset, char c) { super.insert(offset, c); @@ -517,9 +488,6 @@ /** * @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 @@ /** * @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 @@ /** * @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 @@ /** * @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)); diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/java/lang/StringBuilder.java --- a/jdk/src/share/classes/java/lang/StringBuilder.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/java/lang/StringBuilder.java Mon Sep 22 22:37:31 2008 -0700 @@ -124,10 +124,6 @@ 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 @@ } /** - * @throws IndexOutOfBoundsException {@inheritDoc} */ public StringBuilder append(CharSequence s) { if (s == null) @@ -197,20 +192,19 @@ 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 @@ 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 @@ /** * @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 @@ /** * @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 @@ /** * @throws StringIndexOutOfBoundsException {@inheritDoc} - * @see #length() */ public StringBuilder insert(int offset, String str) { super.insert(offset, str); @@ -321,7 +295,7 @@ /** * @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 @@ /** * @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 @@ /** * @throws IndexOutOfBoundsException {@inheritDoc} - * @see #length() */ public StringBuilder insert(int offset, char c) { super.insert(offset, c); @@ -369,9 +339,6 @@ /** * @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 @@ /** * @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 @@ /** * @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 @@ /** * @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)); diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/java/lang/management/PlatformComponent.java --- a/jdk/src/share/classes/java/lang/management/PlatformComponent.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/java/lang/management/PlatformComponent.java Mon Sep 22 22:37:31 2008 -0700 @@ -388,7 +388,7 @@ // 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 set = mbs.queryNames(on, null); for (PlatformComponent pc : subComponents) { set.addAll(pc.getObjectNames(mbs)); diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/java/net/HttpCookie.java --- a/jdk/src/share/classes/java/net/HttpCookie.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/java/net/HttpCookie.java Mon Sep 22 22:37:31 2008 -0700 @@ -75,6 +75,7 @@ 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 @@ version = v; } + /** + * Returns {@code true} if this cookie contains the HttpOnly + * 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 @@ || name.equalsIgnoreCase("Port") // rfc2965 only || name.equalsIgnoreCase("Secure") || name.equalsIgnoreCase("Version") + || name.equalsIgnoreCase("HttpOnly") || name.charAt(0) == '$') { return true; @@ -996,6 +1024,11 @@ 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 { diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java --- a/jdk/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/java/nio/ByteBufferAs-X-Buffer.java Mon Sep 22 22:37:31 2008 -0700 @@ -186,7 +186,7 @@ // --- 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); diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/java/nio/Direct-X-Buffer.java --- a/jdk/src/share/classes/java/nio/Direct-X-Buffer.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/java/nio/Direct-X-Buffer.java Mon Sep 22 22:37:31 2008 -0700 @@ -402,7 +402,7 @@ // --- 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); diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/java/nio/Heap-X-Buffer.java --- a/jdk/src/share/classes/java/nio/Heap-X-Buffer.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/java/nio/Heap-X-Buffer.java Mon Sep 22 22:37:31 2008 -0700 @@ -566,7 +566,7 @@ // --- 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)) diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/java/nio/StringCharBuffer.java --- a/jdk/src/share/classes/java/nio/StringCharBuffer.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/java/nio/StringCharBuffer.java Mon Sep 22 22:37:31 2008 -0700 @@ -99,7 +99,7 @@ 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, diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/java/nio/X-Buffer.java --- a/jdk/src/share/classes/java/nio/X-Buffer.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/java/nio/X-Buffer.java Mon Sep 22 22:37:31 2008 -0700 @@ -1239,13 +1239,13 @@ * smaller than start and no larger than * remaining() * - * @return The new character sequence + * @return The new character buffer * * @throws IndexOutOfBoundsException * If the preconditions on start and end * do not hold */ - public abstract CharSequence subSequence(int start, int end); + public abstract CharBuffer subSequence(int start, int end); // --- Methods to support Appendable --- diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/java/security/cert/CertPathValidatorException.java --- a/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/java/security/cert/CertPathValidatorException.java Mon Sep 22 22:37:31 2008 -0700 @@ -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 @@ * if any, that caused this exception to be thrown. *

* A CertPathValidatorException 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. * *

* Concurrent Access @@ -72,11 +76,16 @@ private CertPath certPath; /** + * @serial the reason the validation failed + */ + private Reason reason = BasicReason.UNSPECIFIED; + + /** * Creates a CertPathValidatorException with * no detail message. */ public CertPathValidatorException() { - super(); + this(null, null); } /** @@ -87,7 +96,7 @@ * @param msg the detail message */ public CertPathValidatorException(String msg) { - super(msg); + this(msg, null); } /** @@ -104,7 +113,7 @@ * permitted, and indicates that the cause is nonexistent or unknown.) */ public CertPathValidatorException(Throwable cause) { - super(cause); + this(null, cause); } /** @@ -117,7 +126,7 @@ * 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 CertPathValidatorException(String msg, Throwable cause, CertPath certPath, int index) { + this(msg, cause, certPath, index, BasicReason.UNSPECIFIED); + } + + /** + * Creates a CertPathValidatorException with the specified + * detail message, cause, certification path, index, and reason. + * + * @param msg the detail message (or null if none) + * @param cause the cause (or null 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 CertPath is zero based. + * @param reason the reason the validation failed + * @throws IndexOutOfBoundsException if the index is out of range + * (index < -1 || (certPath != null && index >= + * certPath.getCertificates().size()) + * @throws IllegalArgumentException if certPath is + * null and index is not -1 + * @throws NullPointerException if reason is null + * + * @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 @@ (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 @@ 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 + * BasicReason.UNSPECIFIED 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 + } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/java/security/cert/PKIXReason.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/src/share/classes/java/security/cert/PKIXReason.java Mon Sep 22 22:37:31 2008 -0700 @@ -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 PKIXReason 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 + * CertPathValidatorException.BasicReason 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 +} diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/java/util/logging/Logging.java --- a/jdk/src/share/classes/java/util/logging/Logging.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/java/util/logging/Logging.java Mon Sep 22 22:37:31 2008 -0700 @@ -118,6 +118,6 @@ } public ObjectName getObjectName() { - return com.sun.jmx.mbeanserver.Util.newObjectName(LogManager.LOGGING_MXBEAN_NAME); + return ObjectName.valueOf(LogManager.LOGGING_MXBEAN_NAME); } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/java/util/zip/ZipOutputStream.java --- a/jdk/src/share/classes/java/util/zip/ZipOutputStream.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/java/util/zip/ZipOutputStream.java Mon Sep 22 22:37:31 2008 -0700 @@ -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 @@ 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) diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/javax/management/InstanceNotFoundException.java --- a/jdk/src/share/classes/javax/management/InstanceNotFoundException.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/javax/management/InstanceNotFoundException.java Mon Sep 22 22:37:31 2008 -0700 @@ -61,6 +61,6 @@ * @since 1.7 */ public InstanceNotFoundException(ObjectName name) { - this(name.toString()); + this(String.valueOf(name)); } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/javax/management/MBeanServerDelegate.java --- a/jdk/src/share/classes/javax/management/MBeanServerDelegate.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/javax/management/MBeanServerDelegate.java Mon Sep 22 22:37:31 2008 -0700 @@ -304,7 +304,7 @@ * @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 diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/javax/management/ObjectName.java --- a/jdk/src/share/classes/javax/management/ObjectName.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/javax/management/ObjectName.java Mon Sep 22 22:37:31 2008 -0700 @@ -413,7 +413,7 @@ } private void copyToOtherDomain(String domain, ObjectName aname) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { // The domain cannot be null if (domain == null) @@ -467,7 +467,7 @@ * is null. */ private void construct(String name) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { // The name cannot be null if (name == null) @@ -729,7 +729,7 @@ * @exception NullPointerException One of the parameters is null. */ private void construct(String domain, Map props) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { // The domain cannot be null if (domain == null) @@ -1071,7 +1071,7 @@ * 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 @@ * @exception NullPointerException The name 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 @@ * 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 @@ * quoting. * @exception NullPointerException One of the parameters is null. * + * @see #valueOf(String, Hashtable) */ public static ObjectName getInstance(String domain, Hashtable table) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { return new ObjectName(domain, table); } @@ -1453,11 +1456,120 @@ * @exception NullPointerException The name 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()); + } + + /** + *

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.

+ * + *

This method is equivalent to {@link #getInstance(String)} except that + * it does not throw any checked exceptions.

+ * + * @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 name 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. + } + } + + /** + *

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.

+ * + *

This method is equivalent to {@link #getInstance(String, String, + * String)} except that it does not throw any checked exceptions.

+ * + * @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 + * domain, key, or value + * contains an illegal character, or value 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); + } + } + + /** + *

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.

+ * + *

This method is equivalent to {@link #getInstance(String, Hashtable)} + * except that it does not throw any checked exceptions.

+ * + * @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 domain + * contains an illegal character, or one of the keys or values in + * table contains an illegal character, or one of the + * values in table 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 table) { + try { + return new ObjectName(domain, table); + } catch (MalformedObjectNameException e) { + throw new IllegalArgumentException(e.getMessage(), e); + } } /** @@ -1477,7 +1589,7 @@ * @since 1.7 **/ public final ObjectName withDomain(String newDomain) - throws NullPointerException, MalformedObjectNameException { + throws MalformedObjectNameException { return new ObjectName(newDomain, this); } @@ -1490,9 +1602,11 @@ * parameter does not have the right format. * @exception NullPointerException The name parameter * is null. + * + * @see #valueOf(String) */ public ObjectName(String name) - throws MalformedObjectNameException, NullPointerException { + throws MalformedObjectNameException { construct(name); } @@ -1508,9 +1622,11 @@ * contains an illegal character, or value 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 @@ * values in table does not follow the rules for * quoting. * @exception NullPointerException One of the parameters is null. + * + * @see #valueOf(String, Hashtable) */ public ObjectName(String domain, Hashtable 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 @@ * * @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 @@ * * @exception NullPointerException If property is null. */ - public String getKeyProperty(String property) throws NullPointerException { + public String getKeyProperty(String property) { return _getKeyPropertyList().get(property); } @@ -1950,8 +2067,7 @@ * @exception NullPointerException if s 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 @@ * @exception NullPointerException if q 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 @@ * * @since 1.6 */ - public static final ObjectName WILDCARD = Util.newObjectName("*:*"); + public static final ObjectName WILDCARD = valueOf("*:*"); // Category : Utilities <=================================== @@ -2064,7 +2179,7 @@ * @exception NullPointerException if name is null. * */ - public boolean apply(ObjectName name) throws NullPointerException { + public boolean apply(ObjectName name) { if (name == null) throw new NullPointerException(); diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/javax/management/QueryNotificationFilter.java --- a/jdk/src/share/classes/javax/management/QueryNotificationFilter.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/javax/management/QueryNotificationFilter.java Mon Sep 22 22:37:31 2008 -0700 @@ -170,7 +170,7 @@ 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); diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/javax/management/event/EventClient.java --- a/jdk/src/share/classes/javax/management/event/EventClient.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/javax/management/event/EventClient.java Mon Sep 22 22:37:31 2008 -0700 @@ -264,11 +264,12 @@ new PerThreadGroupPool.Create() { 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; } }; diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/javax/management/event/EventClientDelegateMBean.java --- a/jdk/src/share/classes/javax/management/event/EventClientDelegateMBean.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/javax/management/event/EventClientDelegateMBean.java Mon Sep 22 22:37:31 2008 -0700 @@ -96,7 +96,7 @@ * {@value #OBJECT_NAME_STRING}. */ public final static ObjectName OBJECT_NAME = - Util.newObjectName(OBJECT_NAME_STRING); + ObjectName.valueOf(OBJECT_NAME_STRING); /** * A unique listener identifier specified for an EventClient. diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/javax/management/event/EventSubscriber.java --- a/jdk/src/share/classes/javax/management/event/EventSubscriber.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/javax/management/event/EventSubscriber.java Mon Sep 22 22:37:31 2008 -0700 @@ -149,10 +149,10 @@ if (listener == null) throw new IllegalArgumentException("Null listener"); - final ListenerInfo li = new ListenerInfo(listener, filter, handback); - List list; + final MyListenerInfo li = new MyListenerInfo(listener, filter, handback); + List list; - Map> map; + Map> map; Set names; if (name.isPattern()) { map = patternSubscriptionMap; @@ -165,7 +165,7 @@ synchronized (map) { list = map.get(name); if (list == null) { - list = new ArrayList(); + list = new ArrayList(); map.put(name, list); } list.add(li); @@ -186,7 +186,6 @@ public void unsubscribe(ObjectName name, NotificationListener listener) throws ListenerNotFoundException, IOException { - if (logger.traceOn()) logger.trace("unsubscribe", "" + name); @@ -196,7 +195,7 @@ if (listener == null) throw new ListenerNotFoundException(); - Map> map; + Map> map; Set names; if (name.isPattern()) { @@ -207,22 +206,39 @@ names = Collections.singleton(name); } - final ListenerInfo li = new ListenerInfo(listener, null, null); - List list; + List toRemove = new ArrayList(); synchronized (map) { - list = map.get(name); - if (list == null || !list.remove(li)) + List 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 @@ return; } - final List listeners = new ArrayList(); + final List listeners = new ArrayList(); // If there are subscribers for the exact name that has just arrived // then add their listeners to the list. synchronized (exactSubscriptionMap) { - List exactListeners = exactSubscriptionMap.get(name); + List exactListeners = exactSubscriptionMap.get(name); if (exactListeners != null) listeners.addAll(exactListeners); } @@ -277,7 +293,7 @@ } // 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 @@ } }; - 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 @@ 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 @@ // --------------------------------- private final MBeanServer mbeanServer; - private final Map> exactSubscriptionMap = - new HashMap>(); - private final Map> patternSubscriptionMap = - new HashMap>(); + private final Map> exactSubscriptionMap = + new HashMap>(); + private final Map> patternSubscriptionMap = + new HashMap>(); diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/javax/management/event/FetchingEventRelay.java --- a/jdk/src/share/classes/javax/management/event/FetchingEventRelay.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/javax/management/event/FetchingEventRelay.java Mon Sep 22 22:37:31 2008 -0700 @@ -31,10 +31,8 @@ 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 @@ 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; - } + if (stopped) { + return; + } - stopped = true; - clientId = null; - } + stopped = true; + clientId = null; + if (defaultExecutor != null) + defaultExecutor.shutdown(); } private class MyJob extends RepeatedSingletonJob { @@ -372,10 +367,9 @@ 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 @@ new ClassLogger("javax.management.event", "FetchingEventRelay"); private static final ThreadFactory daemonThreadFactory = - new DaemonThreadFactory("FetchingEventRelay-executor"); + new DaemonThreadFactory("JMX FetchingEventRelay executor %d"); } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/javax/management/event/RMIPushEventForwarder.java --- a/jdk/src/share/classes/javax/management/event/RMIPushEventForwarder.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/javax/management/event/RMIPushEventForwarder.java Mon Sep 22 22:37:31 2008 -0700 @@ -185,7 +185,7 @@ 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 buffer; diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/javax/management/namespace/JMXDomain.java --- a/jdk/src/share/classes/javax/management/namespace/JMXDomain.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/javax/management/namespace/JMXDomain.java Mon Sep 22 22:37:31 2008 -0700 @@ -308,17 +308,17 @@ * 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; } /** diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/javax/management/namespace/JMXNamespace.java --- a/jdk/src/share/classes/javax/management/namespace/JMXNamespace.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/javax/management/namespace/JMXNamespace.java Mon Sep 22 22:37:31 2008 -0700 @@ -482,8 +482,8 @@ /** * 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. *

* This method is called by the MBean server. * Application classes should never call this method directly. @@ -502,11 +502,14 @@ */ 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 @@ * 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. *

* This method is called by the MBean server. Application classes should @@ -549,7 +552,7 @@ /** * 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. *

* This method is called by the MBean server. Application classes should @@ -573,8 +576,11 @@ * @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; + } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/javax/management/namespace/JMXNamespaces.java --- a/jdk/src/share/classes/javax/management/namespace/JMXNamespaces.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/javax/management/namespace/JMXNamespaces.java Mon Sep 22 22:37:31 2008 -0700 @@ -266,11 +266,15 @@ 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); } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java --- a/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/javax/management/namespace/JMXRemoteNamespace.java Mon Sep 22 22:37:31 2008 -0700 @@ -28,13 +28,12 @@ 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.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 @@ */ 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 @@ 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 @@ // 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 boolean isProbeRequested() { - return this.parent.isProbeRequested(); - } } private static final MBeanNotificationInfo connectNotification = @@ -188,7 +180,7 @@ "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 @@ 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 @@ 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 @@ 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 @@ broadcaster.removeNotificationListener(listener, filter, handback); } - private static synchronized long getNextSeqNumber() { - return seqNumber++; + private static long getNextSeqNumber() { + return seqNumber.getAndIncrement(); } @@ -362,14 +346,18 @@ // 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 @@ } } - 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 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 env = new HashMap(getEnvMap()); try { @@ -640,86 +607,16 @@ 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 { diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/javax/management/namespace/MBeanServerConnectionWrapper.java --- a/jdk/src/share/classes/javax/management/namespace/MBeanServerConnectionWrapper.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/javax/management/namespace/MBeanServerConnectionWrapper.java Mon Sep 22 22:37:31 2008 -0700 @@ -28,7 +28,6 @@ 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; diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/javax/management/namespace/MBeanServerSupport.java --- a/jdk/src/share/classes/javax/management/namespace/MBeanServerSupport.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/javax/management/namespace/MBeanServerSupport.java Mon Sep 22 22:37:31 2008 -0700 @@ -193,14 +193,6 @@ * } * * 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 @@ * 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 @@ * {@code Set names = new TreeSet();} * 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 @@ * } * * 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, diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java --- a/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/javax/management/remote/rmi/RMIConnector.java Mon Sep 22 22:37:31 2008 -0700 @@ -420,7 +420,7 @@ new PerThreadGroupPool.Create() { 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(), diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/management/ClassLoadingImpl.java --- a/jdk/src/share/classes/sun/management/ClassLoadingImpl.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/management/ClassLoadingImpl.java Mon Sep 22 22:37:31 2008 -0700 @@ -71,6 +71,6 @@ 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); } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/management/CompilationImpl.java --- a/jdk/src/share/classes/sun/management/CompilationImpl.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/management/CompilationImpl.java Mon Sep 22 22:37:31 2008 -0700 @@ -70,7 +70,7 @@ } public ObjectName getObjectName() { - return Util.newObjectName(ManagementFactory.COMPILATION_MXBEAN_NAME); + return ObjectName.valueOf(ManagementFactory.COMPILATION_MXBEAN_NAME); } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/management/HotSpotDiagnostic.java --- a/jdk/src/share/classes/sun/management/HotSpotDiagnostic.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/management/HotSpotDiagnostic.java Mon Sep 22 22:37:31 2008 -0700 @@ -117,6 +117,6 @@ } public ObjectName getObjectName() { - return Util.newObjectName("com.sun.management:type=HotSpotDiagnostic"); + return ObjectName.valueOf("com.sun.management:type=HotSpotDiagnostic"); } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/management/HotspotInternal.java --- a/jdk/src/share/classes/sun/management/HotspotInternal.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/management/HotspotInternal.java Mon Sep 22 22:37:31 2008 -0700 @@ -41,7 +41,7 @@ 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; /** diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/management/ManagementFactoryHelper.java --- a/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/management/ManagementFactoryHelper.java Mon Sep 22 22:37:31 2008 -0700 @@ -220,7 +220,7 @@ */ 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 @@ 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; diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/management/MemoryImpl.java --- a/jdk/src/share/classes/sun/management/MemoryImpl.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/management/MemoryImpl.java Mon Sep 22 22:37:31 2008 -0700 @@ -177,7 +177,7 @@ } public ObjectName getObjectName() { - return Util.newObjectName(ManagementFactory.MEMORY_MXBEAN_NAME); + return ObjectName.valueOf(ManagementFactory.MEMORY_MXBEAN_NAME); } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/management/OperatingSystemImpl.java --- a/jdk/src/share/classes/sun/management/OperatingSystemImpl.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/management/OperatingSystemImpl.java Mon Sep 22 22:37:31 2008 -0700 @@ -74,7 +74,7 @@ } } public ObjectName getObjectName() { - return Util.newObjectName(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME); + return ObjectName.valueOf(ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME); } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/management/RuntimeImpl.java --- a/jdk/src/share/classes/sun/management/RuntimeImpl.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/management/RuntimeImpl.java Mon Sep 22 22:37:31 2008 -0700 @@ -149,7 +149,7 @@ } public ObjectName getObjectName() { - return Util.newObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME); + return ObjectName.valueOf(ManagementFactory.RUNTIME_MXBEAN_NAME); } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/management/ThreadImpl.java --- a/jdk/src/share/classes/sun/management/ThreadImpl.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/management/ThreadImpl.java Mon Sep 22 22:37:31 2008 -0700 @@ -415,7 +415,7 @@ private static native void resetContentionTimes0(long tid); public ObjectName getObjectName() { - return Util.newObjectName(ManagementFactory.THREAD_MXBEAN_NAME); + return ObjectName.valueOf(ManagementFactory.THREAD_MXBEAN_NAME); } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/management/Util.java --- a/jdk/src/share/classes/sun/management/Util.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/management/Util.java Mon Sep 22 22:37:31 2008 -0700 @@ -43,12 +43,8 @@ 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 = diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/net/httpserver/ChunkedOutputStream.java --- a/jdk/src/share/classes/sun/net/httpserver/ChunkedOutputStream.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/net/httpserver/ChunkedOutputStream.java Mon Sep 22 22:37:31 2008 -0700 @@ -73,6 +73,7 @@ if (count == CHUNK_SIZE) { writeChunk(); } + assert count < CHUNK_SIZE; } public void write (byte[]b, int off, int len) throws IOException { @@ -86,20 +87,22 @@ 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(); + } } /** diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/security/krb5/Config.java --- a/jdk/src/share/classes/sun/security/krb5/Config.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/security/krb5/Config.java Mon Sep 22 22:37:31 2008 -0700 @@ -803,7 +803,7 @@ 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 (); diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/security/provider/certpath/BasicChecker.java --- a/jdk/src/share/classes/sun/security/provider/certpath/BasicChecker.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/security/provider/certpath/BasicChecker.java Mon Sep 22 22:37:31 2008 -0700 @@ -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.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 @@ 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 @@ 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 @@ // 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 @@ 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); diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/security/provider/certpath/ConstraintsChecker.java --- a/jdk/src/share/classes/sun/security/provider/certpath/ConstraintsChecker.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/security/provider/certpath/ConstraintsChecker.java Mon Sep 22 22:37:31 2008 -0700 @@ -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.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 @@ 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 @@ 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 @@ 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--; } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/security/provider/certpath/CrlRevocationChecker.java --- a/jdk/src/share/classes/sun/security/provider/certpath/CrlRevocationChecker.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/security/provider/certpath/CrlRevocationChecker.java Mon Sep 22 22:37:31 2008 -0700 @@ -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.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 @@ " 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 @@ 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 @@ + 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 @@ 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 @@ " 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 @@ 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 @@ 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); } } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java --- a/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/security/provider/certpath/ForwardBuilder.java Mon Sep 22 22:37:31 2008 -0700 @@ -32,6 +32,7 @@ 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 @@ 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); } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/security/provider/certpath/KeyChecker.java --- a/jdk/src/share/classes/sun/security/provider/certpath/KeyChecker.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/security/provider/certpath/KeyChecker.java Mon Sep 22 22:37:31 2008 -0700 @@ -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 @@ 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 @@ 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 @@ // 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) { diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java --- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPChecker.java Mon Sep 22 22:37:31 2008 -0700 @@ -33,6 +33,7 @@ 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 @@ } 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); diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java --- a/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Mon Sep 22 22:37:31 2008 -0700 @@ -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.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.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 @@ private List userCheckers; private String sigProvider; private BasicChecker basicChecker; + private String ocspProperty; /** * Default constructor. @@ -126,7 +127,7 @@ // Must copy elements of certList into a new modifiable List before // calling Collections.reverse(). - List certList = new ArrayList + ArrayList certList = new ArrayList ((List)cp.getCertificates()); if (debug != null) { if (certList.isEmpty()) { @@ -201,7 +202,8 @@ } // (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 @@ */ private boolean isWorthTrying(X509Certificate trustedCert, X509Certificate firstCert) - throws CertPathValidatorException { if (debug != null) { debug.println("PKIXCertPathValidator.isWorthTrying() checking " @@ -240,7 +241,6 @@ * 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 @@ userCheckers = pkixParam.getCertPathCheckers(); sigProvider = pkixParam.getSigProvider(); + + if (pkixParam.isRevocationEnabled()) { + // Examine OCSP security property + ocspProperty = AccessController.doPrivileged( + new PrivilegedAction() { + public String run() { + return + Security.getProperty(OCSPChecker.OCSP_ENABLE_PROP); + } + }); + } } /** @@ -259,12 +270,9 @@ */ private PolicyNode doValidate( TrustAnchor anchor, CertPath cpOriginal, - List certList, PKIXParameters pkixParam, + ArrayList certList, PKIXParameters pkixParam, PolicyNodeImpl rootNode) throws CertPathValidatorException { - List certPathCheckers = - new ArrayList(); - int certPathLen = certList.size(); basicChecker = new BasicChecker(anchor, testDate, sigProvider, false); @@ -281,6 +289,8 @@ pkixParam.getPolicyQualifiersRejected(), rootNode); + ArrayList certPathCheckers = + new ArrayList(); // add standard checkers that we will be using certPathCheckers.add(keyChecker); certPathCheckers.add(constraintsChecker); @@ -290,15 +300,6 @@ // only add a revocationChecker if revocation is enabled if (pkixParam.isRevocationEnabled()) { - // Examine OCSP security property - String ocspProperty = AccessController.doPrivileged( - new PrivilegedAction() { - public String run() { - return - Security.getProperty(OCSPChecker.OCSP_ENABLE_PROP); - } - }); - // Use OCSP if it has been enabled if ("true".equalsIgnoreCase(ocspProperty)) { OCSPChecker ocspChecker = diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java --- a/jdk/src/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/security/provider/certpath/PKIXMasterCertPathValidator.java Mon Sep 22 22:37:31 2008 -0700 @@ -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.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 @@ */ 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 @@ 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) diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/security/provider/certpath/PolicyChecker.java --- a/jdk/src/share/classes/sun/security/provider/certpath/PolicyChecker.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/security/provider/certpath/PolicyChecker.java Mon Sep 22 22:37:31 2008 -0700 @@ -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.security.cert.Certificate; import java.security.cert.CertificateException; -import java.security.cert.X509Certificate; +import java.security.cert.CertPathValidatorException; import java.security.cert.PKIXCertPathChecker; -import java.security.cert.CertPathValidatorException; +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 @@ // 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 @@ 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 @@ 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 validNodes = diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java --- a/jdk/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/security/provider/certpath/ReverseBuilder.java Mon Sep 22 22:37:31 2008 -0700 @@ -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.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 @@ */ 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 @@ 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 @@ 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); } /* diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java --- a/jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java Mon Sep 22 22:37:31 2008 -0700 @@ -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.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.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 @@ (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); } } } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/tools/jconsole/Plotter.java --- a/jdk/src/share/classes/sun/tools/jconsole/Plotter.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/tools/jconsole/Plotter.java Mon Sep 22 22:37:31 2008 -0700 @@ -30,18 +30,15 @@ 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 @@ 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 @@ 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 @@ } } + @Override public JPopupMenu getComponentPopupMenu() { if (popupMenu == null) { popupMenu = new JPopupMenu(Resources.getText("Chart:")); @@ -330,6 +335,7 @@ } } + @Override public void paintComponent(Graphics g) { super.paintComponent(g); @@ -670,7 +676,7 @@ 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 @@ } 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 @@ } } + @Override public AccessibleContext getAccessibleContext() { if (accessibleContext == null) { accessibleContext = new AccessiblePlotter(); @@ -1042,10 +1051,12 @@ } 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 @@ return name; } + @Override public AccessibleRole getAccessibleRole() { return AccessibleRole.CANVAS; } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanAttributes.java --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanAttributes.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanAttributes.java Mon Sep 22 22:37:31 2008 -0700 @@ -872,8 +872,8 @@ 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 diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java Mon Sep 22 22:37:31 2008 -0700 @@ -34,7 +34,7 @@ JTable table; public XPlotter(JTable table, Plotter.Unit unit) { - super(unit); + super(unit,0,false); this.table = table; } @Override diff -r d718a4419361 -r b23505b07d80 jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java --- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java Mon Sep 22 22:37:31 2008 -0700 @@ -27,14 +27,10 @@ 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 @@ setBackground(g.getColor()); plotter.paintComponent(g); }*/ + @Override public void actionPerformed(ActionEvent evt) { plotterCache.remove(key); Timer t = timerCache.remove(key); @@ -141,9 +138,11 @@ 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 @@ 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); + buttonPanel.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); - + 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(); } diff -r d718a4419361 -r b23505b07d80 jdk/src/share/native/java/util/zip/zip_util.c --- a/jdk/src/share/native/java/util/zip/zip_util.c Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/src/share/native/java/util/zip/zip_util.c Mon Sep 22 22:37:31 2008 -0700 @@ -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 @@ } 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 @@ 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 @@ ulen = 0; } +Finally: ZIP_Unlock(zip); return ze; } diff -r d718a4419361 -r b23505b07d80 jdk/test/com/sun/jdi/ClassesByName2Test.java --- a/jdk/test/com/sun/jdi/ClassesByName2Test.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/com/sun/jdi/ClassesByName2Test.java Mon Sep 22 22:37:31 2008 -0700 @@ -41,8 +41,7 @@ /********** 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 @@ } }; - 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 @@ /********** 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(); } + 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"); + /* - * Get to the top of ready() - */ - startTo("ClassesByName2Targ", "ready", "()V"); - + 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 @@ } } - - // 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); /* diff -r d718a4419361 -r b23505b07d80 jdk/test/com/sun/net/httpserver/bugs/B6744329.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/com/sun/net/httpserver/bugs/B6744329.java Mon Sep 22 22:37:31 2008 -0700 @@ -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(); + } + } +} diff -r d718a4419361 -r b23505b07d80 jdk/test/java/net/CookieHandler/TestHttpCookie.java --- a/jdk/test/java/net/CookieHandler/TestHttpCookie.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/java/net/CookieHandler/TestHttpCookie.java Mon Sep 22 22:37:31 2008 -0700 @@ -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 @@ } 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 @@ } 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) { diff -r d718a4419361 -r b23505b07d80 jdk/test/java/security/cert/CertPathValidator/nameConstraintsRFC822/ValidateCertPath.java --- a/jdk/test/java/security/cert/CertPathValidator/nameConstraintsRFC822/ValidateCertPath.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/java/security/cert/CertPathValidator/nameConstraintsRFC822/ValidateCertPath.java Mon Sep 22 22:37:31 2008 -0700 @@ -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.IOException; import java.security.cert.*; +import java.security.cert.PKIXReason; import java.util.ArrayList; import java.util.Collections; @@ -69,6 +70,9 @@ 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 @@ args = new String[] {"jane2jane.cer", "jane2steve.cer", "steve2tom.cer"}; TrustAnchor anchor = new TrustAnchor(getCertFromFile(args[0]), null); - List list = new ArrayList(); + List list = new ArrayList(); 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 anchors = Collections.singleton(anchor); params = new PKIXParameters(anchors); params.setRevocationEnabled(false); } diff -r d718a4419361 -r b23505b07d80 jdk/test/java/security/cert/CertPathValidatorException/ReasonTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/cert/CertPathValidatorException/ReasonTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -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"); + } + } +} diff -r d718a4419361 -r b23505b07d80 jdk/test/java/security/cert/CertPathValidatorException/Serial.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/security/cert/CertPathValidatorException/Serial.java Mon Sep 22 22:37:31 2008 -0700 @@ -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); + } + } +} diff -r d718a4419361 -r b23505b07d80 jdk/test/java/security/cert/CertPathValidatorException/cert_file Binary file jdk/test/java/security/cert/CertPathValidatorException/cert_file has changed diff -r d718a4419361 -r b23505b07d80 jdk/test/java/security/cert/CertPathValidatorException/jdk6.serial Binary file jdk/test/java/security/cert/CertPathValidatorException/jdk6.serial has changed diff -r d718a4419361 -r b23505b07d80 jdk/test/java/security/cert/PolicyNode/GetPolicyQualifiers.java --- a/jdk/test/java/security/cert/PolicyNode/GetPolicyQualifiers.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/java/security/cert/PolicyNode/GetPolicyQualifiers.java Mon Sep 22 22:37:31 2008 -0700 @@ -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 @@ 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()); + } + } } } diff -r d718a4419361 -r b23505b07d80 jdk/test/java/util/zip/TestEmptyZip.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/util/zip/TestEmptyZip.java Mon Sep 22 22:37:31 2008 -0700 @@ -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");} +} diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/MBeanServer/InstanceNotFoundExceptionTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/management/MBeanServer/InstanceNotFoundExceptionTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -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()); + } +} diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/MBeanServerFactory/NamedMBeanServerTest.java --- a/jdk/test/javax/management/MBeanServerFactory/NamedMBeanServerTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/MBeanServerFactory/NamedMBeanServerTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -25,6 +25,7 @@ * @test * @summary Test named MBeanServers. * @author Daniel Fuchs + * @bug 6299231 * @run clean NamedMBeanServerTest * @run build NamedMBeanServerTest * @run main NamedMBeanServerTest diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/ObjectName/ValueOfTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/management/ObjectName/ValueOfTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -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 h = new Hashtable(); + 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()); + } + + 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; + } +} diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/eventService/EventClientThreadTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/management/eventService/EventClientThreadTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -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 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 jmxThreads = threadsMatching("JMX .*"); + while (!jmxThreads.isEmpty() && System.currentTimeMillis() < deadline) { + Set jmxThreadsNow = threadsMatching("JMX .*"); + Set gone = new TreeSet(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 threadsMatching(String pattern) { + Set matching = new TreeSet(); + 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(); + } +} \ No newline at end of file diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/eventService/LeaseManagerDeadlockTest.java --- a/jdk/test/javax/management/eventService/LeaseManagerDeadlockTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/eventService/LeaseManagerDeadlockTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -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; diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/eventService/SharingThreadTest.java --- a/jdk/test/javax/management/eventService/SharingThreadTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/eventService/SharingThreadTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -1,4 +1,4 @@ -/*/* +/* * Copyright 2007 Sun Microsystems, Inc. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/eventService/SubUnsubTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/management/eventService/SubUnsubTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -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; + } +} \ No newline at end of file diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/DomainCreationTest.java --- a/jdk/test/javax/management/namespace/DomainCreationTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/DomainCreationTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -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 diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/EventWithNamespaceControlTest.java --- a/jdk/test/javax/management/namespace/EventWithNamespaceControlTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/EventWithNamespaceControlTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -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 diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/EventWithNamespaceTest.java --- a/jdk/test/javax/management/namespace/EventWithNamespaceTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/EventWithNamespaceTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -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 diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/ExportNamespaceTest.java --- a/jdk/test/javax/management/namespace/ExportNamespaceTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/ExportNamespaceTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -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 diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/JMXDomainTest.java --- a/jdk/test/javax/management/namespace/JMXDomainTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/JMXDomainTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -23,6 +23,7 @@ /* * * @test JMXDomainTest.java + * @bug 5072476 * @summary Basic test for JMXDomain. * @author Daniel Fuchs * @run clean JMXDomainTest Wombat WombatMBean diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/JMXNamespaceSecurityTest.java --- a/jdk/test/javax/management/namespace/JMXNamespaceSecurityTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/JMXNamespaceSecurityTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -26,6 +26,7 @@ * @test JMXNamespaceSecurityTest.java * @summary General JMXNamespaceSecurityTest test. * @author Daniel Fuchs + * @bug 5072476 6299231 * @run clean JMXNamespaceViewTest JMXNamespaceSecurityTest Wombat WombatMBean * LazyDomainTest * @run build JMXNamespaceSecurityTest JMXNamespaceViewTest Wombat WombatMBean diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/JMXNamespaceTest.java --- a/jdk/test/javax/management/namespace/JMXNamespaceTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/JMXNamespaceTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -25,6 +25,7 @@ * * @test JMXNamespaceTest.java * @summary General JMXNamespace test. + * @bug 5072476 * @author Daniel Fuchs * @run clean JMXNamespaceTest * Wombat WombatMBean JMXRemoteTargetNamespace @@ -34,7 +35,6 @@ * NamespaceController.java NamespaceControllerMBean.java * @run main/othervm JMXNamespaceTest */ -import java.io.IOException; import java.lang.management.ManagementFactory; import java.lang.management.MemoryMXBean; import java.lang.reflect.InvocationTargetException; @@ -51,10 +51,10 @@ import javax.management.JMX; import javax.management.MBeanServer; import javax.management.MBeanServerConnection; +import javax.management.MBeanServerFactory; import javax.management.NotificationEmitter; import javax.management.ObjectInstance; import javax.management.ObjectName; -import javax.management.RuntimeOperationsException; import javax.management.StandardMBean; import javax.management.namespace.JMXNamespaces; import javax.management.namespace.JMXNamespace; @@ -154,7 +154,7 @@ } } - private static class SimpleTestConf { + public static class SimpleTestConf { public final Wombat wombat; public final StandardMBean mbean; public final String dirname; @@ -456,259 +456,56 @@ } } - /** - * Test cycle detection. - * mkdir test ; cd test ; ln -s . kanga ; ln -s kanga/kanga/roo/kanga roo - * touch kanga/roo/wombat - **/ - public static void probeKangaRooTest(String[] args) { - final SimpleTestConf conf; + public static void verySimpleTest(String[] args) { + System.err.println("verySimpleTest: starting"); try { - conf = new SimpleTestConf(args); - try { - final JMXServiceURL url = - new JMXServiceURL("rmi","localHost",0); - final Map empty = Collections.emptyMap(); - final JMXConnectorServer server = - JMXConnectorServerFactory.newJMXConnectorServer(url, - empty,conf.server); - server.start(); - final JMXServiceURL address = server.getAddress(); - final JMXConnector client = - JMXConnectorFactory.connect(address, - empty); - final String[] signature = { - JMXServiceURL.class.getName(), - Map.class.getName(), - }; - - final Object[] params = { - address, - null, - }; - final MBeanServerConnection c = - client.getMBeanServerConnection(); - - // ln -s . kanga - final ObjectName dirName1 = - new ObjectName("kanga//:type=JMXNamespace"); - c.createMBean(JMXRemoteTargetNamespace.class.getName(), - dirName1, params,signature); - c.invoke(dirName1, "connect", null, null); - try { - // ln -s kanga//kanga//roo//kanga roo - final JMXNamespace local = new JMXNamespace( - new MBeanServerConnectionWrapper(null, - JMXNamespaceTest.class.getClassLoader()){ - - @Override - protected MBeanServerConnection getMBeanServerConnection() { - return JMXNamespaces.narrowToNamespace(c, - "kanga//kanga//roo//kanga" - ); - } - - }); - final ObjectName dirName2 = - new ObjectName("roo//:type=JMXNamespace"); - conf.server.registerMBean(local,dirName2); - System.out.println(dirName2 + " created!"); - try { - // touch kanga/roo/wombat - final ObjectName wombatName1 = - new ObjectName("kanga//roo//"+conf.wombatName); - final WombatMBean wombat1 = - JMX.newMBeanProxy(c,wombatName1,WombatMBean.class); - final String newCaption="I am still the same old wombat"; - Exception x = null; - try { - wombat1.setCaption(newCaption); - } catch (RuntimeOperationsException r) { - x=r.getTargetException(); - System.out.println("Got expected exception: " + x); - // r.printStackTrace(); - } - if (x == null) - throw new RuntimeException("cycle not detected!"); - } finally { - c.unregisterMBean(dirName2); - } - } finally { - c.unregisterMBean(dirName1); - client.close(); - server.stop(); - } - } finally { - conf.close(); - } - System.err.println("probeKangaRooTest PASSED"); + final MBeanServer srv = MBeanServerFactory.createMBeanServer(); + srv.registerMBean(new JMXNamespace( + JMXNamespaces.narrowToNamespace(srv, "foo")), + JMXNamespaces.getNamespaceObjectName("foo")); + throw new Exception("Excpected IllegalArgumentException not raised."); + } catch (IllegalArgumentException x) { + System.err.println("verySimpleTest: got expected exception: "+x); } catch (Exception x) { - System.err.println("probeKangaRooTest FAILED: " +x); + System.err.println("verySimpleTest FAILED: " +x); x.printStackTrace(); throw new RuntimeException(x); } + System.err.println("verySimpleTest: PASSED"); } - /** - * Test cycle detection 2. - * mkdir test ; cd test ; ln -s . roo ; ln -s roo/roo kanga - * touch kanga/roo/wombat ; rm roo ; ln -s kanga roo ; - * touch kanga/roo/wombat - * - **/ - public static void probeKangaRooCycleTest(String[] args) { - final SimpleTestConf conf; - try { - conf = new SimpleTestConf(args); - Exception failed = null; - try { - final JMXServiceURL url = - new JMXServiceURL("rmi","localHost",0); - final Map empty = Collections.emptyMap(); - final JMXConnectorServer server = - JMXConnectorServerFactory.newJMXConnectorServer(url, - empty,conf.server); - server.start(); - final JMXServiceURL address = server.getAddress(); - final JMXConnector client = - JMXConnectorFactory.connect(address, - empty); - final String[] signature = { - JMXServiceURL.class.getName(), - Map.class.getName(), - }; - final String[] signature2 = { - JMXServiceURL.class.getName(), - Map.class.getName(), - String.class.getName() - }; - final Object[] params = { - address, - Collections.emptyMap(), - }; - final Object[] params2 = { - address, - null, - "kanga", - }; - final MBeanServerConnection c = - client.getMBeanServerConnection(); - // ln -s . roo - final ObjectName dirName1 = - new ObjectName("roo//:type=JMXNamespace"); - c.createMBean(JMXRemoteTargetNamespace.class.getName(), - dirName1, params,signature); - c.invoke(dirName1, "connect",null,null); - try { - final Map emptyMap = - Collections.emptyMap(); - final JMXNamespace local = new JMXNamespace( - new MBeanServerConnectionWrapper( - JMXNamespaces.narrowToNamespace(c, - "roo//roo//"), - JMXNamespaceTest.class.getClassLoader())) { - }; - // ln -s roo/roo kanga - final ObjectName dirName2 = - new ObjectName("kanga//:type=JMXNamespace"); - conf.server.registerMBean(local,dirName2); - System.out.println(dirName2 + " created!"); - try { - // touch kanga/roo/wombat - final ObjectName wombatName1 = - new ObjectName("kanga//roo//"+conf.wombatName); - final WombatMBean wombat1 = - JMX.newMBeanProxy(c,wombatName1,WombatMBean.class); - final String newCaption="I am still the same old wombat"; - wombat1.setCaption(newCaption); - // rm roo - c.unregisterMBean(dirName1); - // ln -s kanga roo - System.err.println("**** Creating " + dirName1 + - " ****"); - c.createMBean(JMXRemoteTargetNamespace.class.getName(), - dirName1, params2,signature2); - System.err.println("**** Created " + dirName1 + - " ****"); - Exception x = null; - try { - // touch kanga/roo/wombat - wombat1.setCaption(newCaption+" I hope"); - } catch (RuntimeOperationsException r) { - x=(Exception)r.getCause(); - System.out.println("Got expected exception: " + x); - //r.printStackTrace(); - } - if (x == null) - throw new RuntimeException("should have failed!"); - x = null; - try { - // ls kanga/roo/wombat - System.err.println("**** Connecting " + dirName1 + - " ****"); - JMX.newMBeanProxy(c,dirName1, - JMXRemoteNamespaceMBean.class).connect(); - System.err.println("**** Connected " + dirName1 + - " ****"); - } catch (IOException r) { - x=r; - System.out.println("Got expected exception: " + x); - //r.printStackTrace(); - } - System.err.println("**** Expected Exception Not Raised ****"); - if (x == null) { - System.out.println(dirName1+" contains: "+ - c.queryNames(new ObjectName( - dirName1.getDomain()+"*:*"),null)); - throw new RuntimeException("cycle not detected!"); - } - } catch (Exception t) { - if (failed == null) failed = t; - } finally { - c.unregisterMBean(dirName2); - } - } finally { - try { - c.unregisterMBean(dirName1); - } catch (Exception t) { - if (failed == null) failed = t; - System.err.println("Failed to unregister "+dirName1+ - ": "+t); - } - try { - client.close(); - } catch (Exception t) { - if (failed == null) failed = t; - System.err.println("Failed to close client: "+t); - } - try { - server.stop(); - } catch (Exception t) { - if (failed == null) failed = t; - System.err.println("Failed to stop server: "+t); - } - } - } finally { - try { - conf.close(); - } catch (Exception t) { - if (failed == null) failed = t; - System.err.println("Failed to stop server: "+t); - } - } - if (failed != null) throw failed; - System.err.println("probeKangaRooCycleTest PASSED"); + public static void verySimpleTest2(String[] args) { + System.err.println("verySimpleTest2: starting"); + try { + final MBeanServer srv = MBeanServerFactory.createMBeanServer(); + final JMXConnectorServer cs = JMXConnectorServerFactory. + newJMXConnectorServer(new JMXServiceURL("rmi",null,0), + null, srv); + cs.start(); + final JMXConnector cc = JMXConnectorFactory.connect(cs.getAddress()); + + srv.registerMBean(new JMXNamespace( + new MBeanServerConnectionWrapper( + JMXNamespaces.narrowToNamespace( + cc.getMBeanServerConnection(), + "foo"))), + JMXNamespaces.getNamespaceObjectName("foo")); + throw new Exception("Excpected IllegalArgumentException not raised."); + } catch (IllegalArgumentException x) { + System.err.println("verySimpleTest2: got expected exception: "+x); } catch (Exception x) { - System.err.println("probeKangaRooCycleTest FAILED: " +x); + System.err.println("verySimpleTest2 FAILED: " +x); x.printStackTrace(); throw new RuntimeException(x); } + System.err.println("verySimpleTest2: PASSED"); } + public static void main(String[] args) { simpleTest(args); recursiveTest(args); - probeKangaRooTest(args); - probeKangaRooCycleTest(args); + verySimpleTest(args); + verySimpleTest2(args); } } diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/JMXNamespaceViewTest.java --- a/jdk/test/javax/management/namespace/JMXNamespaceViewTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/JMXNamespaceViewTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -24,6 +24,7 @@ * * @test JMXNamespaceViewTest.java * @summary Test the JMXNamespaceView class. + * @bug 5072476 * @author Daniel Fuchs * @run clean JMXNamespaceViewTest Wombat WombatMBean * @run build JMXNamespaceViewTest Wombat WombatMBean diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/JMXNamespacesTest.java --- a/jdk/test/javax/management/namespace/JMXNamespacesTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/JMXNamespacesTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -24,6 +24,7 @@ * @test JMXNamespacesTest.java * @summary Test the static method that rewrite ObjectNames in JMXNamespacesTest * @author Daniel Fuchs + * @bug 5072476 * @run clean JMXNamespacesTest * @compile -XDignore.symbol.file=true JMXNamespacesTest.java * @run main JMXNamespacesTest diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/JMXRemoteNamespaceTest.java --- a/jdk/test/javax/management/namespace/JMXRemoteNamespaceTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/JMXRemoteNamespaceTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -25,6 +25,7 @@ * @test JMXRemoteNamespaceTest.java * @summary Basic tests on a JMXRemoteNamespace. * @author Daniel Fuchs + * @bug 5072476 * @run clean JMXRemoteNamespaceTest Wombat WombatMBean * @run build JMXRemoteNamespaceTest Wombat WombatMBean * @run main JMXRemoteNamespaceTest diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/LazyDomainTest.java --- a/jdk/test/javax/management/namespace/LazyDomainTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/LazyDomainTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -23,6 +23,7 @@ /* * * @test LazyDomainTest.java + * @bug 5072476 * @summary Basic test for Lazy Domains. * @author Daniel Fuchs * @run clean LazyDomainTest Wombat WombatMBean diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/LeadingSeparatorsTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/management/namespace/LeadingSeparatorsTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -0,0 +1,227 @@ +/* + * 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 LeadingSeparatorsTest.java + * @summary Test that the semantics of a leading // in ObjectName is respected. + * @author Daniel Fuchs + * @bug 5072476 + * @run clean LeadingSeparatorsTest Wombat WombatMBean + * @compile -XDignore.symbol.file=true LeadingSeparatorsTest.java + * @run build LeadingSeparatorsTest Wombat WombatMBean + * @run main LeadingSeparatorsTest + */ + +import java.lang.management.ManagementFactory; +import java.util.Arrays; +import java.util.Set; +import java.util.HashSet; +import java.util.logging.Logger; +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.NotCompliantMBeanException; +import javax.management.ObjectName; +import javax.management.namespace.JMXNamespaces; +import javax.management.namespace.JMXRemoteNamespace; +import javax.management.namespace.JMXNamespace; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXConnectorServerFactory; +import javax.management.remote.JMXServiceURL; + +/** + * Class LeadingSeparatorsTest + * @author Sun Microsystems, 2005 - All rights reserved. + */ +public class LeadingSeparatorsTest { + + /** + * A logger for this class. + **/ + private static final Logger LOG = + Logger.getLogger(LeadingSeparatorsTest.class.getName()); + + /** Creates a new instance of NullObjectNameTest */ + public LeadingSeparatorsTest() { + } + + public static interface MyWombatMBean extends WombatMBean { + public Set untrue(ObjectName pat) throws Exception; + } + public static class MyWombat + extends Wombat implements MyWombatMBean { + public MyWombat() throws NotCompliantMBeanException { + super(MyWombatMBean.class); + } + + public Set untrue(ObjectName pat) throws Exception { + final Set res=listMatching(pat.withDomain("*")); + final Set untrue = new HashSet(); + for (ObjectName a:res) { + untrue.add(a.withDomain(pat.getDomain()+"//"+a.getDomain())); + } + return untrue; + } + } + + static String failure=null; + + public static void testRegister() throws Exception { + final MBeanServer top = ManagementFactory.getPlatformMBeanServer(); + final MBeanServer sub = MBeanServerFactory.createMBeanServer(); + final JMXServiceURL url = new JMXServiceURL("rmi",null,0); + final JMXConnectorServer srv = + JMXConnectorServerFactory.newJMXConnectorServer(url,null,sub); + srv.start(); + + try { + + // Create a namespace rmi// that points to 'sub' and flows through + // a JMXRemoteNamespace connected to 'srv' + // The namespace rmi// will accept createMBean, but not registerMBean. + // + final JMXRemoteNamespace rmiHandler = JMXRemoteNamespace. + newJMXRemoteNamespace(srv.getAddress(),null); + top.registerMBean(rmiHandler, + JMXNamespaces.getNamespaceObjectName("rmi")); + top.invoke(JMXNamespaces.getNamespaceObjectName("rmi"), + "connect", null, null); + + // Create a namespace direct// that points to 'sub' and flows + // through a direct reference to 'sub'. + // The namespace direct// will accept createMBean, and registerMBean. + // + final JMXNamespace directHandler = new JMXNamespace(sub); + top.registerMBean(directHandler, + JMXNamespaces.getNamespaceObjectName("direct")); + + final ObjectName n1 = new ObjectName("//direct//w:type=Wombat"); + final ObjectName n2 = new ObjectName("direct//w:type=Wombat"); + final ObjectName n3 = new ObjectName("//rmi//w:type=Wombat"); + final ObjectName n4 = new ObjectName("rmi//w:type=Wombat"); + + // register wombat using an object name with a leading // + final Object obj = new MyWombat(); + // check that returned object name doesn't have the leading // + assertEquals(n2,top.registerMBean(obj, n1).getObjectName()); + System.out.println(n1+" registered"); + + // check that the registered Wombat can be accessed with all its + // names. + System.out.println(n2+" mood is: "+top.getAttribute(n2, "Mood")); + System.out.println(n1+" mood is: "+top.getAttribute(n1, "Mood")); + System.out.println(n4+" mood is: "+top.getAttribute(n4, "Mood")); + System.out.println(n3+" mood is: "+top.getAttribute(n3, "Mood")); + + // call listMatching. The result should not contain any prefix. + final Set res = (Set) + top.invoke(n3, "listMatching", + // remove rmi// from rmi//*:* + JMXNamespaces.deepReplaceHeadNamespace( + new Object[] {ObjectName.WILDCARD.withDomain("rmi//*")}, + "rmi", ""), new String[] {ObjectName.class.getName()}); + + // add rmi// prefix to all names in res. + final Set res1 = + JMXNamespaces.deepReplaceHeadNamespace(res, "", "rmi"); + System.out.println("got: "+res1); + + // compute expected result + final Set res2 = sub.queryNames(null,null); + final Set res3 = new HashSet(); + for (ObjectName o:res2) { + res3.add(o.withDomain("rmi//"+o.getDomain())); + } + System.out.println("expected: "+res3); + assertEquals(res1, res3); + + // invoke "untrue(//niark//niark:*)" + // should return a set were all ObjectNames begin with + // //niark//niark// + // + final Set res4 = (Set) + top.invoke(n3, "untrue", + // remove niark//niark : should remove nothing since + // our ObjectName begins with a leading // + JMXNamespaces.deepReplaceHeadNamespace( + new Object[] { + ObjectName.WILDCARD.withDomain("//niark//niark")}, + "niark//niark", ""), + new String[] {ObjectName.class.getName()}); + System.out.println("got: "+res4); + + // add rmi// should add nothing since the returned names have a + // leading // + // + final Set res5 = + JMXNamespaces.deepReplaceHeadNamespace(res4, "", "rmi"); + System.out.println("got#2: "+res5); + + // compute expected result + final Set res6 = new HashSet(); + for (ObjectName o:res2) { + res6.add(o.withDomain("//niark//niark//"+o.getDomain())); + } + System.out.println("expected: "+res6); + + // both res4 and res5 should be equals to the expected result. + assertEquals(res4, res6); + assertEquals(res5, res6); + + } finally { + srv.stop(); + } + + if (failure != null) + throw new Exception(failure); + + + } + private static void assertEquals(Object x, Object y) { + if (!equal(x, y)) + failed("expected " + string(x) + "; got " + string(y)); + } + + private static boolean equal(Object x, Object y) { + if (x == y) + return true; + if (x == null || y == null) + return false; + if (x.getClass().isArray()) + return Arrays.deepEquals(new Object[] {x}, new Object[] {y}); + return x.equals(y); + } + + private static String string(Object x) { + String s = Arrays.deepToString(new Object[] {x}); + return s.substring(1, s.length() - 1); + } + + + private static void failed(String why) { + failure = why; + new Throwable("FAILED: " + why).printStackTrace(System.out); + } + + public static void main(String[] args) throws Exception { + testRegister(); + } +} diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/NamespaceCreationTest.java --- a/jdk/test/javax/management/namespace/NamespaceCreationTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/NamespaceCreationTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -25,6 +25,7 @@ * @test NamespaceCreationTest.java * @summary General JMXNamespace test. * @author Daniel Fuchs + * @bug 5072476 * @run clean NamespaceCreationTest Wombat WombatMBean * @run build NamespaceCreationTest Wombat WombatMBean * @run main NamespaceCreationTest diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/NamespaceNotificationsTest.java --- a/jdk/test/javax/management/namespace/NamespaceNotificationsTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/NamespaceNotificationsTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -25,6 +25,7 @@ * * @test NamespaceNotificationsTest.java 1.12 * @summary General Namespace & Notifications test. + * @bug 5072476 * @author Daniel Fuchs * @run clean NamespaceNotificationsTest * Wombat WombatMBean JMXRemoteTargetNamespace diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/NullObjectNameTest.java --- a/jdk/test/javax/management/namespace/NullObjectNameTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/NullObjectNameTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -24,6 +24,7 @@ * @test NullObjectNameTest.java * @summary Test that null ObjectName are correctly handled in namespaces. * @author Daniel Fuchs + * @bug 5072476 * @run clean NullObjectNameTest Wombat WombatMBean * @compile -XDignore.symbol.file=true NullObjectNameTest.java * @run build NullObjectNameTest Wombat WombatMBean diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/QueryNamesTest.java --- a/jdk/test/javax/management/namespace/QueryNamesTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/QueryNamesTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -25,6 +25,7 @@ * @test QueryNamesTest.java 1.4 * @summary Test how queryNames works with Namespaces. * @author Daniel Fuchs + * @bug 5072476 * @run clean QueryNamesTest Wombat WombatMBean * @run build QueryNamesTest Wombat WombatMBean * @run main QueryNamesTest diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/RemoveNotificationListenerTest.java --- a/jdk/test/javax/management/namespace/RemoveNotificationListenerTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/RemoveNotificationListenerTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -25,6 +25,7 @@ * @test RemoveNotificationListenerTest.java 1.8 * @summary General RemoveNotificationListenerTest test. * @author Daniel Fuchs + * @bug 5072476 * @run clean RemoveNotificationListenerTest JMXRemoteTargetNamespace * @compile -XDignore.symbol.file=true JMXRemoteTargetNamespace.java * @run build RemoveNotificationListenerTest JMXRemoteTargetNamespace diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/RoutingServerProxyTest.java --- a/jdk/test/javax/management/namespace/RoutingServerProxyTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/RoutingServerProxyTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -25,6 +25,7 @@ * @test RoutingServerProxyTest.java 1.6 * @summary General RoutingServerProxyTest test. * @author Daniel Fuchs + * @bug 5072476 * @run clean RoutingServerProxyTest Wombat WombatMBean * @compile -XDignore.symbol.file=true RoutingServerProxyTest.java * @run build RoutingServerProxyTest Wombat WombatMBean diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/SerialParamProcessorTest.java --- a/jdk/test/javax/management/namespace/SerialParamProcessorTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/SerialParamProcessorTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -26,6 +26,7 @@ * @test SerialParamProcessorTest.java 1.8 * @summary General SerialParamProcessorTest test. * @author Daniel Fuchs + * @bug 5072476 * @run clean SerialParamProcessorTest Wombat WombatMBean * @compile -XDignore.symbol.file=true SerialParamProcessorTest.java * @run build SerialParamProcessorTest Wombat WombatMBean diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/SourceNamespaceTest.java --- a/jdk/test/javax/management/namespace/SourceNamespaceTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/SourceNamespaceTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -24,6 +24,7 @@ * * @test SourceNamespaceTest.java * @summary Test how queryNames works with Namespaces. + * @bug 5072476 * @author Daniel Fuchs * @run clean SourceNamespaceTest Wombat WombatMBean * @run build SourceNamespaceTest Wombat WombatMBean diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/VirtualMBeanNotifTest.java --- a/jdk/test/javax/management/namespace/VirtualMBeanNotifTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/VirtualMBeanNotifTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -25,6 +25,7 @@ * @test VirtualMBeanNotifTest.java * @bug 5108776 * @build VirtualMBeanNotifTest Wombat WombatMBean + * @run main VirtualMBeanNotifTest * @summary Test that Virtual MBeans can be implemented and emit notifs. * @author Daniel Fuchs */ diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/VirtualMBeanTest.java --- a/jdk/test/javax/management/namespace/VirtualMBeanTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/VirtualMBeanTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -23,7 +23,7 @@ /* * @test VirtualMBeanTest.java - * @bug 5108776 + * @bug 5108776 5072476 * @summary Test that Virtual MBeans can be implemented and emit notifs. * @author Eamonn McManus */ diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/VirtualNamespaceQueryTest.java --- a/jdk/test/javax/management/namespace/VirtualNamespaceQueryTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/VirtualNamespaceQueryTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -26,6 +26,7 @@ * @test VirtualNamespaceQueryTest.java * @summary General VirtualNamespaceQueryTest test. * @author Daniel Fuchs + * @bug 5072476 * @run clean VirtualNamespaceQueryTest Wombat WombatMBean * NamespaceController NamespaceControllerMBean * JMXRemoteTargetNamespace diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/VirtualPropsTest.java --- a/jdk/test/javax/management/namespace/VirtualPropsTest.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/VirtualPropsTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -23,7 +23,7 @@ /* * @test - * @bug 5108776 + * @bug 5108776 5072476 * @summary Test the properties use case for Virtual MBeans that is documented * in MBeanServerSupport. * @author Eamonn McManus diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/namespace/Wombat.java --- a/jdk/test/javax/management/namespace/Wombat.java Wed Jul 05 16:41:36 2017 +0200 +++ b/jdk/test/javax/management/namespace/Wombat.java Mon Sep 22 22:37:31 2008 -0700 @@ -68,7 +68,12 @@ } public Wombat() throws NotCompliantMBeanException { - super(WombatMBean.class); + this(WombatMBean.class); + } + + public Wombat(Class clazz) + throws NotCompliantMBeanException { + super(clazz); final Random r = new Random(); seed = ((r.nextLong() % MAX_SEED) + MAX_SEED)%MAX_SEED; period = 200 + (((r.nextLong()%80)+80)%80)*10; diff -r d718a4419361 -r b23505b07d80 jdk/test/javax/management/remote/mandatory/connection/MultiThreadDeadLockTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/javax/management/remote/mandatory/connection/MultiThreadDeadLockTest.java Mon Sep 22 22:37:31 2008 -0700 @@ -0,0 +1,256 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +import java.io.IOException; +import java.io.Serializable; +import java.net.Socket; +import java.rmi.server.RMIClientSocketFactory; +import java.util.HashMap; +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.Notification; +import javax.management.NotificationBroadcasterSupport; +import javax.management.NotificationListener; +import javax.management.ObjectName; +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; +import javax.management.remote.rmi.RMIConnectorServer; + +/* + * @test + * @bug 6697180 + * @summary test on a client notification deadlock. + * @author Shanliang JIANG + * @run clean MultiThreadDeadLockTest + * @run build MultiThreadDeadLockTest + * @run main MultiThreadDeadLockTest + */ + +public class MultiThreadDeadLockTest { + + private static long serverTimeout = 500L; + + public static void main(String[] args) throws Exception { + print("Create the MBean server"); + MBeanServer mbs = MBeanServerFactory.createMBeanServer(); + + print("Initialize environment map"); + HashMap env = new HashMap(); + + print("Specify a client socket factory to control socket creation."); + env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, + clientFactory); + + print("Specify a server idle timeout to make a server close an idle connection."); + env.put("jmx.remote.x.server.connection.timeout", serverTimeout); + + print("Disable client heartbeat."); + env.put("jmx.remote.x.client.connection.check.period", 0); + + env.put("jmx.remote.x.notification.fetch.timeout", serverTimeout); + + print("Create an RMI server"); + JMXServiceURL url = new JMXServiceURL("rmi", null, 0); + JMXConnectorServer server = + JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs); + server.start(); + + url = server.getAddress(); + + print("Create jmx client on "+url); + StateMachine.setState(CREATE_SOCKET); // allow to create client socket + client = JMXConnectorFactory.connect(url, env); + Thread.sleep(100); + + totoName = new ObjectName("default:name=toto"); + mbs.registerMBean(toto, totoName); + print("Register the mbean: " + totoName); + + print("Add listener to toto MBean"); + client.getMBeanServerConnection().addNotificationListener( + totoName, myListener, null, null); + Thread.sleep(10); + + print("send notif, listener will block the fetcher"); + toto.sendNotif(); + Thread.sleep(100); + + StateMachine.setState(NO_OP); + + print("Sleep 3 times of server idle timeout: "+serverTimeout+ + ", the sever should close the idle connection."); + Thread.sleep(serverTimeout*3); + + print("start the user thread to call mbean method, it will get IOexception" + + " and start the reconnection, the socket factory will block the" + + " socket creation."); + UserThread ut = new UserThread(); + ut.start(); + Thread.sleep(10); + + print("Free the listener, the fetcher will get IO and makes " + + "a deadlock if the bug is not fixed."); + StateMachine.setState(FREE_LISTENER); + Thread.sleep(100); + + print("Allow to create new socket for the reconnection"); + StateMachine.setState(CREATE_SOCKET); + + print("Check whether the user thread gets free to call the mbean."); + if (!ut.waitDone(5000)) { + throw new RuntimeException("Possible deadlock!"); + } + + print("Remove the listener."); + client.getMBeanServerConnection().removeNotificationListener( + totoName, myListener, null, null); + Thread.sleep(serverTimeout*3); + + print("\nWell passed, bye!"); + + client.close(); + Thread.sleep(10); + server.stop(); + } + + private static ObjectName totoName = null; + private static JMXConnector client; + + public static class UserThread extends Thread { + public UserThread() { + setDaemon(true); + } + + public void run() { + try { + client.getMBeanServerConnection().invoke( + totoName, "allowReturn", null, null); + } catch (Exception e) { + throw new Error(e); + } + + synchronized(UserThread.class) { + done = true; + UserThread.class.notify(); + } + } + + public boolean waitDone(long timeout) { + synchronized(UserThread.class) { + if(!done) { + try { + UserThread.class.wait(timeout); + } catch (Exception e) { + throw new Error(e); + } + } + } + return done; + } + + private boolean done = false; + } + + public static interface TotoMBean { + public void allowReturn(); + } + + public static class Toto extends NotificationBroadcasterSupport + implements TotoMBean { + + public void allowReturn() { + enter("allowReturn"); + + leave("allowReturn"); + } + + public void sendNotif() { + enter("sendNotif"); + + sendNotification(new Notification("Toto", totoName, 0)); + + leave("sendNotif"); + } + } + private static Toto toto = new Toto(); + + public static NotificationListener myListener = new NotificationListener() { + public void handleNotification(Notification notification, Object handback) { + enter("handleNotification"); + + StateMachine.waitState(FREE_LISTENER); + + leave("handleNotification"); + } + }; + + public static class RMIClientFactory + implements RMIClientSocketFactory, Serializable { + + public Socket createSocket(String host, int port) throws IOException { + enter("createSocket"); + //print("Calling createSocket(" + host + " " + port + ")"); + + StateMachine.waitState(CREATE_SOCKET); + Socket s = new Socket(host, port); + leave("createSocket"); + + return s; + } + } + private static RMIClientFactory clientFactory = new RMIClientFactory(); + + private static int CREATE_SOCKET = 1; + private static int FREE_LISTENER = 3; + private static int NO_OP = 0; + + public static class StateMachine { + + private static int state = NO_OP; + private static int[] lock = new int[0]; + + public static void waitState(int s) { + synchronized (lock) { + while (state != s) { + try { + lock.wait(); + } catch (InterruptedException ire) { + // should not + throw new Error(ire); + } + } + } + } + + public static int getState() { + synchronized (lock) { + return state; + } + } + + public static void setState(int s) { + synchronized (lock) { + state = s; + lock.notifyAll(); + } + } + } + + private static void print(String m) { + System.out.println(m); + } + + private static void enter(String m) { + System.out.println("\n---Enter the method " + m); + } + + private static void leave(String m) { + System.out.println("===Leave the method: " + m); + } +} +