libjava/classpath/ChangeLog.gcj:
2007-05-31 Matthias Klose <doko@ubuntu.com> * javax/management/NotificationBroadcasterSupport.java (getNotificationInfo): Add cast. * native/jni/qt-peer/Makefile.am (AM_CXXFLAGS): Add libstdc++ include directories. * native/jni/qt-peer/Makefile.in: Regenerate. libjava/ChangeLog: 2007-06-03 Matthias Klose <doko@ubuntu.com> * java/io/natFileWin32.cc (setFilePermissions): New (stub only). _access: Handle EXEC query, stub only. 2007-06-03 Matthias Klose <doko@ubuntu.com> Merged from classpath: * gnu/java/nio/SelectorProviderImpl.java: Whitespace merge. * java/lang/System.java(inheritedChannel): New. * java/lang/Character.java: Remove stray`;'. * java/net/MulticastSocket.java: Merged. * java/text/DateFormatSymbols.java(getInstance): New, comment updates. * java/text/Collator.java(getInstance): Merged. * java/util/Calendar.java: New attributes ALL_STYLES, SHORT, LONG. getDisplayName, getDisplayNames: New. * java/util/logging/Logger.java: Merged. * Regenerate .class and .h files. 2007-06-03 Matthias Klose <doko@ubuntu.com> * java/io/File.java: Merge with classpath-0.95, new method setFilePermissions, new attribute EXEC. * java/io/natFilePosix.cc (setFilePermissions): New. _access: Handle EXEC query. * classpath/lib/java/io/File.class, java/io/File.h: Regenerate. 2007-06-03 Matthias Klose <doko@ubuntu.com> Imported GNU Classpath 0.95. * classpath/Makefile.in, classpath/native/jni/midi-dssi/Makefile.in, classpath/native/jni/classpath/Makefile.in, classpath/native/jni/Makefile.in, classpath/native/jni/gconf-peer/Makefile.in, classpath/native/jni/java-io/Makefile.in, classpath/native/jni/native-lib/Makefile.in, classpath/native/jni/java-util/Makefile.in, classpath/native/jni/midi-alsa/Makefile.in, classpath/native/jni/java-lang/Makefile.in, classpath/native/jni/java-nio/Makefile.in, classpath/native/jni/java-net/Makefile.in, classpath/native/jni/xmlj/Makefile.in, classpath/native/jni/qt-peer/Makefile.in, classpath/native/jni/gtk-peer/Makefile.in, classpath/native/Makefile.in, classpath/native/jawt/Makefile.in, classpath/native/fdlibm/Makefile.in, classpath/native/plugin/Makefile.in, classpath/resource/Makefile.in, classpath/scripts/Makefile.in, classpath/tools/Makefile.in, classpath/doc/Makefile.in, classpath/doc/api/Makefile.in, classpath/lib/Makefile.in, classpath/external/Makefile.in, classpath/external/jsr166/Makefile.in, classpath/external/sax/Makefile.in, classpath/external/w3c_dom/Makefile.in, classpath/external/relaxngDatatype/Makefile.in, classpath/include/Makefile.in, classpath/examples/Makefile.in: Regenerate. * classpath/config.guess, classpath/config.sub, classpath/ltmain.sh : Update. * classpath/configure, classpath/depcomp, classpath/missing, classpath/aclocal.m4, classpath/install-sh: Regenerate. * gnu/classpath/Configuration.java (CLASSPATH_VERSION): Now 0.95. * sources.am: Regenerate. * Makefile.in: Regenerate. * Update the .class files and generated CNI header files, add new .class and generated CNI header files. * Remove generated files for removed java source files: classpath/gnu/java/net/BASE64.java, classpath/gnu/java/security/util/Base64.java, classpath/gnu/java/awt/peer/gtk/GThreadMutex.java, classpath/gnu/java/awt/peer/gtk/GThreadNativeMethodRunner.java, classpath/gnu/java/awt/font/autofit/Scaler.java, classpath/gnu/classpath/jdwp/util/Value.java, classpath/gnu/javax/net/ssl/Base64.java. * Remove empty directories. * Makefile.am(nat_source_files): Add natVMOperatingSystemMXBeanImpl.cc. * java/lang/Class.java(setAccessible): Merge from classpath. * java/util/Locale.java: Remove. * gnu/java/lang/management/VMOperatingSystemMXBeanImpl.java, gnu/java/lang/management/natVMOperatingSystemMXBeanImpl.cc: New. * gcj/javaprims.h: Update class declarations. * scripts/classes.pl: Update usage. * HACKING: Mention to build all peers. From-SVN: r125302
This commit is contained in:
@@ -156,7 +156,7 @@ public final class Character implements Serializable, Comparable<Character>
|
||||
private final String canonicalName;
|
||||
|
||||
/** Enumeration for the <code>forName()</code> method */
|
||||
private enum NameType { CANONICAL, NO_SPACES, CONSTANT; };
|
||||
private enum NameType { CANONICAL, NO_SPACES, CONSTANT; }
|
||||
|
||||
/**
|
||||
* Constructor for strictly defined blocks.
|
||||
|
||||
@@ -45,6 +45,7 @@ import java.io.InputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.reflect.AccessibleObject;
|
||||
import java.lang.reflect.AnnotatedElement;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
@@ -1126,15 +1127,7 @@ public final class Class<T>
|
||||
if (!Modifier.isPublic(constructor.getModifiers())
|
||||
|| !Modifier.isPublic(VMClass.getModifiers(this, true)))
|
||||
{
|
||||
final Constructor finalConstructor = constructor;
|
||||
AccessController.doPrivileged(new PrivilegedAction()
|
||||
{
|
||||
public Object run()
|
||||
{
|
||||
finalConstructor.setAccessible(true);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
setAccessible(constructor);
|
||||
}
|
||||
synchronized(this)
|
||||
{
|
||||
@@ -1397,7 +1390,9 @@ public final class Class<T>
|
||||
{
|
||||
try
|
||||
{
|
||||
return (T[]) getMethod("values").invoke(null);
|
||||
Method m = getMethod("values");
|
||||
setAccessible(m);
|
||||
return (T[]) m.invoke(null);
|
||||
}
|
||||
catch (NoSuchMethodException exception)
|
||||
{
|
||||
@@ -1787,5 +1782,18 @@ public final class Class<T>
|
||||
return VMClass.isMemberClass(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Utility method for use by classes in this package.
|
||||
*/
|
||||
static void setAccessible(final AccessibleObject obj)
|
||||
{
|
||||
AccessController.doPrivileged(new PrivilegedAction()
|
||||
{
|
||||
public Object run()
|
||||
{
|
||||
obj.setAccessible(true);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,9 +97,12 @@ public abstract class Enum<T extends Enum<T>>
|
||||
|
||||
try
|
||||
{
|
||||
// XXX We should not use getDeclaredField, because it does
|
||||
// an unnecessary security check.
|
||||
Field f = etype.getDeclaredField(s);
|
||||
if (! f.isEnumConstant())
|
||||
throw new IllegalArgumentException(s);
|
||||
Class.setAccessible(f);
|
||||
return (S) f.get(null);
|
||||
}
|
||||
catch (NoSuchFieldException exception)
|
||||
@@ -220,4 +223,14 @@ public abstract class Enum<T extends Enum<T>>
|
||||
k = k.getSuperclass();
|
||||
return k;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enumerations can not have finalization methods.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
protected final void finalize()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2278,8 +2278,9 @@ public final strictfp class StrictMath
|
||||
j |= iq[i];
|
||||
if (j == 0) // Need recomputation.
|
||||
{
|
||||
int k;
|
||||
for (k = 1; iq[jk - k] == 0; k++); // k = no. of terms needed.
|
||||
int k; // k = no. of terms needed.
|
||||
for (k = 1; iq[jk - k] == 0; k++)
|
||||
;
|
||||
|
||||
for (i = jz + 1; i <= jz + k; i++) // Add q[jz+1] to q[jz+k].
|
||||
{
|
||||
|
||||
@@ -1592,8 +1592,10 @@ public final class String
|
||||
if (begin == limit)
|
||||
return "";
|
||||
while (value[begin++] <= '\u0020');
|
||||
|
||||
int end = limit;
|
||||
while (value[--end] <= '\u0020');
|
||||
while (value[--end] <= '\u0020')
|
||||
;
|
||||
return substring(begin - offset - 1, end - offset + 1);
|
||||
}
|
||||
|
||||
@@ -1988,4 +1990,17 @@ public final class String
|
||||
return Character.offsetByCodePoints(value, offset, count, offset + index,
|
||||
codePointOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if, and only if, {@link #length()}
|
||||
* is <code>0</code>.
|
||||
*
|
||||
* @return true if the length of the string is zero.
|
||||
* @since 1.6
|
||||
*/
|
||||
public boolean isEmpty()
|
||||
{
|
||||
return count == 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* System.java -- useful methods to interface with the system
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
|
||||
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
@@ -42,8 +42,11 @@ package java.lang;
|
||||
import gnu.classpath.SystemProperties;
|
||||
import gnu.classpath.VMStackWalker;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.nio.channels.Channel;
|
||||
import java.nio.channels.spi.SelectorProvider;
|
||||
import java.util.AbstractCollection;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
@@ -362,6 +365,7 @@ public final class System
|
||||
* <dt>gnu.java.io.encoding_scheme_alias.iso-latin-_?</dt> <dd>8859_?</dd>
|
||||
* <dt>gnu.java.io.encoding_scheme_alias.latin?</dt> <dd>8859_?</dd>
|
||||
* <dt>gnu.java.io.encoding_scheme_alias.utf-8</dt> <dd>UTF8</dd>
|
||||
* <dt>gnu.java.util.zoneinfo.dir</dt> <dd>Root of zoneinfo tree</dd>
|
||||
* <dt>gnu.javax.print.server</dt> <dd>Hostname of external CUPS server.</dd>
|
||||
* </dl>
|
||||
*
|
||||
@@ -671,6 +675,25 @@ public final class System
|
||||
return VMRuntime.mapLibraryName(libname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the inherited channel of the VM.
|
||||
*
|
||||
* This wraps the inheritedChannel() call of the system's default
|
||||
* {@link SelectorProvider}.
|
||||
*
|
||||
* @return the inherited channel of the VM
|
||||
*
|
||||
* @throws IOException If an I/O error occurs
|
||||
* @throws SecurityException If an installed security manager denies access
|
||||
* to RuntimePermission("inheritedChannel")
|
||||
*
|
||||
* @since 1.5
|
||||
*/
|
||||
public static Channel inheritedChannel()
|
||||
throws IOException
|
||||
{
|
||||
return SelectorProvider.provider().inheritedChannel();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is a specialised <code>Collection</code>, providing
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
# This property file contains dependencies of classes, methods, and
|
||||
# field on other methods or classes.
|
||||
#
|
||||
# Syntax:
|
||||
#
|
||||
# <used>: <needed 1> [... <needed N>]
|
||||
#
|
||||
# means that when <used> is included, <needed 1> (... <needed N>) must
|
||||
# be included as well.
|
||||
#
|
||||
# <needed X> and <used> are of the form
|
||||
#
|
||||
# <class.methodOrField(signature)>
|
||||
#
|
||||
# or just
|
||||
#
|
||||
# <class>
|
||||
#
|
||||
# Within dependencies, variables can be used. A variable is defined as
|
||||
# follows:
|
||||
#
|
||||
# {variable}: value1 value2 ... value<n>
|
||||
#
|
||||
# variables can be used on the right side of dependencies as follows:
|
||||
#
|
||||
# <used>: com.bla.blu.{variable}.Class.m()V
|
||||
#
|
||||
# The use of the variable will expand to <n> dependencies of the form
|
||||
#
|
||||
# <used>: com.bla.blu.value1.Class.m()V
|
||||
# <used>: com.bla.blu.value2.Class.m()V
|
||||
# ...
|
||||
# <used>: com.bla.blu.value<n>.Class.m()V
|
||||
#
|
||||
# Variables can be redefined when building a system to select the
|
||||
# required support for features like encodings, protocols, etc.
|
||||
#
|
||||
# Hints:
|
||||
#
|
||||
# - For methods and fields, the signature is mandatory. For
|
||||
# specification, please see the Java Virtual Machine Specification by
|
||||
# SUN. Unlike in the spec, field signatures (types) are in brackets.
|
||||
#
|
||||
# - Package names must be separated by '/' (and not '.'). E.g.,
|
||||
# java/lang/Class (this is necessary, because the '.' is used to
|
||||
# separate method or field names from classes)
|
||||
#
|
||||
# - In case <needed> refers to a class, only the class itself will be
|
||||
# included in the resulting binary, NOT necessarily all its methods
|
||||
# and fields. If you want to refer to all methods and fields, you can
|
||||
# write class.* as an abbreviation.
|
||||
#
|
||||
# - Abbreviations for packages are also possible: my/package/* means all
|
||||
# methods and fields of all classes in my/package.
|
||||
#
|
||||
# - A line with a trailing '\' continues in the next line.
|
||||
|
||||
# end of file
|
||||
@@ -0,0 +1,114 @@
|
||||
/* LockInfo.java - Information on a lock.
|
||||
Copyright (C) 2006 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.lang.management;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
|
||||
/**
|
||||
* Provides information on a lock held by a thread.
|
||||
* A lock can be either a built-in monitor, an
|
||||
* <emph>ownable synchronizer</emph> (i.e. a subclass
|
||||
* of {@link java.util.concurrent.locks.AbstractOwnableSynchronizer}),
|
||||
* or a {@link java.util.concurrent.locks.Condition}
|
||||
* object.
|
||||
*
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
* @since 1.6
|
||||
*/
|
||||
public class LockInfo
|
||||
{
|
||||
|
||||
/**
|
||||
* The class name of the lock object.
|
||||
*/
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* The identity hash code of the lock object.
|
||||
*/
|
||||
private int identityHashCode;
|
||||
|
||||
/**
|
||||
* Constructs a new {@link LockInfo} object with the
|
||||
* specified class name and identity hash code.
|
||||
*
|
||||
* @param className the name of the class of the lock object.
|
||||
* @param identityHashCode the identity hash code of the
|
||||
* lock object.
|
||||
*/
|
||||
@ConstructorProperties({"className","identityHashCode"})
|
||||
public LockInfo(String className, int identityHashCode)
|
||||
{
|
||||
this.className = className;
|
||||
this.identityHashCode = identityHashCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class name of the lock object.
|
||||
*
|
||||
* @return the class name of the lock object.
|
||||
*/
|
||||
public String getClassName()
|
||||
{
|
||||
return className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the identity hash code of the lock object.
|
||||
*
|
||||
* @return the identity hash code of the lock object.
|
||||
*/
|
||||
public int getIdentityHashCode()
|
||||
{
|
||||
return identityHashCode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a textual representation of the lock,
|
||||
* constructed by concatenating the class name,
|
||||
* <code>'@'</code> and the identity hash code
|
||||
* in unsigned hexadecimal form.
|
||||
*
|
||||
* @return a textual representation of the lock.
|
||||
*/
|
||||
public String toString()
|
||||
{
|
||||
return className + '@' + Integer.toHexString(identityHashCode);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -49,20 +49,36 @@ import gnu.java.lang.management.MemoryPoolMXBeanImpl;
|
||||
import gnu.java.lang.management.RuntimeMXBeanImpl;
|
||||
import gnu.java.lang.management.ThreadMXBeanImpl;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import java.util.logging.LogManager;
|
||||
|
||||
import javax.management.Attribute;
|
||||
import javax.management.InstanceAlreadyExistsException;
|
||||
import javax.management.MBeanRegistrationException;
|
||||
import javax.management.MBeanServer;
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.MBeanServerFactory;
|
||||
import javax.management.MalformedObjectNameException;
|
||||
import javax.management.NotCompliantMBeanException;
|
||||
import javax.management.NotificationEmitter;
|
||||
import javax.management.NotificationFilter;
|
||||
import javax.management.NotificationListener;
|
||||
import javax.management.ObjectName;
|
||||
|
||||
import javax.management.openmbean.CompositeData;
|
||||
import javax.management.openmbean.TabularData;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Provides access to the system's management beans via a series
|
||||
@@ -549,4 +565,253 @@ public class ManagementFactory
|
||||
return platformServer;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns a proxy for the specified platform bean. A proxy object is created
|
||||
* using <code>Proxy.newProxyInstance(mxbeanInterface.getClassLoader(),
|
||||
* new Class[] { mxbeanInterface }, handler)</code>. The
|
||||
* {@link javax.management.NotificationEmitter} class is also added to the
|
||||
* array if the bean provides notifications. <code>handler</code> refers
|
||||
* to the invocation handler which forwards calls to the connection, and
|
||||
* also provides translation between the Java data types used in the
|
||||
* bean interfaces and the open data types, as specified in the description
|
||||
* of this class. It is this translation that makes the
|
||||
* usual {@link javax.management.MBeanServerInvocationHandler} inappropriate
|
||||
* for providing such a proxy.
|
||||
* </p>
|
||||
* <p>
|
||||
* <strong>Note</strong>: use of the proxy may result in
|
||||
* {@link java.io.IOException}s from the underlying {@link MBeanServerConnection}
|
||||
* and a {@link java.io.InvalidObjectException} if enum constants
|
||||
* used on the client and the server don't match.
|
||||
* </p>
|
||||
*
|
||||
* @param connection the server connection to use to access the bean.
|
||||
* @param mxbeanName the {@link javax.management.ObjectName} of the
|
||||
* bean to provide a proxy for.
|
||||
* @param mxbeanInterface the interface for the bean being proxied.
|
||||
* @return a proxy for the specified bean.
|
||||
* @throws IllegalArgumentException if <code>mxbeanName</code> is not a valid
|
||||
* {@link javax.management.ObjectName},
|
||||
* the interface and name do not match the
|
||||
* same bean, the name does not refer to a
|
||||
* platform bean or the bean is not registered
|
||||
* with the server accessed by <code>connection</code>.
|
||||
* @throws IOException if the connection throws one.
|
||||
*/
|
||||
public static <T> T newPlatformMXBeanProxy(MBeanServerConnection connection,
|
||||
String mxbeanName,
|
||||
Class<T> mxbeanInterface)
|
||||
throws IOException
|
||||
{
|
||||
if (!(mxbeanName.equals(CLASS_LOADING_MXBEAN_NAME) ||
|
||||
mxbeanName.equals(COMPILATION_MXBEAN_NAME) ||
|
||||
mxbeanName.startsWith(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE) ||
|
||||
mxbeanName.startsWith(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE) ||
|
||||
mxbeanName.equals(MEMORY_MXBEAN_NAME) ||
|
||||
mxbeanName.startsWith(MEMORY_POOL_MXBEAN_DOMAIN_TYPE) ||
|
||||
mxbeanName.equals(OPERATING_SYSTEM_MXBEAN_NAME) ||
|
||||
mxbeanName.equals(RUNTIME_MXBEAN_NAME) ||
|
||||
mxbeanName.equals(THREAD_MXBEAN_NAME)))
|
||||
{
|
||||
throw new IllegalArgumentException("The named bean, " + mxbeanName +
|
||||
", is not a platform name.");
|
||||
}
|
||||
if ((mxbeanName.equals(CLASS_LOADING_MXBEAN_NAME) &&
|
||||
mxbeanInterface != ClassLoadingMXBean.class) ||
|
||||
(mxbeanName.equals(COMPILATION_MXBEAN_NAME) &&
|
||||
mxbeanInterface != CompilationMXBean.class) ||
|
||||
(mxbeanName.startsWith(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE) &&
|
||||
mxbeanInterface != GarbageCollectorMXBean.class) ||
|
||||
(mxbeanName.startsWith(MEMORY_MANAGER_MXBEAN_DOMAIN_TYPE) &&
|
||||
mxbeanInterface != MemoryManagerMXBean.class) ||
|
||||
(mxbeanName.equals(MEMORY_MXBEAN_NAME) &&
|
||||
mxbeanInterface != MemoryMXBean.class) ||
|
||||
(mxbeanName.startsWith(MEMORY_POOL_MXBEAN_DOMAIN_TYPE) &&
|
||||
mxbeanInterface != MemoryPoolMXBean.class) ||
|
||||
(mxbeanName.equals(OPERATING_SYSTEM_MXBEAN_NAME) &&
|
||||
mxbeanInterface != OperatingSystemMXBean.class) ||
|
||||
(mxbeanName.equals(RUNTIME_MXBEAN_NAME) &&
|
||||
mxbeanInterface != RuntimeMXBean.class) ||
|
||||
(mxbeanName.equals(THREAD_MXBEAN_NAME) &&
|
||||
mxbeanInterface != ThreadMXBean.class))
|
||||
throw new IllegalArgumentException("The interface, " + mxbeanInterface +
|
||||
", does not match the bean, " + mxbeanName);
|
||||
ObjectName bean;
|
||||
try
|
||||
{
|
||||
bean = new ObjectName(mxbeanName);
|
||||
}
|
||||
catch (MalformedObjectNameException e)
|
||||
{
|
||||
throw new IllegalArgumentException("The named bean is invalid.");
|
||||
}
|
||||
if (!(connection.isRegistered(bean)))
|
||||
throw new IllegalArgumentException("The bean is not registered on this connection.");
|
||||
Class[] interfaces;
|
||||
if (mxbeanName.equals(MEMORY_MXBEAN_NAME))
|
||||
interfaces = new Class[] { mxbeanInterface, NotificationEmitter.class };
|
||||
else
|
||||
interfaces = new Class[] { mxbeanInterface };
|
||||
return (T) Proxy.newProxyInstance(mxbeanInterface.getClassLoader(),
|
||||
interfaces,
|
||||
new ManagementInvocationHandler(connection, bean));
|
||||
}
|
||||
|
||||
/**
|
||||
* This invocation handler provides method calls for a platform bean
|
||||
* by forwarding them to a {@link MBeanServerConnection}. Translation from
|
||||
* Java data types to open data types is performed as specified above.
|
||||
*
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
* @since 1.5
|
||||
*/
|
||||
private static class ManagementInvocationHandler
|
||||
implements InvocationHandler
|
||||
{
|
||||
|
||||
/**
|
||||
* The encapsulated connection.
|
||||
*/
|
||||
private MBeanServerConnection conn;
|
||||
|
||||
/**
|
||||
* The bean being proxied.
|
||||
*/
|
||||
private ObjectName bean;
|
||||
|
||||
/**
|
||||
* Constructs a new {@link InvocationHandler} which proxies
|
||||
* for the specified bean using the supplied connection.
|
||||
*
|
||||
* @param conn the connection on which to forward method calls.
|
||||
* @param bean the bean to proxy.
|
||||
*/
|
||||
public ManagementInvocationHandler(MBeanServerConnection conn,
|
||||
ObjectName bean)
|
||||
throws IOException
|
||||
{
|
||||
this.conn = conn;
|
||||
this.bean = bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the proxy class whenever a method is called. The method
|
||||
* is emulated by retrieving an attribute from, setting an attribute on
|
||||
* or invoking a method on the server connection as required. Translation
|
||||
* between the Java data types supplied as arguments to the open types used
|
||||
* by the bean is provided, as well as translation of the return value back
|
||||
* in to the appropriate Java type.
|
||||
*
|
||||
* @param proxy the proxy on which the method was called.
|
||||
* @param method the method which was called.
|
||||
* @param args the arguments supplied to the method.
|
||||
* @return the return value from the method.
|
||||
* @throws Throwable if an exception is thrown in performing the
|
||||
* method emulation.
|
||||
*/
|
||||
public Object invoke(Object proxy, Method method, Object[] args)
|
||||
throws Throwable
|
||||
{
|
||||
String name = method.getName();
|
||||
if (name.equals("toString"))
|
||||
return "Proxy for " + bean + " using " + conn;
|
||||
if (name.equals("addNotificationListener"))
|
||||
{
|
||||
conn.addNotificationListener(bean,
|
||||
(NotificationListener) args[0],
|
||||
(NotificationFilter) args[1],
|
||||
args[2]);
|
||||
return null;
|
||||
}
|
||||
if (name.equals("getNotificationInfo"))
|
||||
return conn.getMBeanInfo(bean).getNotifications();
|
||||
if (name.equals("removeNotificationListener"))
|
||||
{
|
||||
if (args.length == 1)
|
||||
conn.removeNotificationListener(bean,
|
||||
(NotificationListener)
|
||||
args[0]);
|
||||
else
|
||||
conn.removeNotificationListener(bean,
|
||||
(NotificationListener)
|
||||
args[0],
|
||||
(NotificationFilter)
|
||||
args[1], args[2]);
|
||||
return null;
|
||||
}
|
||||
String attrib = null;
|
||||
if (name.startsWith("get"))
|
||||
attrib = name.substring(3);
|
||||
else if (name.startsWith("is"))
|
||||
attrib = name.substring(2);
|
||||
if (attrib != null)
|
||||
return translate(conn.getAttribute(bean, attrib), method);
|
||||
else if (name.startsWith("set"))
|
||||
{
|
||||
conn.setAttribute(bean, new Attribute(name.substring(3),
|
||||
args[0]));
|
||||
return null;
|
||||
}
|
||||
else
|
||||
return translate(conn.invoke(bean, name, args, null), method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Translates the returned open data type to the value
|
||||
* required by the interface.
|
||||
*
|
||||
* @param otype the open type returned by the method call.
|
||||
* @param method the method that was called.
|
||||
* @return the equivalent return type required by the interface.
|
||||
* @throws Throwable if an exception is thrown in performing the
|
||||
* conversion.
|
||||
*/
|
||||
private final Object translate(Object otype, Method method)
|
||||
throws Throwable
|
||||
{
|
||||
Class<?> returnType = method.getReturnType();
|
||||
if (returnType.isEnum())
|
||||
{
|
||||
String ename = (String) otype;
|
||||
Enum[] constants = (Enum[]) returnType.getEnumConstants();
|
||||
for (Enum c : constants)
|
||||
if (c.name().equals(ename))
|
||||
return c;
|
||||
}
|
||||
if (List.class.isAssignableFrom(returnType))
|
||||
{
|
||||
Object[] elems = (Object[]) otype;
|
||||
List l = new ArrayList(elems.length);
|
||||
for (Object elem : elems)
|
||||
l.add(elem);
|
||||
return l;
|
||||
}
|
||||
if (Map.class.isAssignableFrom(returnType))
|
||||
{
|
||||
TabularData data = (TabularData) otype;
|
||||
Map m = new HashMap(data.size());
|
||||
for (Object val : data.values())
|
||||
{
|
||||
CompositeData vals = (CompositeData) val;
|
||||
m.put(vals.get("key"), vals.get("value"));
|
||||
}
|
||||
return m;
|
||||
}
|
||||
try
|
||||
{
|
||||
Method m = returnType.getMethod("from",
|
||||
new Class[]
|
||||
{ CompositeData.class });
|
||||
return m.invoke(null, (CompositeData) otype);
|
||||
}
|
||||
catch (NoSuchMethodException e)
|
||||
{
|
||||
/* Ignored; we expect this if this
|
||||
isn't a from(CompositeData) class */
|
||||
}
|
||||
return otype;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,14 +180,14 @@ public class MemoryUsage
|
||||
if (data == null)
|
||||
return null;
|
||||
CompositeType type = data.getCompositeType();
|
||||
ThreadInfo.checkAttribute(type, "init", SimpleType.LONG);
|
||||
ThreadInfo.checkAttribute(type, "used", SimpleType.LONG);
|
||||
ThreadInfo.checkAttribute(type, "committed", SimpleType.LONG);
|
||||
ThreadInfo.checkAttribute(type, "max", SimpleType.LONG);
|
||||
return new MemoryUsage(((Long) data.get("init")).longValue(),
|
||||
((Long) data.get("used")).longValue(),
|
||||
((Long) data.get("committed")).longValue(),
|
||||
((Long) data.get("max")).longValue());
|
||||
ThreadInfo.checkAttribute(type, "Init", SimpleType.LONG);
|
||||
ThreadInfo.checkAttribute(type, "Used", SimpleType.LONG);
|
||||
ThreadInfo.checkAttribute(type, "Committed", SimpleType.LONG);
|
||||
ThreadInfo.checkAttribute(type, "Max", SimpleType.LONG);
|
||||
return new MemoryUsage(((Long) data.get("Init")).longValue(),
|
||||
((Long) data.get("Used")).longValue(),
|
||||
((Long) data.get("Committed")).longValue(),
|
||||
((Long) data.get("Max")).longValue());
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,179 @@
|
||||
/* MonitorInfo.java - Information on a monitor lock.
|
||||
Copyright (C) 2006 Free Software Foundation
|
||||
|
||||
This file is part of GNU Classpath.
|
||||
|
||||
GNU Classpath is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
GNU Classpath 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 for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Classpath; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||||
02110-1301 USA.
|
||||
|
||||
Linking this library statically or dynamically with other modules is
|
||||
making a combined work based on this library. Thus, the terms and
|
||||
conditions of the GNU General Public License cover the whole
|
||||
combination.
|
||||
|
||||
As a special exception, the copyright holders of this library give you
|
||||
permission to link this library with independent modules to produce an
|
||||
executable, regardless of the license terms of these independent
|
||||
modules, and to copy and distribute the resulting executable under
|
||||
terms of your choice, provided that you also meet, for each linked
|
||||
independent module, the terms and conditions of the license of that
|
||||
module. An independent module is a module which is not derived from
|
||||
or based on this library. If you modify this library, you may extend
|
||||
this exception to your version of the library, but you are not
|
||||
obligated to do so. If you do not wish to do so, delete this
|
||||
exception statement from your version. */
|
||||
|
||||
package java.lang.management;
|
||||
|
||||
import javax.management.openmbean.CompositeData;
|
||||
import javax.management.openmbean.CompositeType;
|
||||
import javax.management.openmbean.SimpleType;
|
||||
|
||||
/**
|
||||
* Provides information on a monitor lock held by a thread.
|
||||
* A monitor lock is obtained when a thread enters a synchronized
|
||||
* block or method.
|
||||
*
|
||||
* @author Andrew John Hughes (gnu_andrew@member.fsf.org)
|
||||
* @since 1.6
|
||||
*/
|
||||
public class MonitorInfo
|
||||
extends LockInfo
|
||||
{
|
||||
|
||||
/**
|
||||
* The stack depth at which the lock was obtained.
|
||||
*/
|
||||
private int stackDepth;
|
||||
|
||||
/**
|
||||
* The stack frame at which the lock was obtained.
|
||||
*/
|
||||
private StackTraceElement stackFrame;
|
||||
|
||||
/**
|
||||
* Constructs a new {@link MonitorInfo} using the specified
|
||||
* lock class name and identity hash code, and the given
|
||||
* stack depth and frame.
|
||||
*
|
||||
* @param className the class name of the lock object.
|
||||
* @param identityHashCode the identity hash code of the lock object.
|
||||
* @param stackDepth the depth of the stack at which the lock
|
||||
* was obtained.
|
||||
* @param stackFrame the frame of the stack at which the lock was
|
||||
* obtained.
|
||||
* @throws IllegalArgumentException if the stack depth and frame are
|
||||
* inconsistent i.e. the frame is
|
||||
* <code>null</code> but the depth is
|
||||
* ≥ 0, or the frame is not
|
||||
* <code>null</code> but the depth is
|
||||
* < 0.
|
||||
*/
|
||||
public MonitorInfo(String className, int identityHashCode, int stackDepth,
|
||||
StackTraceElement stackFrame)
|
||||
{
|
||||
super(className, identityHashCode);
|
||||
if (stackFrame == null && stackDepth >= 0)
|
||||
throw new IllegalArgumentException("The stack frame is null, but the " +
|
||||
"stack depth is greater than or equal " +
|
||||
"to zero.");
|
||||
if (stackFrame != null && stackDepth < 0)
|
||||
throw new IllegalArgumentException("The stack frame is not null, but the " +
|
||||
"stack depth is less than zero.");
|
||||
this.stackDepth = stackDepth;
|
||||
this.stackFrame = stackFrame;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns a {@link MonitorInfo} instance using the values
|
||||
* given in the supplied
|
||||
* {@link javax.management.openmbean.CompositeData} object.
|
||||
* The composite data instance should contain the following
|
||||
* attributes with the specified types:
|
||||
* </p>
|
||||
* <table>
|
||||
* <th><td>Name</td><td>Type</td></th>
|
||||
* <tr><td>className</td><td>java.lang.String</td></tr>
|
||||
* <tr><td>identityHashCode</td><td>java.lang.Integer</td></tr>
|
||||
* <tr><td>lockedStackDepth</td><td>java.lang.Integer</td></tr>
|
||||
* <tr><td>lockedStackFrame</td><td>javax.management.openmbean.CompositeData
|
||||
* </td></tr>
|
||||
* </table>
|
||||
* <p>
|
||||
* The stack trace is further described as:
|
||||
* </p>
|
||||
* <table>
|
||||
* <th><td>Name</td><td>Type</td></th>
|
||||
* <tr><td>className</td><td>java.lang.String</td></tr>
|
||||
* <tr><td>methodName</td><td>java.lang.String</td></tr>
|
||||
* <tr><td>fileName</td><td>java.lang.String</td></tr>
|
||||
* <tr><td>lineNumber</td><td>java.lang.Integer</td></tr>
|
||||
* <tr><td>nativeMethod</td><td>java.lang.Boolean</td></tr>
|
||||
* </table>
|
||||
*
|
||||
* @param data the composite data structure to take values from.
|
||||
* @return a new instance containing the values from the
|
||||
* composite data structure, or <code>null</code>
|
||||
* if the data structure was also <code>null</code>.
|
||||
* @throws IllegalArgumentException if the composite data structure
|
||||
* does not match the structure
|
||||
* outlined above.
|
||||
*/
|
||||
public static MonitorInfo from(CompositeData data)
|
||||
{
|
||||
if (data == null)
|
||||
return null;
|
||||
CompositeType type = data.getCompositeType();
|
||||
ThreadInfo.checkAttribute(type, "ClassName", SimpleType.STRING);
|
||||
ThreadInfo.checkAttribute(type, "IdentityHashCode", SimpleType.INTEGER);
|
||||
ThreadInfo.checkAttribute(type, "LockedStackDepth", SimpleType.INTEGER);
|
||||
ThreadInfo.checkAttribute(type, "LockedStackFrame",
|
||||
ThreadInfo.getStackTraceType());
|
||||
CompositeData frame = (CompositeData) data.get("LockedStackFrame");
|
||||
return new MonitorInfo((String) data.get("ClassName"),
|
||||
(Integer) data.get("IdentityHashCode"),
|
||||
(Integer) data.get("LockedStackDepth"),
|
||||
new StackTraceElement((String) frame.get("ClassName"),
|
||||
(String) frame.get("MethodName"),
|
||||
(String) frame.get("FileName"),
|
||||
(Integer) frame.get("LineNumber")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the depth of the stack at which the lock was obtained.
|
||||
* This works as an index into the array returned by
|
||||
* {@link ThreadInfo#getStackTrace()}.
|
||||
*
|
||||
* @return the depth of the stack at which the lock was obtained,
|
||||
* or a negative number if this information is unavailable.
|
||||
*/
|
||||
public int getLockedStackDepth()
|
||||
{
|
||||
return stackDepth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the stack frame at which the lock was obtained.
|
||||
*
|
||||
* @return the stack frame at which the lock was obtained,
|
||||
* or <code>null</code> if this informati0on is unavailable.
|
||||
*/
|
||||
public StackTraceElement getLockedStackFrame()
|
||||
{
|
||||
return stackFrame;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -86,6 +86,22 @@ public interface OperatingSystemMXBean
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Returns the system load average for the last minute, or -1
|
||||
* if this is unavailable. The availability and calculation
|
||||
* of the load average is system-dependent, but is usually
|
||||
* a damped time-dependent average obtained by monitoring the
|
||||
* number of queued and running processes. It is expected
|
||||
* that this method will be called frequently to monitor the
|
||||
* average over time, so it may not be implemented on systems
|
||||
* where such a call is expensive.
|
||||
*
|
||||
* @return the system load average for the last minute, or -1
|
||||
* if this is unavailable.
|
||||
* @since 1.6
|
||||
*/
|
||||
double getSystemLoadAverage();
|
||||
|
||||
/**
|
||||
* Returns the version of the underlying operating system. This
|
||||
* is equivalent to obtaining the <code>os.version</code> property
|
||||
|
||||
@@ -37,6 +37,8 @@ exception statement from your version. */
|
||||
|
||||
package java.lang.management;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.management.openmbean.ArrayType;
|
||||
import javax.management.openmbean.CompositeData;
|
||||
import javax.management.openmbean.CompositeType;
|
||||
@@ -68,6 +70,8 @@ import javax.management.openmbean.SimpleType;
|
||||
* monitor, upon which the thread described here is blocked.</li>
|
||||
* <li>The stack trace of the thread (if requested on creation
|
||||
* of this object</li>
|
||||
* <li>The current locks held on object monitors by the thread.</li>
|
||||
* <li>The current locks held on ownable synchronizers by the thread.</li>
|
||||
* </ul>
|
||||
* <li><strong>Synchronization Statistics</strong>
|
||||
* <ul>
|
||||
@@ -164,11 +168,28 @@ public class ThreadInfo
|
||||
*/
|
||||
private StackTraceElement[] trace;
|
||||
|
||||
/**
|
||||
* The array of information on monitors locked by the thread.
|
||||
*/
|
||||
private MonitorInfo[] lockedMonitors;
|
||||
|
||||
/**
|
||||
* The array of information on ownable synchronizers locked
|
||||
* by the thread.
|
||||
*/
|
||||
private LockInfo[] lockedSynchronizers;
|
||||
|
||||
/**
|
||||
* Cache a local reference to the thread management bean.
|
||||
*/
|
||||
private static ThreadMXBean bean = null;
|
||||
|
||||
/**
|
||||
* Cache the {@link javax.management.openmbean.CompositeType}
|
||||
* for the {@link StackTraceElement}.
|
||||
*/
|
||||
private static CompositeType seType;
|
||||
|
||||
/**
|
||||
* Constructs a new {@link ThreadInfo} corresponding
|
||||
* to the thread specified.
|
||||
@@ -199,6 +220,50 @@ public class ThreadInfo
|
||||
Object lock, Thread lockOwner, long waitedCount,
|
||||
long waitedTime, boolean isInNative, boolean isSuspended,
|
||||
StackTraceElement[] trace)
|
||||
{
|
||||
this(thread, blockedCount, blockedTime, lock, lockOwner, waitedCount,
|
||||
waitedTime, isInNative, isSuspended, trace, new MonitorInfo[]{},
|
||||
new LockInfo[]{});
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link ThreadInfo} corresponding
|
||||
* to the thread specified.
|
||||
*
|
||||
* @param thread the thread on which the new instance
|
||||
* will be based.
|
||||
* @param blockedCount the number of times the thread
|
||||
* has been blocked.
|
||||
* @param blockedTime the accumulated number of milliseconds
|
||||
* the specified thread has been blocked
|
||||
* (only used with contention monitoring enabled)
|
||||
* @param lock the monitor lock the thread is waiting for
|
||||
* (only used if blocked)
|
||||
* @param lockOwner the thread which owns the monitor lock, or
|
||||
* <code>null</code> if it doesn't have an owner
|
||||
* (only used if blocked)
|
||||
* @param waitedCount the number of times the thread has been in a
|
||||
* waiting state.
|
||||
* @param waitedTime the accumulated number of milliseconds the
|
||||
* specified thread has been waiting
|
||||
* (only used with contention monitoring enabled)
|
||||
* @param isInNative true if the thread is in a native method.
|
||||
* @param isSuspended true if the thread is suspended.
|
||||
* @param trace the stack trace of the thread to a pre-determined
|
||||
* depth (see VMThreadMXBeanImpl)
|
||||
* @param lockedMonitors an array of {@link MonitorInfo} objects
|
||||
* representing locks held on object monitors
|
||||
* by the thread.
|
||||
* @param lockedSynchronizers an array of {@link LockInfo} objects
|
||||
* representing locks held on ownable
|
||||
* synchronizers by the thread.
|
||||
* @since 1.6
|
||||
*/
|
||||
private ThreadInfo(Thread thread, long blockedCount, long blockedTime,
|
||||
Object lock, Thread lockOwner, long waitedCount,
|
||||
long waitedTime, boolean isInNative, boolean isSuspended,
|
||||
StackTraceElement[] trace, MonitorInfo[] lockedMonitors,
|
||||
LockInfo[] lockedSynchronizers)
|
||||
{
|
||||
this(thread.getId(), thread.getName(), thread.getState(), blockedCount, blockedTime,
|
||||
lock == null ? null : lock.getClass().getName() + "@" +
|
||||
@@ -206,7 +271,7 @@ public class ThreadInfo
|
||||
lockOwner == null ? -1 : lockOwner.getId(),
|
||||
lockOwner == null ? null : lockOwner.getName(),
|
||||
waitedCount, waitedTime, isInNative, isSuspended,
|
||||
trace);
|
||||
trace, lockedMonitors, lockedSynchronizers);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -247,6 +312,59 @@ public class ThreadInfo
|
||||
long lockOwnerId, String lockOwnerName, long waitedCount,
|
||||
long waitedTime, boolean isInNative, boolean isSuspended,
|
||||
StackTraceElement[] trace)
|
||||
{
|
||||
this(threadId, threadName, threadState, blockedCount, blockedTime,
|
||||
lockName, lockOwnerId, lockOwnerName, waitedCount, waitedTime,
|
||||
isInNative, isSuspended, trace, new MonitorInfo[]{}, new LockInfo[]{});
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@link ThreadInfo} corresponding
|
||||
* to the thread details specified.
|
||||
*
|
||||
* @param threadId the id of the thread on which this
|
||||
* new instance will be based.
|
||||
* @param threadName the name of the thread on which
|
||||
* this new instance will be based.
|
||||
* @param threadState the state of the thread on which
|
||||
* this new instance will be based.
|
||||
* @param blockedCount the number of times the thread
|
||||
* has been blocked.
|
||||
* @param blockedTime the accumulated number of milliseconds
|
||||
* the specified thread has been blocked
|
||||
* (only used with contention monitoring enabled)
|
||||
* @param lockName the name of the monitor lock the thread is waiting for
|
||||
* (only used if blocked)
|
||||
* @param lockOwnerId the id of the thread which owns the monitor
|
||||
* lock, or <code>-1</code> if it doesn't have an owner
|
||||
* (only used if blocked)
|
||||
* @param lockOwnerName the name of the thread which owns the monitor
|
||||
* lock, or <code>null</code> if it doesn't have an
|
||||
* owner (only used if blocked)
|
||||
* @param waitedCount the number of times the thread has been in a
|
||||
* waiting state.
|
||||
* @param waitedTime the accumulated number of milliseconds the
|
||||
* specified thread has been waiting
|
||||
* (only used with contention monitoring enabled)
|
||||
* @param isInNative true if the thread is in a native method.
|
||||
* @param isSuspended true if the thread is suspended.
|
||||
* @param trace the stack trace of the thread to a pre-determined
|
||||
* depth (see VMThreadMXBeanImpl)
|
||||
* @param lockedMonitors an array of {@link MonitorInfo} objects
|
||||
* representing locks held on object monitors
|
||||
* by the thread.
|
||||
* @param lockedSynchronizers an array of {@link LockInfo} objects
|
||||
* representing locks held on ownable
|
||||
* synchronizers by the thread.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
private ThreadInfo(long threadId, String threadName, Thread.State threadState,
|
||||
long blockedCount, long blockedTime, String lockName,
|
||||
long lockOwnerId, String lockOwnerName, long waitedCount,
|
||||
long waitedTime, boolean isInNative, boolean isSuspended,
|
||||
StackTraceElement[] trace, MonitorInfo[] lockedMonitors,
|
||||
LockInfo[] lockedSynchronizers)
|
||||
{
|
||||
this.threadId = threadId;
|
||||
this.threadName = threadName;
|
||||
@@ -261,6 +379,8 @@ public class ThreadInfo
|
||||
this.isInNative = isInNative;
|
||||
this.isSuspended = isSuspended;
|
||||
this.trace = trace;
|
||||
this.lockedMonitors = lockedMonitors;
|
||||
this.lockedSynchronizers = lockedSynchronizers;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -286,6 +406,44 @@ public class ThreadInfo
|
||||
"type " + type.getClassName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link javax.management.openmbean.CompositeType} for
|
||||
* a {@link StackTraceElement}.
|
||||
*
|
||||
* @return the type for the stack trace element.
|
||||
*/
|
||||
static CompositeType getStackTraceType()
|
||||
{
|
||||
if (seType == null)
|
||||
try
|
||||
{
|
||||
seType = new CompositeType(StackTraceElement.class.getName(),
|
||||
"An element of a stack trace",
|
||||
new String[] { "className", "methodName",
|
||||
"fileName", "lineNumber",
|
||||
"nativeMethod"
|
||||
},
|
||||
new String[] { "Name of the class",
|
||||
"Name of the method",
|
||||
"Name of the source code file",
|
||||
"Line number",
|
||||
"True if this is a native method"
|
||||
},
|
||||
new OpenType[] {
|
||||
SimpleType.STRING, SimpleType.STRING,
|
||||
SimpleType.STRING, SimpleType.INTEGER,
|
||||
SimpleType.BOOLEAN
|
||||
});
|
||||
}
|
||||
catch (OpenDataException e)
|
||||
{
|
||||
throw new IllegalStateException("Something went wrong in creating " +
|
||||
"the composite data type for the " +
|
||||
"stack trace element.", e);
|
||||
}
|
||||
return seType;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns a {@link ThreadInfo} instance using the values
|
||||
@@ -336,70 +494,133 @@ public class ThreadInfo
|
||||
if (data == null)
|
||||
return null;
|
||||
CompositeType type = data.getCompositeType();
|
||||
checkAttribute(type, "threadId", SimpleType.LONG);
|
||||
checkAttribute(type, "threadName", SimpleType.STRING);
|
||||
checkAttribute(type, "threadState", SimpleType.STRING);
|
||||
checkAttribute(type, "suspended", SimpleType.BOOLEAN);
|
||||
checkAttribute(type, "inNative", SimpleType.BOOLEAN);
|
||||
checkAttribute(type, "blockedCount", SimpleType.LONG);
|
||||
checkAttribute(type, "blockedTime", SimpleType.LONG);
|
||||
checkAttribute(type, "waitedCount", SimpleType.LONG);
|
||||
checkAttribute(type, "waitedTime", SimpleType.LONG);
|
||||
checkAttribute(type, "lockName", SimpleType.STRING);
|
||||
checkAttribute(type, "lockOwnerId", SimpleType.LONG);
|
||||
checkAttribute(type, "lockOwnerName", SimpleType.STRING);
|
||||
checkAttribute(type, "ThreadId", SimpleType.LONG);
|
||||
checkAttribute(type, "ThreadName", SimpleType.STRING);
|
||||
checkAttribute(type, "ThreadState", SimpleType.STRING);
|
||||
checkAttribute(type, "Suspended", SimpleType.BOOLEAN);
|
||||
checkAttribute(type, "InNative", SimpleType.BOOLEAN);
|
||||
checkAttribute(type, "BlockedCount", SimpleType.LONG);
|
||||
checkAttribute(type, "BlockedTime", SimpleType.LONG);
|
||||
checkAttribute(type, "WaitedCount", SimpleType.LONG);
|
||||
checkAttribute(type, "WaitedTime", SimpleType.LONG);
|
||||
checkAttribute(type, "LockName", SimpleType.STRING);
|
||||
checkAttribute(type, "LockOwnerId", SimpleType.LONG);
|
||||
checkAttribute(type, "LockOwnerName", SimpleType.STRING);
|
||||
try
|
||||
{
|
||||
CompositeType seType =
|
||||
new CompositeType(StackTraceElement.class.getName(),
|
||||
"An element of a stack trace",
|
||||
new String[] { "className", "methodName",
|
||||
"fileName", "lineNumber",
|
||||
"nativeMethod"
|
||||
},
|
||||
new String[] { "Name of the class",
|
||||
"Name of the method",
|
||||
"Name of the source code file",
|
||||
"Line number",
|
||||
"True if this is a native method"
|
||||
},
|
||||
new OpenType[] {
|
||||
SimpleType.STRING, SimpleType.STRING,
|
||||
SimpleType.STRING, SimpleType.INTEGER,
|
||||
SimpleType.BOOLEAN
|
||||
});
|
||||
checkAttribute(type, "stackTrace", new ArrayType(1, seType));
|
||||
checkAttribute(type, "StackTrace",
|
||||
new ArrayType(1, getStackTraceType()));
|
||||
}
|
||||
catch (OpenDataException e)
|
||||
{
|
||||
throw new IllegalStateException("Something went wrong in creating " +
|
||||
"the composite data type for the " +
|
||||
"stack trace element.", e);
|
||||
"the array for the stack trace element.",
|
||||
e);
|
||||
}
|
||||
CompositeData[] dTraces = (CompositeData[]) data.get("stackTrace");
|
||||
OpenType foundType = type.getType("LockedMonitors");
|
||||
if (foundType != null)
|
||||
try
|
||||
{
|
||||
CompositeType mType = new CompositeType(MonitorInfo.class.getName(),
|
||||
"Information on a object monitor lock",
|
||||
new String[] { "ClassName",
|
||||
"IdentityHashCode",
|
||||
"LockedStackDepth",
|
||||
"LockedStackFrame"
|
||||
},
|
||||
new String[] { "Name of the class",
|
||||
"Identity hash code " +
|
||||
"of the class",
|
||||
"Stack depth at time " +
|
||||
"of lock",
|
||||
"Stack frame at time " +
|
||||
"of lock",
|
||||
},
|
||||
new OpenType[] {
|
||||
SimpleType.STRING, SimpleType.INTEGER,
|
||||
SimpleType.INTEGER, getStackTraceType()
|
||||
});
|
||||
if (!(foundType.equals(new ArrayType(1, mType))))
|
||||
throw new IllegalArgumentException("Field LockedMonitors is not of " +
|
||||
"type " + mType.getClassName());
|
||||
}
|
||||
catch (OpenDataException e)
|
||||
{
|
||||
throw new IllegalStateException("Something went wrong in creating " +
|
||||
"the composite data type for the " +
|
||||
"object monitor information array.", e);
|
||||
}
|
||||
foundType = type.getType("LockedSynchronizers");
|
||||
if (foundType != null)
|
||||
try
|
||||
{
|
||||
CompositeType lType = new CompositeType(LockInfo.class.getName(),
|
||||
"Information on a lock",
|
||||
new String[] { "ClassName",
|
||||
"IdentityHashCode"
|
||||
},
|
||||
new String[] { "Name of the class",
|
||||
"Identity hash code " +
|
||||
"of the class"
|
||||
},
|
||||
new OpenType[] {
|
||||
SimpleType.STRING, SimpleType.INTEGER
|
||||
});
|
||||
if (!(foundType.equals(new ArrayType(1, lType))))
|
||||
throw new IllegalArgumentException("Field LockedSynchronizers is not of " +
|
||||
"type " + lType.getClassName());
|
||||
}
|
||||
catch (OpenDataException e)
|
||||
{
|
||||
throw new IllegalStateException("Something went wrong in creating " +
|
||||
"the composite data type for the " +
|
||||
"ownable synchronizerinformation array.", e);
|
||||
}
|
||||
CompositeData[] dTraces = (CompositeData[]) data.get("StackTrace");
|
||||
StackTraceElement[] traces = new StackTraceElement[dTraces.length];
|
||||
for (int a = 0; a < dTraces.length; ++a)
|
||||
/* FIXME: We can't use the boolean as there is no available
|
||||
constructor. */
|
||||
traces[a] =
|
||||
new StackTraceElement((String) dTraces[a].get("className"),
|
||||
(String) dTraces[a].get("methodName"),
|
||||
(String) dTraces[a].get("fileName"),
|
||||
new StackTraceElement((String) dTraces[a].get("ClassName"),
|
||||
(String) dTraces[a].get("MethodName"),
|
||||
(String) dTraces[a].get("FileName"),
|
||||
((Integer)
|
||||
dTraces[a].get("lineNumber")).intValue());
|
||||
return new ThreadInfo(((Long) data.get("threadId")).longValue(),
|
||||
(String) data.get("threadName"),
|
||||
Thread.State.valueOf((String) data.get("threadState")),
|
||||
((Long) data.get("blockedCount")).longValue(),
|
||||
((Long) data.get("blockedTime")).longValue(),
|
||||
(String) data.get("lockName"),
|
||||
((Long) data.get("lockOwnerId")).longValue(),
|
||||
(String) data.get("lockOwnerName"),
|
||||
((Long) data.get("waitedCount")).longValue(),
|
||||
((Long) data.get("waitedTime")).longValue(),
|
||||
((Boolean) data.get("inNative")).booleanValue(),
|
||||
((Boolean) data.get("suspended")).booleanValue(),
|
||||
traces);
|
||||
dTraces[a].get("LineNumber")).intValue());
|
||||
MonitorInfo[] mInfo;
|
||||
if (data.containsKey("LockedMonitors"))
|
||||
{
|
||||
CompositeData[] dmInfos = (CompositeData[]) data.get("LockedMonitors");
|
||||
mInfo = new MonitorInfo[dmInfos.length];
|
||||
for (int a = 0; a < dmInfos.length; ++a)
|
||||
mInfo[a] = MonitorInfo.from(dmInfos[a]);
|
||||
}
|
||||
else
|
||||
mInfo = new MonitorInfo[]{};
|
||||
LockInfo[] lInfo;
|
||||
if (data.containsKey("LockedSynchronizers"))
|
||||
{
|
||||
CompositeData[] dlInfos = (CompositeData[]) data.get("LockedSynchronizers");
|
||||
lInfo = new LockInfo[dlInfos.length];
|
||||
for (int a = 0; a < dlInfos.length; ++a)
|
||||
lInfo[a] = new LockInfo((String) dlInfos[a].get("ClassName"),
|
||||
(Integer) dlInfos[a].get("IdentityHashCode"));
|
||||
}
|
||||
else
|
||||
lInfo = new LockInfo[]{};
|
||||
return new ThreadInfo(((Long) data.get("ThreadId")).longValue(),
|
||||
(String) data.get("ThreadName"),
|
||||
Thread.State.valueOf((String) data.get("ThreadState")),
|
||||
((Long) data.get("BlockedCount")).longValue(),
|
||||
((Long) data.get("BlockedTime")).longValue(),
|
||||
(String) data.get("LockName"),
|
||||
((Long) data.get("LockOwnerId")).longValue(),
|
||||
(String) data.get("LockOwnerName"),
|
||||
((Long) data.get("WaitedCount")).longValue(),
|
||||
((Long) data.get("WaitedTime")).longValue(),
|
||||
((Boolean) data.get("InNative")).booleanValue(),
|
||||
((Boolean) data.get("Suspended")).booleanValue(),
|
||||
traces, mInfo, lInfo);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -458,10 +679,75 @@ public class ThreadInfo
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of {@link MonitorInfo} objects representing
|
||||
* information on the locks on object monitors held by the thread.
|
||||
* If no locks are held, or such information was not requested
|
||||
* on creating this {@link ThreadInfo} object, a zero-length
|
||||
* array will be returned.
|
||||
*
|
||||
* @return information on object monitors locked by this thread.
|
||||
*/
|
||||
public MonitorInfo[] getLockedMonitors()
|
||||
{
|
||||
return lockedMonitors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of {@link LockInfo} objects representing
|
||||
* information on the locks on ownable synchronizers held by the thread.
|
||||
* If no locks are held, or such information was not requested
|
||||
* on creating this {@link ThreadInfo} object, a zero-length
|
||||
* array will be returned.
|
||||
*
|
||||
* @return information on ownable synchronizers locked by this thread.
|
||||
*/
|
||||
public LockInfo[] getLockedSynchronizers()
|
||||
{
|
||||
return lockedSynchronizers;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns a {@link LockInfo} object representing the
|
||||
* lock on which this thread is blocked. If the thread
|
||||
* is not blocked, this method returns <code>null</code>.
|
||||
* </p>
|
||||
* <p>
|
||||
* The thread may be blocked due to one of three reasons:
|
||||
* </p>
|
||||
* <ol>
|
||||
* <li>The thread is in the <code>BLOCKED</code> state
|
||||
* waiting to acquire an object monitor in order to enter
|
||||
* a synchronized method or block.</li>
|
||||
* <li>The thread is in the <code>WAITING</code> or
|
||||
* <code>TIMED_WAITING</code> state due to a call to
|
||||
* {@link java.lang.Object#wait()}.</li>
|
||||
* <li>The thread is in the <code>WAITING</code> or
|
||||
* <code>TIMED_WAITING</code> state due to a call
|
||||
* to {@link java.util.concurrent.locks.LockSupport#park()}.
|
||||
* The lock is the return value of
|
||||
* {@link java.util.concurrent.locks.LockSupport#getBlocker()}.</li>
|
||||
* </ol>
|
||||
*
|
||||
* @return a {@link LockInfo} object representing the lock on
|
||||
* which the thread is blocked, or <code>null</code> if
|
||||
* the thread isn't blocked.
|
||||
* @since 1.6
|
||||
* @see #getLockName()
|
||||
*/
|
||||
public LockInfo getLockInfo()
|
||||
{
|
||||
String lockName = getLockName();
|
||||
int at = lockName.indexOf('@');
|
||||
return new LockInfo(lockName.substring(0, at),
|
||||
Integer.decode(lockName.substring(at + 1)));
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns a {@link java.lang.String} representation of
|
||||
* the monitor lock on which this thread is blocked. If
|
||||
* the lock on which this thread is blocked. If
|
||||
* the thread is not blocked, this method returns
|
||||
* <code>null</code>.
|
||||
* </p>
|
||||
@@ -477,7 +763,8 @@ public class ThreadInfo
|
||||
* and
|
||||
* <code>Integer.toHexString(System.identityHashCode(l))</code>.
|
||||
* The value is only unique to the extent that the identity
|
||||
* hash code is also unique.
|
||||
* hash code is also unique. The value is the same as would
|
||||
* be returned by <code>getLockInfo().toString()</code>
|
||||
* </p>
|
||||
*
|
||||
* @return a string representing the lock on which this
|
||||
@@ -486,7 +773,7 @@ public class ThreadInfo
|
||||
*/
|
||||
public String getLockName()
|
||||
{
|
||||
if (threadState != Thread.State.BLOCKED)
|
||||
if (!isThreadBlocked())
|
||||
return null;
|
||||
return lockName;
|
||||
}
|
||||
@@ -504,7 +791,7 @@ public class ThreadInfo
|
||||
*/
|
||||
public long getLockOwnerId()
|
||||
{
|
||||
if (threadState != Thread.State.BLOCKED)
|
||||
if (!isThreadBlocked())
|
||||
return -1;
|
||||
return lockOwnerId;
|
||||
}
|
||||
@@ -522,7 +809,7 @@ public class ThreadInfo
|
||||
*/
|
||||
public String getLockOwnerName()
|
||||
{
|
||||
if (threadState != Thread.State.BLOCKED)
|
||||
if (!isThreadBlocked())
|
||||
return null;
|
||||
return lockOwnerName;
|
||||
}
|
||||
@@ -697,10 +984,40 @@ public class ThreadInfo
|
||||
", waitedCount=" + waitedCount +
|
||||
", isInNative=" + isInNative +
|
||||
", isSuspended=" + isSuspended +
|
||||
(threadState == Thread.State.BLOCKED ?
|
||||
(isThreadBlocked() ?
|
||||
", lockOwnerId=" + lockOwnerId +
|
||||
", lockOwnerName=" + lockOwnerName : "") +
|
||||
", lockedMonitors=" + Arrays.toString(lockedMonitors) +
|
||||
", lockedSynchronizers=" + Arrays.toString(lockedSynchronizers) +
|
||||
"]";
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Returns true if the thread is in a blocked state.
|
||||
* The thread is regarded as blocked if:
|
||||
* </p>
|
||||
* <ol>
|
||||
* <li>The thread is in the <code>BLOCKED</code> state
|
||||
* waiting to acquire an object monitor in order to enter
|
||||
* a synchronized method or block.</li>
|
||||
* <li>The thread is in the <code>WAITING</code> or
|
||||
* <code>TIMED_WAITING</code> state due to a call to
|
||||
* {@link java.lang.Object#wait()}.</li>
|
||||
* <li>The thread is in the <code>WAITING</code> or
|
||||
* <code>TIMED_WAITING</code> state due to a call
|
||||
* to {@link java.util.concurrent.locks.LockSupport#park()}.
|
||||
* The lock is the return value of
|
||||
* {@link java.util.concurrent.locks.LockSupport#getBlocker()}.</li>
|
||||
* </ol>
|
||||
*
|
||||
* @return true if the thread is blocked.
|
||||
*/
|
||||
private boolean isThreadBlocked()
|
||||
{
|
||||
return (threadState == Thread.State.BLOCKED ||
|
||||
threadState == Thread.State.WAITING ||
|
||||
threadState == Thread.State.TIMED_WAITING);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -57,20 +57,30 @@ package java.lang.management;
|
||||
* <p>
|
||||
* This bean supports some optional behaviour, which all
|
||||
* virtual machines may not choose to implement. Specifically,
|
||||
* this includes the monitoring of the CPU time used by a
|
||||
* thread, and the monitoring of thread contention. The former
|
||||
* is further subdivided into the monitoring of either just
|
||||
* the current thread or all threads. The methods
|
||||
* this includes the monitoring of:
|
||||
* </p>
|
||||
* <ul>
|
||||
* <li>the CPU time used by a thread</li>
|
||||
* <li>thread contention</li>
|
||||
* <li>object monitor usage</li>
|
||||
* <li>ownable synchronizer usage</li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* The monitoring of CPU time is further subdivided into
|
||||
* the monitoring of either just the current thread or all
|
||||
* threads. The methods
|
||||
* {@link #isThreadCpuTimeSupported()},
|
||||
* {@link #isCurrentThreadCpuTimeSupported()} and
|
||||
* {@link #isThreadContentionMonitoringSupported()} may be
|
||||
* {@link #isCurrentThreadCpuTimeSupported()}
|
||||
* {@link #isThreadContentionMonitoringSupported()},
|
||||
* {@link #isObjectMonitorUsageSupported()} and
|
||||
* {@link #isSynchronizerUsageSupported()} may be
|
||||
* used to determine whether or not this functionality is
|
||||
* supported.
|
||||
* </p>
|
||||
* <p>
|
||||
* Furthermore, both these facilities may be disabled.
|
||||
* In fact, thread contention monitoring is disabled by
|
||||
* default, and must be explictly turned on by calling
|
||||
* Furthermore, both time and contention monitoring may be
|
||||
* disabled. In fact, thread contention monitoring is disabled
|
||||
* by default, and must be explictly turned on by calling
|
||||
* the {@link #setThreadContentionMonitoringEnabled(boolean)}
|
||||
* method.
|
||||
* </p>
|
||||
@@ -81,6 +91,70 @@ package java.lang.management;
|
||||
public interface ThreadMXBean
|
||||
{
|
||||
|
||||
/**
|
||||
* This method returns information on all live threads at the
|
||||
* time of execution (some threads may have terminated by the
|
||||
* time the method completes). This method is simply a shorthand
|
||||
* for calling {@link #getThreadInfo(long[], boolean,
|
||||
* boolean)} with the return value of {@link #getAllThreadIds()}.
|
||||
*
|
||||
* @param lockedMonitors true if the returned {@link ThreadInfo}
|
||||
* objects should contain information on
|
||||
* locked monitors.
|
||||
* @param lockedSynchronizers true if the returned {@link ThreadInfo}
|
||||
* objects should contain information
|
||||
* on locked ownable synchronizers.
|
||||
* @return an array of {@link ThreadInfo} objects for all live threads.
|
||||
* @throws SecurityException if a security manager exists and
|
||||
* denies ManagementPermission("monitor").
|
||||
* @throws UnsupportedOperationException if <code>lockedMonitors</code>
|
||||
* is true, but object monitor
|
||||
* usage monitoring is not supported
|
||||
* by the VM, or
|
||||
* <code>lockedSynchronizers</code>
|
||||
* is true, but ownable synchronizer
|
||||
* usage monitoring is not supported
|
||||
* by the VM.
|
||||
* @since 1.6
|
||||
* @see #getThreadInfo(long[], boolean, boolean)
|
||||
* @see #getAllThreadIds()
|
||||
* @see #isObjectMonitorUsageSupported()
|
||||
* @see #isSynchronizerUsageSupported()
|
||||
*/
|
||||
ThreadInfo[] dumpAllThreads(boolean lockedMonitors,
|
||||
boolean lockedSynchronizers);
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This method obtains a list of threads which are deadlocked
|
||||
* waiting to obtain monitor or ownable synchronizer ownership.
|
||||
* This is similar to the behaviour described for
|
||||
* {@link #getMonitorDeadlockedThreads()}, except this method also
|
||||
* takes in to account deadlocks involving ownable synchronizers.
|
||||
* </p>
|
||||
* <p>
|
||||
* Note that this method is not designed for controlling
|
||||
* synchronization, but for troubleshooting problems which cause such
|
||||
* deadlocks; it may be prohibitively expensive to use in normal
|
||||
* operation. If only deadlocks involving monitors are of interest,
|
||||
* then {@link #findMonitorDeadlockedThreads()} should be used in
|
||||
* preference to this method.
|
||||
* </p>
|
||||
*
|
||||
* @return an array of thread identifiers, corresponding to threads
|
||||
* which are currently in a deadlocked situation, or
|
||||
* <code>null</code> if there are no deadlocks.
|
||||
* @throws SecurityException if a security manager exists and
|
||||
* denies ManagementPermission("monitor").
|
||||
* @throws UnsupportedOperationException if the VM does not support
|
||||
* the monitoring of ownable
|
||||
* synchronizer usage.
|
||||
* @since 1.6
|
||||
* @see #findMonitorDeadlockedThreads()
|
||||
* @see #isSynchronizerUsageSupported()
|
||||
*/
|
||||
long[] findDeadlockedThreads();
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* This method obtains a list of threads which are deadlocked
|
||||
@@ -115,13 +189,17 @@ public interface ThreadMXBean
|
||||
* of A and B. Note that this method is not designed for controlling
|
||||
* synchronization, but for troubleshooting problems which cause such
|
||||
* deadlocks; it may be prohibitively expensive to use in normal
|
||||
* operation.
|
||||
* operation. This method only returns deadlocks involving monitors;
|
||||
* to include deadlocks involving ownable synchronizers,
|
||||
* {@link #findDeadlockedThreads()} should be used instead.
|
||||
* </p>
|
||||
*
|
||||
* @return an array of thread identifiers, corresponding to threads
|
||||
* which are currently in a deadlocked situation.
|
||||
* which are currently in a deadlocked situation, or
|
||||
* <code>null</code> if there are no deadlocks.
|
||||
* @throws SecurityException if a security manager exists and
|
||||
* denies ManagementPermission("monitor").
|
||||
* @see #findDeadlockedThreads()
|
||||
*/
|
||||
long[] findMonitorDeadlockedThreads();
|
||||
|
||||
@@ -284,6 +362,53 @@ public interface ThreadMXBean
|
||||
*/
|
||||
ThreadInfo[] getThreadInfo(long[] ids);
|
||||
|
||||
/**
|
||||
* Returns information on the specified threads with full
|
||||
* stack trace information and optional synchronization
|
||||
* information. If <code>lockedMonitors</code> is false,
|
||||
* or there are no locked monitors for a particular thread,
|
||||
* then the corresponding {@link ThreadInfo} object will have
|
||||
* an empty {@link MonitorInfo} array. Likewise, if
|
||||
* <code>lockedSynchronizers</code> is false, or there are
|
||||
* no locked ownable synchronizers for a particular thread,
|
||||
* then the corresponding {@link ThreadInfo} object will have
|
||||
* an empty {@link LockInfo} array. If both
|
||||
* <code>lockedMonitors</code> and <code>lockedSynchronizers</code>
|
||||
* are false, the return value is equivalent to that from
|
||||
* <code>{@link #getThreadInfo}(ids, Integer.MAX_VALUE)</code>.
|
||||
* If an identifier specifies a thread which is either non-existant
|
||||
* or not alive, then the corresponding element in the returned
|
||||
* array is <code>null</code>.
|
||||
*
|
||||
* @param ids an array of thread identifiers to return information
|
||||
* on.
|
||||
* @param lockedMonitors true if information on locked monitors
|
||||
* should be included.
|
||||
* @param lockedSynchronizers true if information on locked
|
||||
* ownable synchronizers should be included.
|
||||
* @return an array of {@link ThreadInfo} objects matching the
|
||||
* specified threads. The corresponding element is
|
||||
* <code>null</code> if the identifier specifies
|
||||
* a thread that doesn't exist or is not alive.
|
||||
* @throws IllegalArgumentException if an identifier in the array is
|
||||
* <= 0.
|
||||
* @throws SecurityException if a security manager exists and
|
||||
* denies ManagementPermission("monitor").
|
||||
* @throws UnsupportedOperationException if <code>lockedMonitors</code>
|
||||
* is true, but object monitor
|
||||
* usage monitoring is not supported
|
||||
* by the VM, or
|
||||
* <code>lockedSynchronizers</code>
|
||||
* is true, but ownable synchronizer
|
||||
* usage monitoring is not supported
|
||||
* by the VM.
|
||||
* @since 1.6
|
||||
* @see #isObjectMonitorUsageSupported()
|
||||
* @see #isSynchronizerUsageSupported()
|
||||
*/
|
||||
ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors,
|
||||
boolean lockedSynchronizers);
|
||||
|
||||
/**
|
||||
* Returns information on the specified thread with
|
||||
* stack trace information to the supplied depth. If the
|
||||
@@ -389,6 +514,26 @@ public interface ThreadMXBean
|
||||
*/
|
||||
boolean isCurrentThreadCpuTimeSupported();
|
||||
|
||||
/**
|
||||
* Returns true if the virtual machine supports the monitoring
|
||||
* of object monitor usage.
|
||||
*
|
||||
* @return true if the monitoring of object monitor usage
|
||||
* is supported by the virtual machine.
|
||||
* @since 1.6
|
||||
*/
|
||||
boolean isObjectMonitorUsageSupported();
|
||||
|
||||
/**
|
||||
* Returns true if the virtual machine supports the monitoring
|
||||
* of ownable synchronizer usage.
|
||||
*
|
||||
* @return true if the monitoring of ownable synchronizer usage
|
||||
* is supported by the virtual machine.
|
||||
* @since 1.6
|
||||
*/
|
||||
boolean isSynchronizerUsageSupported();
|
||||
|
||||
/**
|
||||
* Returns true if thread contention monitoring is currently
|
||||
* enabled.
|
||||
|
||||
Reference in New Issue
Block a user