diff --git a/jdk/make/Import.gmk b/jdk/make/Import.gmk index 9e743349437..ffe2869897f 100644 --- a/jdk/make/Import.gmk +++ b/jdk/make/Import.gmk @@ -32,11 +32,11 @@ include MakeBase.gmk # Put the libraries here. Different locations for different target OS types. ifneq ($(OPENJDK_TARGET_OS), windows) - HOTSPOT_LIB_DIR := $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR) + HOTSPOT_LIB_DIR := $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR) BASE_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base$(OPENJDK_TARGET_CPU_LIBDIR) SA_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.hotspot.agent$(OPENJDK_TARGET_CPU_LIBDIR) else - HOTSPOT_LIB_DIR := $(HOTSPOT_DIST)/jre/bin + HOTSPOT_LIB_DIR := $(HOTSPOT_DIST)/bin BASE_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/java.base SA_INSTALL_LIBRARIES_HERE := $(SUPPORT_OUTPUTDIR)/modules_libs/jdk.hotspot.agent endif @@ -80,11 +80,11 @@ SA_TARGETS := $(COPY_HOTSPOT_SA) ################################################################################ ifeq ($(OPENJDK_TARGET_OS), macosx) - JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig$(SHARED_LIBRARY_SUFFIX).dSYM) \ - $(wildcard $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) ) + JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig$(SHARED_LIBRARY_SUFFIX).dSYM) \ + $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) ) else - JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.debuginfo) \ - $(wildcard $(HOTSPOT_DIST)/jre/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) ) + JSIG_DEBUGINFO := $(strip $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.debuginfo) \ + $(wildcard $(HOTSPOT_DIST)/lib$(OPENJDK_TARGET_CPU_LIBDIR)/libjsig.diz) ) endif ifneq ($(OPENJDK_TARGET_OS), windows) diff --git a/jdk/make/lib/Lib-java.instrument.gmk b/jdk/make/lib/Lib-java.instrument.gmk index 5b668c87872..b0eb7e858db 100644 --- a/jdk/make/lib/Lib-java.instrument.gmk +++ b/jdk/make/lib/Lib-java.instrument.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,9 @@ include LibCommon.gmk +# Hook to include the corresponding custom file, if present. +$(eval $(call IncludeCustomExtension, jdk, lib/Lib-java.instrument.gmk)) + ################################################################################ LIBINSTRUMENT_SRC := $(JDK_TOPDIR)/src/java.instrument/share/native/libinstrument \ diff --git a/jdk/make/lib/Lib-java.management.gmk b/jdk/make/lib/Lib-java.management.gmk index 29d5c081665..3da181b0d1a 100644 --- a/jdk/make/lib/Lib-java.management.gmk +++ b/jdk/make/lib/Lib-java.management.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -30,10 +30,10 @@ $(eval $(call IncludeCustomExtension, jdk, lib/Lib-java.management.gmk)) ################################################################################ -BUILD_LIBMANAGEMENT_SRC += $(JDK_TOPDIR)/src/java.management/share/native/libmanagement \ +LIBMANAGEMENT_SRC += $(JDK_TOPDIR)/src/java.management/share/native/libmanagement \ $(JDK_TOPDIR)/src/java.management/$(OPENJDK_TARGET_OS_TYPE)/native/libmanagement -BUILD_LIBMANAGEMENT_CFLAGS := -I$(JDK_TOPDIR)/src/java.management/share/native/include \ - $(addprefix -I,$(BUILD_LIBMANAGEMENT_SRC)) \ +LIBMANAGEMENT_CFLAGS := -I$(JDK_TOPDIR)/src/java.management/share/native/include \ + $(addprefix -I,$(LIBMANAGEMENT_SRC)) \ -I$(SUPPORT_OUTPUTDIR)/headers/java.management \ $(LIBJAVA_HEADER_FLAGS) \ # @@ -43,20 +43,6 @@ BUILD_LIBMANAGEMENT_CFLAGS := -I$(JDK_TOPDIR)/src/java.management/share/native/i # See MSDN documentation for GetProcessMemoryInfo for more information. BUILD_LIBMANAGEMENT_CFLAGS += -DPSAPI_VERSION=1 -BUILD_LIBMANAGEMENT_EXCLUDES := - -ifneq ($(OPENJDK_TARGET_OS), solaris) - BUILD_LIBMANAGEMENT_EXCLUDES += SolarisOperatingSystem.c -endif - -ifneq ($(OPENJDK_TARGET_OS), linux) - BUILD_LIBMANAGEMENT_EXCLUDES += LinuxOperatingSystem.c -endif - -ifneq ($(OPENJDK_TARGET_OS), macosx) - BUILD_LIBMANAGEMENT_EXCLUDES += MacosxOperatingSystem.c -endif - LIBMANAGEMENT_OPTIMIZATION := HIGH ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), ) ifeq ($(ENABLE_DEBUG_SYMBOLS), true) @@ -64,17 +50,13 @@ ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), ) endif endif -# Make it possible to override this variable -LIBMANAGEMENT_MAPFILE ?= $(JDK_TOPDIR)/make/mapfiles/libmanagement/mapfile-vers - $(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT, \ LIBRARY := management, \ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ - SRC := $(BUILD_LIBMANAGEMENT_SRC), \ - EXCLUDE_FILES := $(BUILD_LIBMANAGEMENT_EXCLUDES), \ + SRC := $(LIBMANAGEMENT_SRC), \ OPTIMIZATION := $(LIBMANAGEMENT_OPTIMIZATION), \ - CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) $(BUILD_LIBMANAGEMENT_CFLAGS), \ - MAPFILE := $(LIBMANAGEMENT_MAPFILE), \ + CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) $(LIBMANAGEMENT_CFLAGS), \ + MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libmanagement/mapfile-vers, \ LDFLAGS := $(LDFLAGS_JDKLIB) \ $(call SET_SHARED_LIBRARY_ORIGIN), \ LDFLAGS_solaris := -lkstat, \ diff --git a/jdk/make/lib/Lib-jdk.management.gmk b/jdk/make/lib/Lib-jdk.management.gmk new file mode 100644 index 00000000000..819bef81252 --- /dev/null +++ b/jdk/make/lib/Lib-jdk.management.gmk @@ -0,0 +1,75 @@ +# +# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +include LibCommon.gmk + +# Hook to include the corresponding custom file, if present. +$(eval $(call IncludeCustomExtension, jdk, lib/Lib-jdk.management.gmk)) + +################################################################################ + +LIBMANAGEMENT_EXT_SRC += $(JDK_TOPDIR)/src/jdk.management/share/native/libmanagement_ext \ + $(JDK_TOPDIR)/src/jdk.management/$(OPENJDK_TARGET_OS_TYPE)/native/libmanagement_ext \ + $(JDK_TOPDIR)/src/jdk.management/$(OPENJDK_TARGET_OS)/native/libmanagement_ext +LIBMANAGEMENT_EXT_CFLAGS := -I$(JDK_TOPDIR)/src/java.management/share/native/include \ + $(addprefix -I,$(LIBMANAGEMENT_EXT_SRC)) \ + -I$(SUPPORT_OUTPUTDIR)/headers/jdk.management \ + $(LIBJAVA_HEADER_FLAGS) \ + # + +LIBMANAGEMENT_EXT_OPTIMIZATION := HIGH +ifneq ($(findstring $(OPENJDK_TARGET_OS), solaris linux), ) + ifeq ($(ENABLE_DEBUG_SYMBOLS), true) + LIBMANAGEMENT_EXT_OPTIMIZATION := LOW + endif +endif + +$(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT_EXT, \ + LIBRARY := management_ext, \ + OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \ + SRC := $(LIBMANAGEMENT_EXT_SRC), \ + LANG := C, \ + OPTIMIZATION := $(LIBMANAGEMENT_EXT_OPTIMIZATION), \ + CFLAGS := $(CFLAGS_JDKLIB) $(CFLAGS_WARNINGS_ARE_ERRORS) $(LIBMANAGEMENT_EXT_CFLAGS), \ + MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libmanagement_ext/mapfile-vers, \ + LDFLAGS := $(LDFLAGS_JDKLIB) \ + $(call SET_SHARED_LIBRARY_ORIGIN), \ + LDFLAGS_solaris := -lkstat, \ + LDFLAGS_SUFFIX := $(LDFLAGS_JDKLIB_SUFFIX), \ + LDFLAGS_SUFFIX_windows := jvm.lib psapi.lib $(WIN_JAVA_LIB) advapi32.lib, \ + LDFLAGS_SUFFIX_aix := -lperfstat,\ + VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \ + RC_FLAGS := $(RC_FLAGS) \ + -D "JDK_FNAME=management_ext.dll" \ + -D "JDK_INTERNAL_NAME=management_ext" \ + -D "JDK_FTYPE=0x2L", \ + OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libmanagement_ext, \ + DEBUG_SYMBOLS := true)) + +$(BUILD_LIBMANAGEMENT_EXT): $(call FindLib, java.base, java) + +TARGETS += $(BUILD_LIBMANAGEMENT_EXT) + +################################################################################ diff --git a/jdk/make/mapfiles/libmanagement/mapfile-vers b/jdk/make/mapfiles/libmanagement/mapfile-vers index a4cb163806a..228ef93abb6 100644 --- a/jdk/make/mapfiles/libmanagement/mapfile-vers +++ b/jdk/make/mapfiles/libmanagement/mapfile-vers @@ -1,5 +1,5 @@ # -# Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -27,37 +27,10 @@ SUNWprivate_1.1 { global: - Java_sun_management_OperatingSystemImpl_getCommittedVirtualMemorySize0; - Java_sun_management_OperatingSystemImpl_getFreePhysicalMemorySize0; - Java_sun_management_OperatingSystemImpl_getFreeSwapSpaceSize0; - Java_sun_management_OperatingSystemImpl_getMaxFileDescriptorCount0; - Java_sun_management_OperatingSystemImpl_getOpenFileDescriptorCount0; - Java_sun_management_OperatingSystemImpl_getProcessCpuLoad0; - Java_sun_management_OperatingSystemImpl_getProcessCpuTime0; - Java_sun_management_OperatingSystemImpl_getSystemCpuLoad0; - Java_sun_management_OperatingSystemImpl_getTotalPhysicalMemorySize0; - Java_sun_management_OperatingSystemImpl_getTotalSwapSpaceSize0; - Java_sun_management_OperatingSystemImpl_initialize0; Java_sun_management_ClassLoadingImpl_setVerboseClass; - Java_sun_management_DiagnosticCommandImpl_executeDiagnosticCommand; - Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommands; - Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo; - Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled; - Java_sun_management_FileSystemImpl_isAccessUserOnly0; - Java_sun_management_Flag_getAllFlagNames; - Java_sun_management_Flag_getFlags; - Java_sun_management_Flag_getInternalFlagCount; - Java_sun_management_Flag_initialize; - Java_sun_management_Flag_setLongValue; - Java_sun_management_Flag_setBooleanValue; - Java_sun_management_Flag_setStringValue; - Java_sun_management_GarbageCollectorImpl_getCollectionCount; + Java_sun_management_FileSystemImpl_isAccessUserOnly0; + Java_sun_management_GarbageCollectorImpl_getCollectionCount; Java_sun_management_GarbageCollectorImpl_getCollectionTime; - Java_sun_management_GarbageCollectorImpl_setNotificationEnabled; - Java_sun_management_GcInfoBuilder_fillGcAttributeInfo; - Java_sun_management_GcInfoBuilder_getLastGcInfo0; - Java_sun_management_GcInfoBuilder_getNumGcExtAttributes; - Java_sun_management_HotSpotDiagnostic_dumpHeap0; Java_sun_management_HotspotThread_getInternalThreadCount; Java_sun_management_HotspotThread_getInternalThreadTimes0; Java_sun_management_MemoryImpl_getMemoryManagers0; diff --git a/jdk/make/mapfiles/libmanagement_ext/mapfile-vers b/jdk/make/mapfiles/libmanagement_ext/mapfile-vers new file mode 100644 index 00000000000..b8397bf9c1b --- /dev/null +++ b/jdk/make/mapfiles/libmanagement_ext/mapfile-vers @@ -0,0 +1,60 @@ +# +# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. Oracle designates this +# particular file as subject to the "Classpath" exception as provided +# by Oracle in the LICENSE file that accompanied this code. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +# Define library interface. + +SUNWprivate_1.1 { + global: + Java_com_sun_management_internal_OperatingSystemImpl_getCommittedVirtualMemorySize0; + Java_com_sun_management_internal_OperatingSystemImpl_getFreePhysicalMemorySize0; + Java_com_sun_management_internal_OperatingSystemImpl_getFreeSwapSpaceSize0; + Java_com_sun_management_internal_OperatingSystemImpl_getMaxFileDescriptorCount0; + Java_com_sun_management_internal_OperatingSystemImpl_getOpenFileDescriptorCount0; + Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuLoad0; + Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuTime0; + Java_com_sun_management_internal_OperatingSystemImpl_getSystemCpuLoad0; + Java_com_sun_management_internal_OperatingSystemImpl_getTotalPhysicalMemorySize0; + Java_com_sun_management_internal_OperatingSystemImpl_getTotalSwapSpaceSize0; + Java_com_sun_management_internal_OperatingSystemImpl_initialize0; + Java_com_sun_management_internal_DiagnosticCommandImpl_executeDiagnosticCommand; + Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommands; + Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommandInfo; + Java_com_sun_management_internal_DiagnosticCommandImpl_setNotificationEnabled; + Java_com_sun_management_internal_Flag_getAllFlagNames; + Java_com_sun_management_internal_Flag_getFlags; + Java_com_sun_management_internal_Flag_getInternalFlagCount; + Java_com_sun_management_internal_Flag_initialize; + Java_com_sun_management_internal_Flag_setLongValue; + Java_com_sun_management_internal_Flag_setBooleanValue; + Java_com_sun_management_internal_Flag_setStringValue; + Java_com_sun_management_internal_GarbageCollectorExtImpl_setNotificationEnabled; + Java_com_sun_management_internal_GcInfoBuilder_fillGcAttributeInfo; + Java_com_sun_management_internal_GcInfoBuilder_getLastGcInfo0; + Java_com_sun_management_internal_GcInfoBuilder_getNumGcExtAttributes; + Java_com_sun_management_internal_HotSpotDiagnostic_dumpHeap0; + JNI_OnLoad; + local: + *; +}; diff --git a/jdk/make/src/classes/build/tools/module/boot.modules b/jdk/make/src/classes/build/tools/module/boot.modules index 2c32d09526f..eb0ac74d739 100644 --- a/jdk/make/src/classes/build/tools/module/boot.modules +++ b/jdk/make/src/classes/build/tools/module/boot.modules @@ -22,6 +22,7 @@ jdk.deploy.osx jdk.hprof.agent jdk.httpserver jdk.jfr +jdk.management jdk.management.cmm jdk.naming.rmi jdk.sctp diff --git a/jdk/src/java.base/share/classes/com/sun/crypto/provider/GCTR.java b/jdk/src/java.base/share/classes/com/sun/crypto/provider/GCTR.java index d4cd740af7b..f8a3eaa0a4c 100644 --- a/jdk/src/java.base/share/classes/com/sun/crypto/provider/GCTR.java +++ b/jdk/src/java.base/share/classes/com/sun/crypto/provider/GCTR.java @@ -38,7 +38,17 @@ import static com.sun.crypto.provider.AESConstants.AES_BLOCK_SIZE; * under section 6.5. It needs to be constructed w/ an initialized * cipher object, and initial counter block(ICB). Given an input X * of arbitrary length, it processes and returns an output which has - * the same length as X. + * the same length as X. The invariants of this class are: + * + * (1) The length of intialCounterBlk (and also of its clones, e.g., + * fields counter and counterSave) is equal to AES_BLOCK_SIZE. + * + * (2) After construction, the field counter never becomes null, it + * always contains a byte array of length AES_BLOCK_SIZE. + * + * If any invariant is broken, failures can occur because the + * AESCrypt.encryptBlock method can be intrinsified on the HotSpot VM + * (see JDK-8067648 for details). * *

This function is used in the implementation of GCM mode. * @@ -59,6 +69,10 @@ final class GCTR { // NOTE: cipher should already be initialized GCTR(SymmetricCipher cipher, byte[] initialCounterBlk) { this.aes = cipher; + if (initialCounterBlk.length != AES_BLOCK_SIZE) { + throw new RuntimeException("length of initial counter block (" + initialCounterBlk.length + + ") not equal to AES_BLOCK_SIZE (" + AES_BLOCK_SIZE + ")"); + } this.icb = initialCounterBlk; this.counter = icb.clone(); } @@ -137,6 +151,8 @@ final class GCTR { * Restores the content of this object to the previous saved one. */ void restore() { - this.counter = this.counterSave; + if (this.counterSave != null) { + this.counter = this.counterSave; + } } } diff --git a/jdk/src/java.base/share/classes/java/lang/Class.java b/jdk/src/java.base/share/classes/java/lang/Class.java index 9748cc6c804..3aefe6ee2fb 100644 --- a/jdk/src/java.base/share/classes/java/lang/Class.java +++ b/jdk/src/java.base/share/classes/java/lang/Class.java @@ -1312,7 +1312,7 @@ public final class Class implements java.io.Serializable, // e) Anonymous classes - // JVM Spec 4.8.6: A class must have an EnclosingMethod + // JVM Spec 4.7.7: A class must have an EnclosingMethod // attribute if and only if it is a local class or an // anonymous class. EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo(); @@ -1357,28 +1357,7 @@ public final class Class implements java.io.Serializable, simpleName = getName(); return simpleName.substring(simpleName.lastIndexOf('.')+1); // strip the package name } - // According to JLS3 "Binary Compatibility" (13.1) the binary - // name of non-package classes (not top level) is the binary - // name of the immediately enclosing class followed by a '$' followed by: - // (for nested and inner classes): the simple name. - // (for local classes): 1 or more digits followed by the simple name. - // (for anonymous classes): 1 or more digits. - - // Since getSimpleBinaryName() will strip the binary name of - // the immediately enclosing class, we are now looking at a - // string that matches the regular expression "\$[0-9]*" - // followed by a simple name (considering the simple of an - // anonymous class to be the empty string). - - // Remove leading "\$[0-9]*" from the name - int length = simpleName.length(); - if (length < 1 || simpleName.charAt(0) != '$') - throw new InternalError("Malformed class name"); - int index = 1; - while (index < length && isAsciiDigit(simpleName.charAt(index))) - index++; - // Eventually, this is the empty string iff this is an anonymous class - return simpleName.substring(index); + return simpleName; } /** @@ -1489,20 +1468,20 @@ public final class Class implements java.io.Serializable, Class enclosingClass = getEnclosingClass(); if (enclosingClass == null) // top level class return null; - // Otherwise, strip the enclosing class' name - try { - return getName().substring(enclosingClass.getName().length()); - } catch (IndexOutOfBoundsException ex) { - throw new InternalError("Malformed class name", ex); - } + String name = getSimpleBinaryName0(); + if (name == null) // anonymous class + return ""; + return name; } + private native String getSimpleBinaryName0(); + /** * Returns {@code true} if this is a local class or an anonymous * class. Returns {@code false} otherwise. */ private boolean isLocalOrAnonymousClass() { - // JVM Spec 4.8.6: A class must have an EnclosingMethod + // JVM Spec 4.7.7: A class must have an EnclosingMethod // attribute if and only if it is a local class or an // anonymous class. return getEnclosingMethodInfo() != null; diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java b/jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java index 10ac1c0716e..11e452b96c9 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java @@ -25,9 +25,10 @@ package java.lang.invoke; -import sun.invoke.empty.Empty; import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; +import java.lang.reflect.Field; +import sun.misc.Cleaner; /** * A {@code CallSite} is a holder for a variable {@link MethodHandle}, @@ -135,6 +136,50 @@ public class CallSite { this.target = boundTarget; } + /** + * {@code CallSite} dependency context. + * VM uses context class to store nmethod dependencies on the call site target. + * Can be in 2 states: (a) null; or (b) {@code Cleaner} instance pointing to some Class instance. + * Lazily initialized when CallSite instance is linked to some indy call site or VM needs + * it to store dependencies. As a corollary, "null" context means there are no dependencies + * registered yet. {@code Cleaner} is used in 2 roles: + * (a) context class access for VM; + * (b) stale context class cleanup. + * {@code Cleaner} holds the context class until cleanup action is finished (see {@code PhantomReference}). + * Though it's impossible to get the context class using {@code Reference.get()}, VM extracts it directly + * from {@code Reference.referent} field. + */ + private volatile Cleaner context = null; + + /** + * Default context. + * VM uses it to initialize non-linked CallSite context. + */ + private static class DefaultContext {} + private static final Cleaner DEFAULT_CONTEXT = makeContext(DefaultContext.class, null); + + private static Cleaner makeContext(Class referent, final CallSite holder) { + return Cleaner.create(referent, + new Runnable() { + @Override public void run() { + MethodHandleNatives.invalidateDependentNMethods(holder); + } + }); + } + + /** Initialize context class used for nmethod dependency tracking */ + /*package-private*/ + void initContext(Class newContext) { + // If there are concurrent actions, exactly one succeeds. + if (context == null) { + UNSAFE.compareAndSwapObject(this, CONTEXT_OFFSET, /*expected=*/null, makeContext(newContext, this)); + // No need to care about failed CAS attempt. + // Since initContext is called from indy call site linkage in newContext class, there's no risk + // that the context class becomes dead while corresponding context cleaner is alive (causing cleanup + // action in the wrong context). + } + } + /** * Returns the type of this call site's target. * Although targets may change, any call site's type is permanent, and can never change to an unequal type. @@ -246,11 +291,13 @@ public class CallSite { } // unsafe stuff: - private static final long TARGET_OFFSET; + private static final long TARGET_OFFSET; + private static final long CONTEXT_OFFSET; static { try { - TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("target")); - } catch (Exception ex) { throw new Error(ex); } + TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("target")); + CONTEXT_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("context")); + } catch (Exception ex) { throw newInternalError(ex); } } /*package-private*/ diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java index 7cdb8c5e982..f02ed74aae5 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/DirectMethodHandle.java @@ -691,10 +691,4 @@ class DirectMethodHandle extends MethodHandle { } } } - - @Override - void customize() { - assert(form.customized == null); - // No need to customize DMHs. - } } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java index b44f9adf62f..225b998efb3 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java @@ -847,11 +847,7 @@ class InvokerBytecodeGenerator { refKind = REF_invokeVirtual; } - if (member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual) { - // Methods from Object declared in an interface can be resolved by JVM to invokevirtual kind. - // Need to convert it back to invokeinterface to pass verification and make the invocation works as expected. - refKind = REF_invokeInterface; - } + assert(!(member.getDeclaringClass().isInterface() && refKind == REF_invokeVirtual)); // push arguments emitPushArguments(name); diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java index 43cf38f12bd..e674829338e 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java @@ -281,7 +281,7 @@ class Invokers { outArgs[0] = names[CHECK_TYPE]; } if (CHECK_CUSTOM != -1) { - names[CHECK_CUSTOM] = new Name(NF_checkCustomized, names[CALL_MH]); + names[CHECK_CUSTOM] = new Name(NF_checkCustomized, outArgs[0]); } names[LINKER_CALL] = new Name(outCallType, outArgs); lform = new LambdaForm(debugName, INARG_LIMIT, names); @@ -394,6 +394,7 @@ class Invokers { @ForceInline void checkCustomized(Object o) { MethodHandle mh = (MethodHandle)o; + if (MethodHandleImpl.isCompileConstant(mh)) return; if (mh.form.customized == null) { maybeCustomize(mh); } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java index c138676a8fb..d1c1d6984f8 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -722,6 +722,13 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; return result; } + // Intrinsified by C2. Returns true if obj is a compile-time constant. + @LambdaForm.Hidden + static + boolean isCompileConstant(Object obj) { + return false; + } + static MethodHandle makeGuardWithTest(MethodHandle test, MethodHandle target, diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java index 01c3b33001d..3d3c47f689c 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,121 +55,42 @@ class MethodHandleNatives { static native Object staticFieldBase(MemberName self); // e.g., returns clazz static native Object getMemberVMInfo(MemberName self); // returns {vmindex,vmtarget} - /// MethodHandle support - - /** Fetch MH-related JVM parameter. - * which=0 retrieves MethodHandlePushLimit - * which=1 retrieves stack slot push size (in address units) - */ - static native int getConstant(int which); - - static final boolean COUNT_GWT; - /// CallSite support /** Tell the JVM that we need to change the target of a CallSite. */ static native void setCallSiteTargetNormal(CallSite site, MethodHandle target); static native void setCallSiteTargetVolatile(CallSite site, MethodHandle target); + /** Invalidate CallSite context: clean up dependent nmethods and reset call site context to initial state (null). */ + static native void invalidateDependentNMethods(CallSite site); + private static native void registerNatives(); static { registerNatives(); - COUNT_GWT = getConstant(Constants.GC_COUNT_GWT) != 0; // The JVM calls MethodHandleNatives.. Cascade the calls as needed: MethodHandleImpl.initStatics(); } - // All compile-time constants go here. - // There is an opportunity to check them against the JVM's idea of them. + /** + * Compile-time constants go here. This collection exists not only for + * reference from clients, but also for ensuring the VM and JDK agree on the + * values of these constants (see {@link #verifyConstants()}). + */ static class Constants { Constants() { } // static only - // MethodHandleImpl - static final int // for getConstant - GC_COUNT_GWT = 4, - GC_LAMBDA_SUPPORT = 5; - // MemberName - // The JVM uses values of -2 and above for vtable indexes. - // Field values are simple positive offsets. - // Ref: src/share/vm/oops/methodOop.hpp - // This value is negative enough to avoid such numbers, - // but not too negative. static final int - MN_IS_METHOD = 0x00010000, // method (not constructor) - MN_IS_CONSTRUCTOR = 0x00020000, // constructor - MN_IS_FIELD = 0x00040000, // field - MN_IS_TYPE = 0x00080000, // nested type - MN_CALLER_SENSITIVE = 0x00100000, // @CallerSensitive annotation detected - MN_REFERENCE_KIND_SHIFT = 24, // refKind - MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT, - // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers: - MN_SEARCH_SUPERCLASSES = 0x00100000, - MN_SEARCH_INTERFACES = 0x00200000; - - /** - * Basic types as encoded in the JVM. These code values are not - * intended for use outside this class. They are used as part of - * a private interface between the JVM and this class. - */ - static final int - T_BOOLEAN = 4, - T_CHAR = 5, - T_FLOAT = 6, - T_DOUBLE = 7, - T_BYTE = 8, - T_SHORT = 9, - T_INT = 10, - T_LONG = 11, - T_OBJECT = 12, - //T_ARRAY = 13 - T_VOID = 14, - //T_ADDRESS = 15 - T_ILLEGAL = 99; - - /** - * Constant pool entry types. - */ - static final byte - CONSTANT_Utf8 = 1, - CONSTANT_Integer = 3, - CONSTANT_Float = 4, - CONSTANT_Long = 5, - CONSTANT_Double = 6, - CONSTANT_Class = 7, - CONSTANT_String = 8, - CONSTANT_Fieldref = 9, - CONSTANT_Methodref = 10, - CONSTANT_InterfaceMethodref = 11, - CONSTANT_NameAndType = 12, - CONSTANT_MethodHandle = 15, // JSR 292 - CONSTANT_MethodType = 16, // JSR 292 - CONSTANT_InvokeDynamic = 18, - CONSTANT_LIMIT = 19; // Limit to tags found in classfiles - - /** - * Access modifier flags. - */ - static final char - ACC_PUBLIC = 0x0001, - ACC_PRIVATE = 0x0002, - ACC_PROTECTED = 0x0004, - ACC_STATIC = 0x0008, - ACC_FINAL = 0x0010, - ACC_SYNCHRONIZED = 0x0020, - ACC_VOLATILE = 0x0040, - ACC_TRANSIENT = 0x0080, - ACC_NATIVE = 0x0100, - ACC_INTERFACE = 0x0200, - ACC_ABSTRACT = 0x0400, - ACC_STRICT = 0x0800, - ACC_SYNTHETIC = 0x1000, - ACC_ANNOTATION = 0x2000, - ACC_ENUM = 0x4000, - // aliases: - ACC_SUPER = ACC_SYNCHRONIZED, - ACC_BRIDGE = ACC_VOLATILE, - ACC_VARARGS = ACC_TRANSIENT; + MN_IS_METHOD = 0x00010000, // method (not constructor) + MN_IS_CONSTRUCTOR = 0x00020000, // constructor + MN_IS_FIELD = 0x00040000, // field + MN_IS_TYPE = 0x00080000, // nested type + MN_CALLER_SENSITIVE = 0x00100000, // @CallerSensitive annotation detected + MN_REFERENCE_KIND_SHIFT = 24, // refKind + MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT, + // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers: + MN_SEARCH_SUPERCLASSES = 0x00100000, + MN_SEARCH_INTERFACES = 0x00200000; /** * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries. @@ -314,6 +235,7 @@ class MethodHandleNatives { return Invokers.linkToTargetMethod(type); } else { appendixResult[0] = callSite; + callSite.initContext(caller); return Invokers.linkToCallSiteMethod(type); } } diff --git a/jdk/src/java.base/share/classes/java/nio/Bits.java b/jdk/src/java.base/share/classes/java/nio/Bits.java index c7f2b78422b..d23e35e82aa 100644 --- a/jdk/src/java.base/share/classes/java/nio/Bits.java +++ b/jdk/src/java.base/share/classes/java/nio/Bits.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -567,32 +567,13 @@ class Bits { // package-private // -- Processor and memory-system properties -- - private static final ByteOrder byteOrder; + private static final ByteOrder byteOrder + = unsafe.isBigEndian() ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN; static ByteOrder byteOrder() { - if (byteOrder == null) - throw new Error("Unknown byte order"); return byteOrder; } - static { - long a = unsafe.allocateMemory(8); - try { - unsafe.putLong(a, 0x0102030405060708L); - byte b = unsafe.getByte(a); - switch (b) { - case 0x01: byteOrder = ByteOrder.BIG_ENDIAN; break; - case 0x08: byteOrder = ByteOrder.LITTLE_ENDIAN; break; - default: - assert false; - byteOrder = null; - } - } finally { - unsafe.freeMemory(a); - } - } - - private static int pageSize = -1; static int pageSize() { @@ -605,17 +586,9 @@ class Bits { // package-private return (int)(size + (long)pageSize() - 1L) / pageSize(); } - private static boolean unaligned; - private static boolean unalignedKnown = false; + private static boolean unaligned = unsafe.unalignedAccess(); static boolean unaligned() { - if (unalignedKnown) - return unaligned; - String arch = AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("os.arch")); - unaligned = arch.equals("i386") || arch.equals("x86") - || arch.equals("amd64") || arch.equals("x86_64"); - unalignedKnown = true; return unaligned; } diff --git a/jdk/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template b/jdk/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template index e8639c4d21f..3876b147093 100644 --- a/jdk/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template +++ b/jdk/src/java.base/share/classes/java/nio/Heap-X-Buffer.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ package java.nio; +import sun.misc.Unsafe; /** #if[rw] @@ -52,6 +53,16 @@ class Heap$Type$Buffer$RW$ #end[rw] */ +#if[byte] + + // Cached unsafe-access object + private static final Unsafe unsafe = Bits.unsafe(); + + // Cached array base offset + private static final long arrayBaseOffset = unsafe.arrayBaseOffset($type$[].class); + +#end[byte] + Heap$Type$Buffer$RW$(int cap, int lim) { // package-private #if[rw] super(-1, 0, lim, cap, new $type$[cap], 0); @@ -131,6 +142,12 @@ class Heap$Type$Buffer$RW$ return i + offset; } +#if[byte] + private long byteOffset(long i) { + return arrayBaseOffset + i + offset; + } +#end[byte] + public $type$ get() { return hb[ix(nextGetIndex())]; } @@ -256,18 +273,18 @@ class Heap$Type$Buffer$RW$ #if[rw] public char getChar() { - return Bits.getChar(this, ix(nextGetIndex(2)), bigEndian); + return unsafe.getCharUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian); } public char getChar(int i) { - return Bits.getChar(this, ix(checkIndex(i, 2)), bigEndian); + return unsafe.getCharUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian); } #end[rw] public $Type$Buffer putChar(char x) { #if[rw] - Bits.putChar(this, ix(nextPutIndex(2)), x, bigEndian); + unsafe.putCharUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian); return this; #else[rw] throw new ReadOnlyBufferException(); @@ -276,7 +293,7 @@ class Heap$Type$Buffer$RW$ public $Type$Buffer putChar(int i, char x) { #if[rw] - Bits.putChar(this, ix(checkIndex(i, 2)), x, bigEndian); + unsafe.putCharUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian); return this; #else[rw] throw new ReadOnlyBufferException(); @@ -307,18 +324,18 @@ class Heap$Type$Buffer$RW$ #if[rw] public short getShort() { - return Bits.getShort(this, ix(nextGetIndex(2)), bigEndian); + return unsafe.getShortUnaligned(hb, byteOffset(nextGetIndex(2)), bigEndian); } public short getShort(int i) { - return Bits.getShort(this, ix(checkIndex(i, 2)), bigEndian); + return unsafe.getShortUnaligned(hb, byteOffset(checkIndex(i, 2)), bigEndian); } #end[rw] public $Type$Buffer putShort(short x) { #if[rw] - Bits.putShort(this, ix(nextPutIndex(2)), x, bigEndian); + unsafe.putShortUnaligned(hb, byteOffset(nextPutIndex(2)), x, bigEndian); return this; #else[rw] throw new ReadOnlyBufferException(); @@ -327,7 +344,7 @@ class Heap$Type$Buffer$RW$ public $Type$Buffer putShort(int i, short x) { #if[rw] - Bits.putShort(this, ix(checkIndex(i, 2)), x, bigEndian); + unsafe.putShortUnaligned(hb, byteOffset(checkIndex(i, 2)), x, bigEndian); return this; #else[rw] throw new ReadOnlyBufferException(); @@ -358,18 +375,18 @@ class Heap$Type$Buffer$RW$ #if[rw] public int getInt() { - return Bits.getInt(this, ix(nextGetIndex(4)), bigEndian); + return unsafe.getIntUnaligned(hb, byteOffset(nextGetIndex(4)), bigEndian); } public int getInt(int i) { - return Bits.getInt(this, ix(checkIndex(i, 4)), bigEndian); + return unsafe.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian); } #end[rw] public $Type$Buffer putInt(int x) { #if[rw] - Bits.putInt(this, ix(nextPutIndex(4)), x, bigEndian); + unsafe.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), x, bigEndian); return this; #else[rw] throw new ReadOnlyBufferException(); @@ -378,7 +395,7 @@ class Heap$Type$Buffer$RW$ public $Type$Buffer putInt(int i, int x) { #if[rw] - Bits.putInt(this, ix(checkIndex(i, 4)), x, bigEndian); + unsafe.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), x, bigEndian); return this; #else[rw] throw new ReadOnlyBufferException(); @@ -409,18 +426,18 @@ class Heap$Type$Buffer$RW$ #if[rw] public long getLong() { - return Bits.getLong(this, ix(nextGetIndex(8)), bigEndian); + return unsafe.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian); } public long getLong(int i) { - return Bits.getLong(this, ix(checkIndex(i, 8)), bigEndian); + return unsafe.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian); } #end[rw] public $Type$Buffer putLong(long x) { #if[rw] - Bits.putLong(this, ix(nextPutIndex(8)), x, bigEndian); + unsafe.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), x, bigEndian); return this; #else[rw] throw new ReadOnlyBufferException(); @@ -429,7 +446,7 @@ class Heap$Type$Buffer$RW$ public $Type$Buffer putLong(int i, long x) { #if[rw] - Bits.putLong(this, ix(checkIndex(i, 8)), x, bigEndian); + unsafe.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), x, bigEndian); return this; #else[rw] throw new ReadOnlyBufferException(); @@ -460,18 +477,21 @@ class Heap$Type$Buffer$RW$ #if[rw] public float getFloat() { - return Bits.getFloat(this, ix(nextGetIndex(4)), bigEndian); + int x = unsafe.getIntUnaligned(hb, byteOffset(nextPutIndex(4)), bigEndian); + return Float.intBitsToFloat(x); } public float getFloat(int i) { - return Bits.getFloat(this, ix(checkIndex(i, 4)), bigEndian); + int x = unsafe.getIntUnaligned(hb, byteOffset(checkIndex(i, 4)), bigEndian); + return Float.intBitsToFloat(x); } #end[rw] public $Type$Buffer putFloat(float x) { #if[rw] - Bits.putFloat(this, ix(nextPutIndex(4)), x, bigEndian); + int y = Float.floatToRawIntBits(x); + unsafe.putIntUnaligned(hb, byteOffset(nextPutIndex(4)), y, bigEndian); return this; #else[rw] throw new ReadOnlyBufferException(); @@ -480,7 +500,8 @@ class Heap$Type$Buffer$RW$ public $Type$Buffer putFloat(int i, float x) { #if[rw] - Bits.putFloat(this, ix(checkIndex(i, 4)), x, bigEndian); + int y = Float.floatToRawIntBits(x); + unsafe.putIntUnaligned(hb, byteOffset(checkIndex(i, 4)), y, bigEndian); return this; #else[rw] throw new ReadOnlyBufferException(); @@ -511,18 +532,21 @@ class Heap$Type$Buffer$RW$ #if[rw] public double getDouble() { - return Bits.getDouble(this, ix(nextGetIndex(8)), bigEndian); + long x = unsafe.getLongUnaligned(hb, byteOffset(nextGetIndex(8)), bigEndian); + return Double.longBitsToDouble(x); } public double getDouble(int i) { - return Bits.getDouble(this, ix(checkIndex(i, 8)), bigEndian); + long x = unsafe.getLongUnaligned(hb, byteOffset(checkIndex(i, 8)), bigEndian); + return Double.longBitsToDouble(x); } #end[rw] public $Type$Buffer putDouble(double x) { #if[rw] - Bits.putDouble(this, ix(nextPutIndex(8)), x, bigEndian); + long y = Double.doubleToRawLongBits(x); + unsafe.putLongUnaligned(hb, byteOffset(nextPutIndex(8)), y, bigEndian); return this; #else[rw] throw new ReadOnlyBufferException(); @@ -531,7 +555,8 @@ class Heap$Type$Buffer$RW$ public $Type$Buffer putDouble(int i, double x) { #if[rw] - Bits.putDouble(this, ix(checkIndex(i, 8)), x, bigEndian); + long y = Double.doubleToRawLongBits(x); + unsafe.putLongUnaligned(hb, byteOffset(checkIndex(i, 8)), y, bigEndian); return this; #else[rw] throw new ReadOnlyBufferException(); diff --git a/jdk/src/java.base/share/classes/sun/misc/Unsafe.java b/jdk/src/java.base/share/classes/sun/misc/Unsafe.java index 5ca9cb3059d..1d3454e281e 100644 --- a/jdk/src/java.base/share/classes/sun/misc/Unsafe.java +++ b/jdk/src/java.base/share/classes/sun/misc/Unsafe.java @@ -183,7 +183,7 @@ public final class Unsafe { *

* Unless the reference {@code x} being stored is either null * or matches the field type, the results are undefined. - * If the reference {@code o} is non-null, car marks or + * If the reference {@code o} is non-null, card marks or * other store barriers for that object (if the VM requires them) * are updated. * @see #putInt(Object, long, int) @@ -219,6 +219,35 @@ public final class Unsafe { /** @see #putInt(Object, long, int) */ public native void putDouble(Object o, long offset, double x); + // These read VM internal data. + + /** + * Fetches an uncompressed reference value from a given native variable + * ignoring the VM's compressed references mode. + * + * @param address a memory address locating the variable + * @return the value fetched from the indicated native variable + */ + public native Object getUncompressedObject(long address); + + /** + * Fetches the {@link java.lang.Class} Java mirror for the given native + * metaspace {@code Klass} pointer. + * + * @param metaspaceKlass a native metaspace {@code Klass} pointer + * @return the {@link java.lang.Class} Java mirror + */ + public native Class getJavaMirror(long metaspaceKlass); + + /** + * Fetches a native metaspace {@code Klass} pointer for the given Java + * object. + * + * @param o Java heap object for which to fetch the class pointer + * @return a native metaspace {@code Klass} pointer + */ + public native long getKlassPointer(Object o); + // These work on values in the C heap. /** @@ -934,4 +963,347 @@ public final class Unsafe { private static void throwIllegalAccessError() { throw new IllegalAccessError(); } + + /** + * @return Returns true if the native byte ordering of this + * platform is big-endian, false if it is little-endian. + */ + public final boolean isBigEndian() { return BE; } + + /** + * @return Returns true if this platform is capable of performing + * accesses at addresses which are not aligned for the type of the + * primitive type being accessed, false otherwise. + */ + public final boolean unalignedAccess() { return unalignedAccess; } + + /** + * Fetches a value at some byte offset into a given Java object. + * More specifically, fetches a value within the given object + * o at the given offset, or (if o is + * null) from the memory address whose numerical value is the + * given offset.

+ * + * The specification of this method is the same as {@link + * #getLong(Object, long)} except that the offset does not need to + * have been obtained from {@link #objectFieldOffset} on the + * {@link java.lang.reflect.Field} of some Java field. The value + * in memory is raw data, and need not correspond to any Java + * variable. Unless o is null, the value accessed + * must be entirely within the allocated object. The endianness + * of the value in memory is the endianness of the native platform. + * + *

The read will be atomic with respect to the largest power + * of two that divides the GCD of the offset and the storage size. + * For example, getLongUnaligned will make atomic reads of 2-, 4-, + * or 8-byte storage units if the offset is zero mod 2, 4, or 8, + * respectively. There are no other guarantees of atomicity. + *

+ * 8-byte atomicity is only guaranteed on platforms on which + * support atomic accesses to longs. + * + * @param o Java heap object in which the value resides, if any, else + * null + * @param offset The offset in bytes from the start of the object + * @return the value fetched from the indicated object + * @throws RuntimeException No defined exceptions are thrown, not even + * {@link NullPointerException} + * @since 1.9 + */ + public final long getLongUnaligned(Object o, long offset) { + if ((offset & 7) == 0) { + return getLong(o, offset); + } else if ((offset & 3) == 0) { + return makeLong(getInt(o, offset), + getInt(o, offset + 4)); + } else if ((offset & 1) == 0) { + return makeLong(getShort(o, offset), + getShort(o, offset + 2), + getShort(o, offset + 4), + getShort(o, offset + 6)); + } else { + return makeLong(getByte(o, offset), + getByte(o, offset + 1), + getByte(o, offset + 2), + getByte(o, offset + 3), + getByte(o, offset + 4), + getByte(o, offset + 5), + getByte(o, offset + 6), + getByte(o, offset + 7)); + } + } + /** + * As {@link #getLongUnaligned(Object, long)} but with an + * additional argument which specifies the endianness of the value + * as stored in memory. + * + * @param o Java heap object in which the variable resides + * @param offset The offset in bytes from the start of the object + * @param bigEndian The endianness of the value + * @return the value fetched from the indicated object + * @since 1.9 + */ + public final long getLongUnaligned(Object o, long offset, boolean bigEndian) { + return convEndian(bigEndian, getLongUnaligned(o, offset)); + } + + /** @see #getLongUnaligned(Object, long) */ + public final int getIntUnaligned(Object o, long offset) { + if ((offset & 3) == 0) { + return getInt(o, offset); + } else if ((offset & 1) == 0) { + return makeInt(getShort(o, offset), + getShort(o, offset + 2)); + } else { + return makeInt(getByte(o, offset), + getByte(o, offset + 1), + getByte(o, offset + 2), + getByte(o, offset + 3)); + } + } + /** @see #getLongUnaligned(Object, long, boolean) */ + public final int getIntUnaligned(Object o, long offset, boolean bigEndian) { + return convEndian(bigEndian, getIntUnaligned(o, offset)); + } + + /** @see #getLongUnaligned(Object, long) */ + public final short getShortUnaligned(Object o, long offset) { + if ((offset & 1) == 0) { + return getShort(o, offset); + } else { + return makeShort(getByte(o, offset), + getByte(o, offset + 1)); + } + } + /** @see #getLongUnaligned(Object, long, boolean) */ + public final short getShortUnaligned(Object o, long offset, boolean bigEndian) { + return convEndian(bigEndian, getShortUnaligned(o, offset)); + } + + /** @see #getLongUnaligned(Object, long) */ + public final char getCharUnaligned(Object o, long offset) { + return (char)getShortUnaligned(o, offset); + } + /** @see #getLongUnaligned(Object, long, boolean) */ + public final char getCharUnaligned(Object o, long offset, boolean bigEndian) { + return convEndian(bigEndian, getCharUnaligned(o, offset)); + } + + /** + * Stores a value at some byte offset into a given Java object. + *

+ * The specification of this method is the same as {@link + * #getLong(Object, long)} except that the offset does not need to + * have been obtained from {@link #objectFieldOffset} on the + * {@link java.lang.reflect.Field} of some Java field. The value + * in memory is raw data, and need not correspond to any Java + * variable. The endianness of the value in memory is the + * endianness of the native platform. + *

+ * The write will be atomic with respect to the largest power of + * two that divides the GCD of the offset and the storage size. + * For example, putLongUnaligned will make atomic writes of 2-, 4-, + * or 8-byte storage units if the offset is zero mod 2, 4, or 8, + * respectively. There are no other guarantees of atomicity. + *

+ * 8-byte atomicity is only guaranteed on platforms on which + * support atomic accesses to longs. + *

+ * + * @param o Java heap object in which the value resides, if any, else + * null + * @param offset The offset in bytes from the start of the object + * @param x the value to store + * @throws RuntimeException No defined exceptions are thrown, not even + * {@link NullPointerException} + * @since 1.9 + */ + public final void putLongUnaligned(Object o, long offset, long x) { + if ((offset & 7) == 0) { + putLong(o, offset, x); + } else if ((offset & 3) == 0) { + putLongParts(o, offset, + (int)(x >> 0), + (int)(x >>> 32)); + } else if ((offset & 1) == 0) { + putLongParts(o, offset, + (short)(x >>> 0), + (short)(x >>> 16), + (short)(x >>> 32), + (short)(x >>> 48)); + } else { + putLongParts(o, offset, + (byte)(x >>> 0), + (byte)(x >>> 8), + (byte)(x >>> 16), + (byte)(x >>> 24), + (byte)(x >>> 32), + (byte)(x >>> 40), + (byte)(x >>> 48), + (byte)(x >>> 56)); + } + } + /** + * As {@link #putLongUnaligned(Object, long, long)} but with an additional + * argument which specifies the endianness of the value as stored in memory. + * @param o Java heap object in which the value resides + * @param offset The offset in bytes from the start of the object + * @param x the value to store + * @param bigEndian The endianness of the value + * @throws RuntimeException No defined exceptions are thrown, not even + * {@link NullPointerException} + * @since 1.9 + */ + public final void putLongUnaligned(Object o, long offset, long x, boolean bigEndian) { + putLongUnaligned(o, offset, convEndian(bigEndian, x)); + } + + /** @see #putLongUnaligned(Object, long, long) */ + public final void putIntUnaligned(Object o, long offset, int x) { + if ((offset & 3) == 0) { + putInt(o, offset, x); + } else if ((offset & 1) == 0) { + putIntParts(o, offset, + (short)(x >> 0), + (short)(x >>> 16)); + } else { + putIntParts(o, offset, + (byte)(x >>> 0), + (byte)(x >>> 8), + (byte)(x >>> 16), + (byte)(x >>> 24)); + } + } + /** @see #putLongUnaligned(Object, long, long, boolean) */ + public final void putIntUnaligned(Object o, long offset, int x, boolean bigEndian) { + putIntUnaligned(o, offset, convEndian(bigEndian, x)); + } + + /** @see #putLongUnaligned(Object, long, long) */ + public final void putShortUnaligned(Object o, long offset, short x) { + if ((offset & 1) == 0) { + putShort(o, offset, x); + } else { + putShortParts(o, offset, + (byte)(x >>> 0), + (byte)(x >>> 8)); + } + } + /** @see #putLongUnaligned(Object, long, long, boolean) */ + public final void putShortUnaligned(Object o, long offset, short x, boolean bigEndian) { + putShortUnaligned(o, offset, convEndian(bigEndian, x)); + } + + /** @see #putLongUnaligned(Object, long, long) */ + public final void putCharUnaligned(Object o, long offset, char x) { + putShortUnaligned(o, offset, (short)x); + } + /** @see #putLongUnaligned(Object, long, long, boolean) */ + public final void putCharUnaligned(Object o, long offset, char x, boolean bigEndian) { + putCharUnaligned(o, offset, convEndian(bigEndian, x)); + } + + // JVM interface methods + private native boolean unalignedAccess0(); + private native boolean isBigEndian0(); + + // BE is true iff the native endianness of this platform is big. + private static final boolean BE = theUnsafe.isBigEndian0(); + + // unalignedAccess is true iff this platform can perform unaligned accesses. + private static final boolean unalignedAccess = theUnsafe.unalignedAccess0(); + + private static int pickPos(int top, int pos) { return BE ? top - pos : pos; } + + // These methods construct integers from bytes. The byte ordering + // is the native endianness of this platform. + private static long makeLong(byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) { + return ((toUnsignedLong(i0) << pickPos(56, 0)) + | (toUnsignedLong(i1) << pickPos(56, 8)) + | (toUnsignedLong(i2) << pickPos(56, 16)) + | (toUnsignedLong(i3) << pickPos(56, 24)) + | (toUnsignedLong(i4) << pickPos(56, 32)) + | (toUnsignedLong(i5) << pickPos(56, 40)) + | (toUnsignedLong(i6) << pickPos(56, 48)) + | (toUnsignedLong(i7) << pickPos(56, 56))); + } + private static long makeLong(short i0, short i1, short i2, short i3) { + return ((toUnsignedLong(i0) << pickPos(48, 0)) + | (toUnsignedLong(i1) << pickPos(48, 16)) + | (toUnsignedLong(i2) << pickPos(48, 32)) + | (toUnsignedLong(i3) << pickPos(48, 48))); + } + private static long makeLong(int i0, int i1) { + return (toUnsignedLong(i0) << pickPos(32, 0)) + | (toUnsignedLong(i1) << pickPos(32, 32)); + } + private static int makeInt(short i0, short i1) { + return (toUnsignedInt(i0) << pickPos(16, 0)) + | (toUnsignedInt(i1) << pickPos(16, 16)); + } + private static int makeInt(byte i0, byte i1, byte i2, byte i3) { + return ((toUnsignedInt(i0) << pickPos(24, 0)) + | (toUnsignedInt(i1) << pickPos(24, 8)) + | (toUnsignedInt(i2) << pickPos(24, 16)) + | (toUnsignedInt(i3) << pickPos(24, 24))); + } + private static short makeShort(byte i0, byte i1) { + return (short)((toUnsignedInt(i0) << pickPos(8, 0)) + | (toUnsignedInt(i1) << pickPos(8, 8))); + } + + private static byte pick(byte le, byte be) { return BE ? be : le; } + private static short pick(short le, short be) { return BE ? be : le; } + private static int pick(int le, int be) { return BE ? be : le; } + + // These methods write integers to memory from smaller parts + // provided by their caller. The ordering in which these parts + // are written is the native endianness of this platform. + private void putLongParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3, byte i4, byte i5, byte i6, byte i7) { + putByte(o, offset + 0, pick(i0, i7)); + putByte(o, offset + 1, pick(i1, i6)); + putByte(o, offset + 2, pick(i2, i5)); + putByte(o, offset + 3, pick(i3, i4)); + putByte(o, offset + 4, pick(i4, i3)); + putByte(o, offset + 5, pick(i5, i2)); + putByte(o, offset + 6, pick(i6, i1)); + putByte(o, offset + 7, pick(i7, i0)); + } + private void putLongParts(Object o, long offset, short i0, short i1, short i2, short i3) { + putShort(o, offset + 0, pick(i0, i3)); + putShort(o, offset + 2, pick(i1, i2)); + putShort(o, offset + 4, pick(i2, i1)); + putShort(o, offset + 6, pick(i3, i0)); + } + private void putLongParts(Object o, long offset, int i0, int i1) { + putInt(o, offset + 0, pick(i0, i1)); + putInt(o, offset + 4, pick(i1, i0)); + } + private void putIntParts(Object o, long offset, short i0, short i1) { + putShort(o, offset + 0, pick(i0, i1)); + putShort(o, offset + 2, pick(i1, i0)); + } + private void putIntParts(Object o, long offset, byte i0, byte i1, byte i2, byte i3) { + putByte(o, offset + 0, pick(i0, i3)); + putByte(o, offset + 1, pick(i1, i2)); + putByte(o, offset + 2, pick(i2, i1)); + putByte(o, offset + 3, pick(i3, i0)); + } + private void putShortParts(Object o, long offset, byte i0, byte i1) { + putByte(o, offset + 0, pick(i0, i1)); + putByte(o, offset + 1, pick(i1, i0)); + } + + // Zero-extend an integer + private static int toUnsignedInt(byte n) { return n & 0xff; } + private static int toUnsignedInt(short n) { return n & 0xffff; } + private static long toUnsignedLong(byte n) { return n & 0xffl; } + private static long toUnsignedLong(short n) { return n & 0xffffl; } + private static long toUnsignedLong(int n) { return n & 0xffffffffl; } + + // Maybe byte-reverse an integer + private static char convEndian(boolean big, char n) { return big == BE ? n : Character.reverseBytes(n); } + private static short convEndian(boolean big, short n) { return big == BE ? n : Short.reverseBytes(n) ; } + private static int convEndian(boolean big, int n) { return big == BE ? n : Integer.reverseBytes(n) ; } + private static long convEndian(boolean big, long n) { return big == BE ? n : Long.reverseBytes(n) ; } } diff --git a/jdk/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java b/jdk/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java index e06832bf3c6..1669429a4fa 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,13 +88,8 @@ final class ByteArrayAccess { // Return whether this platform supports full speed int/long memory access // at unaligned addresses. - // This code was copied from java.nio.Bits because there is no equivalent - // public API. private static boolean unaligned() { - String arch = java.security.AccessController.doPrivileged - (new sun.security.action.GetPropertyAction("os.arch", "")); - return arch.equals("i386") || arch.equals("x86") || arch.equals("amd64") - || arch.equals("x86_64"); + return unsafe.unalignedAccess(); } /** diff --git a/jdk/src/java.base/share/native/include/jvm.h b/jdk/src/java.base/share/native/include/jvm.h index 7177f2e1d1e..91decb2ed82 100644 --- a/jdk/src/java.base/share/native/include/jvm.h +++ b/jdk/src/java.base/share/native/include/jvm.h @@ -395,6 +395,9 @@ JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass); JNIEXPORT jclass JNICALL JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass); +JNIEXPORT jstring JNICALL +JVM_GetSimpleBinaryName(JNIEnv *env, jclass ofClass); + /* Generics support (JDK 1.5) */ JNIEXPORT jstring JNICALL JVM_GetClassSignature(JNIEnv *env, jclass cls); diff --git a/jdk/src/java.base/share/native/libjava/Class.c b/jdk/src/java.base/share/native/libjava/Class.c index ae759514a79..07a3f6db716 100644 --- a/jdk/src/java.base/share/native/libjava/Class.c +++ b/jdk/src/java.base/share/native/libjava/Class.c @@ -67,6 +67,7 @@ static JNINativeMethod methods[] = { {"getProtectionDomain0", "()" PD, (void *)&JVM_GetProtectionDomain}, {"getDeclaredClasses0", "()[" CLS, (void *)&JVM_GetDeclaredClasses}, {"getDeclaringClass0", "()" CLS, (void *)&JVM_GetDeclaringClass}, + {"getSimpleBinaryName0", "()" STR, (void *)&JVM_GetSimpleBinaryName}, {"getGenericSignature0", "()" STR, (void *)&JVM_GetClassSignature}, {"getRawAnnotations", "()" BA, (void *)&JVM_GetClassAnnotations}, {"getConstantPool", "()" CPL, (void *)&JVM_GetClassConstantPool}, diff --git a/jdk/src/java.management/share/classes/java/lang/management/DefaultPlatformMBeanProvider.java b/jdk/src/java.management/share/classes/java/lang/management/DefaultPlatformMBeanProvider.java index 128b0ba8afd..f265f4c44fe 100644 --- a/jdk/src/java.management/share/classes/java/lang/management/DefaultPlatformMBeanProvider.java +++ b/jdk/src/java.management/share/classes/java/lang/management/DefaultPlatformMBeanProvider.java @@ -33,7 +33,6 @@ import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; -import javax.management.DynamicMBean; import javax.management.ObjectName; import sun.management.ManagementFactoryHelper; import sun.management.spi.PlatformMBeanProvider; @@ -162,8 +161,7 @@ class DefaultPlatformMBeanProvider extends PlatformMBeanProvider { @Override public Set> mbeanInterfaces() { return Stream.of(MemoryManagerMXBean.class, - GarbageCollectorMXBean.class, - com.sun.management.GarbageCollectorMXBean.class).collect(Collectors.toSet()); + GarbageCollectorMXBean.class).collect(Collectors.toSet()); } @Override @@ -464,39 +462,6 @@ class DefaultPlatformMBeanProvider extends PlatformMBeanProvider { }); - /** - * DynamicMBean - */ - HashMap dynmbeans - = ManagementFactoryHelper.getPlatformDynamicMBeans(); - final Set dynamicMBeanInterfaceNames = - Collections.unmodifiableSet(Collections.singleton("javax.management.DynamicMBean")); - for (Map.Entry e : dynmbeans.entrySet()) { - initMBeanList.add(new PlatformComponent() { - @Override - public Set> mbeanInterfaces() { - return Collections.emptySet(); - } - - @Override - public Set mbeanInterfaceNames() { - return dynamicMBeanInterfaceNames; - } - - @Override - public String getObjectNamePattern() { - return e.getKey().getCanonicalName(); - } - - @Override - public Map nameToMBeanMap() { - return Collections.singletonMap( - e.getKey().getCanonicalName(), - e.getValue()); - } - }); - } - initMBeanList.trimToSize(); return initMBeanList; } diff --git a/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java b/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java index 9a0e1ebbd61..82508822954 100644 --- a/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java +++ b/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java @@ -582,7 +582,7 @@ public class ManagementFactory { final Class cls = mxbeanInterface; ClassLoader loader = AccessController.doPrivileged( - (PrivilegedAction) () -> cls.getClassLoader()); + (PrivilegedAction) () -> cls.getClassLoader()); if (!sun.misc.VM.isSystemDomainLoader(loader)) { throw new IllegalArgumentException(mxbeanName + " is not a platform MXBean"); @@ -883,7 +883,7 @@ public class ManagementFactory { all.add(new DefaultPlatformMBeanProvider()); return all; }, null, new FilePermission("<>", "read"), - new RuntimePermission("sun.management.spi.PlatformMBeanProvider")); + new RuntimePermission("sun.management.spi.PlatformMBeanProvider.subclass")); // load all platform components into a map componentMap = providers.stream() @@ -970,4 +970,11 @@ public class ManagementFactory { return singleton; } } + + static { + AccessController.doPrivileged((PrivilegedAction) () -> { + System.loadLibrary("management"); + return null; + }); + } } diff --git a/jdk/src/java.management/share/classes/sun/management/Agent.java b/jdk/src/java.management/share/classes/sun/management/Agent.java index 3128ca442ea..ffb3105255e 100644 --- a/jdk/src/java.management/share/classes/sun/management/Agent.java +++ b/jdk/src/java.management/share/classes/sun/management/Agent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ import java.lang.management.ManagementFactory; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.InetAddress; +import java.net.MalformedURLException; import java.net.UnknownHostException; import java.text.MessageFormat; import java.util.MissingResourceException; @@ -55,6 +56,125 @@ import sun.misc.VMSupport; * system class loader. Also jmx framework could be started by jcmd */ public class Agent { + /** + * Agent status collector strategy class + */ + private static abstract class StatusCollector { + final protected StringBuilder sb = new StringBuilder(); + final public String collect() { + Properties agentProps = VMSupport.getAgentProperties(); + String localConnAddr = (String)agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP); + if (localConnAddr != null || jmxServer != null) { + addAgentStatus(true); + appendConnections(localConnAddr); + } else { + addAgentStatus(false); + } + return sb.toString(); + } + + private void appendConnections(String localConnAddr) { + appendConnectionsHeader(); + if (localConnAddr != null) { + try { + JMXServiceURL u = new JMXServiceURL(localConnAddr); + addConnection(false, u); + } catch (MalformedURLException e) { + // will never happen + } + + } + if (jmxServer != null) { + addConnection(true, jmxServer.getAddress()); + } + appendConnectionsFooter(); + } + + private void addConnection(boolean remote, JMXServiceURL u) { + appendConnectionHeader(remote); + addConnectionDetails(u); + if (remote) { + addConfigProperties(); + } + appendConnectionFooter(remote); + } + + private void addConfigProperties() { + appendConfigPropsHeader(); + boolean[] first = new boolean[] {true}; + configProps.entrySet().stream().forEach((e) -> { + String key = (String)e.getKey(); + if (key.startsWith("com.sun.management.")) { + addConfigProp(key, e.getValue(), first[0]); + first[0] = false; + } + }); + appendConfigPropsFooter(); + } + + abstract protected void addAgentStatus(boolean enabled); + abstract protected void appendConnectionsHeader(); + abstract protected void appendConnectionsFooter(); + abstract protected void addConnectionDetails(JMXServiceURL u); + abstract protected void appendConnectionHeader(boolean remote); + abstract protected void appendConnectionFooter(boolean remote); + abstract protected void appendConfigPropsHeader(); + abstract protected void appendConfigPropsFooter(); + abstract protected void addConfigProp(String key, Object value, boolean first); + } + + /** + * Free-text status collector strategy implementation + */ + final private static class TextStatusCollector extends StatusCollector { + + @Override + protected void addAgentStatus(boolean enabled) { + sb.append("Agent: ").append(enabled ? "enabled" : "disabled").append('\n'); + } + + @Override + protected void appendConnectionsHeader() { + sb.append('\n'); + } + + @Override + protected void addConnectionDetails(JMXServiceURL u) { + sb.append("Protocol : ").append(u.getProtocol()).append('\n') + .append("Host : ").append(u.getHost()).append('\n') + .append("URL : ").append(u).append('\n'); + } + + @Override + protected void appendConnectionHeader(boolean remote) { + sb.append("Connection Type: ").append(remote ? "remote" : "local").append('\n'); + } + + @Override + protected void appendConfigPropsHeader() { + sb.append("Properties :\n"); + } + + @Override + protected void addConfigProp(String key, Object value, boolean first) { + if (!first) { + sb.append('\n'); + } + sb.append(" ").append(key).append(" = ").append(value); + } + + @Override + protected void appendConnectionsFooter() {} + + @Override + protected void appendConnectionFooter(boolean remote) { + sb.append('\n'); + } + + @Override + protected void appendConfigPropsFooter() {} + } + // management properties private static Properties mgmtProps; @@ -81,6 +201,8 @@ public class Agent { // The only active agent allowed private static JMXConnectorServer jmxServer = null; + // The properties used to configure the server + private static Properties configProps = null; // Parse string com.sun.management.prop=xxx,com.sun.management.prop=yyyy // and return property set if args is null or empty @@ -161,7 +283,7 @@ public class Agent { try { Properties argProps = parseString(args); - Properties configProps = new Properties(); + configProps = new Properties(); // Load the management properties from the config file // if config file is not specified readConfiguration implicitly @@ -228,9 +350,14 @@ public class Agent { // Don't cause any errors. jmxServer.stop(); jmxServer = null; + configProps = null; } } + private static synchronized String getManagementAgentStatus() throws Exception { + return new TextStatusCollector().collect(); + } + private static void startAgent(Properties props) throws Exception { String snmpPort = props.getProperty(SNMP_PORT); String jmxremote = props.getProperty(JMXREMOTE); diff --git a/jdk/src/java.management/share/classes/sun/management/GarbageCollectorImpl.java b/jdk/src/java.management/share/classes/sun/management/GarbageCollectorImpl.java index 251dad43e04..9c1373f854e 100644 --- a/jdk/src/java.management/share/classes/sun/management/GarbageCollectorImpl.java +++ b/jdk/src/java.management/share/classes/sun/management/GarbageCollectorImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,168 +25,31 @@ package sun.management; -import com.sun.management.GarbageCollectorMXBean; -import com.sun.management.GarbageCollectionNotificationInfo; +import java.lang.management.GarbageCollectorMXBean; import java.lang.management.ManagementFactory; -import java.lang.management.MemoryPoolMXBean; -import java.lang.management.MemoryUsage; - -import com.sun.management.GcInfo; -import javax.management.openmbean.CompositeData; -import javax.management.MBeanInfo; -import javax.management.MBeanAttributeInfo; import javax.management.ObjectName; -import javax.management.MBeanNotificationInfo; -import javax.management.Notification; -import javax.management.NotificationFilter; -import javax.management.NotificationListener; -import javax.management.ListenerNotFoundException; - -import java.util.List; -import java.util.ListIterator; -import java.util.Map; /** * Implementation class for the garbage collector. - * Standard and committed hotspot-specific metrics if any. * * ManagementFactory.getGarbageCollectorMXBeans() returns a list * of instances of this class. */ -class GarbageCollectorImpl extends MemoryManagerImpl +public class GarbageCollectorImpl extends MemoryManagerImpl implements GarbageCollectorMXBean { - GarbageCollectorImpl(String name) { + protected GarbageCollectorImpl(String name) { super(name); } + @Override public native long getCollectionCount(); + + @Override public native long getCollectionTime(); - - // The memory pools are static and won't be changed. - // TODO: If the hotspot implementation begins to have pools - // dynamically created and removed, this needs to be modified. - private String[] poolNames = null; - synchronized String[] getAllPoolNames() { - if (poolNames == null) { - List pools = ManagementFactory.getMemoryPoolMXBeans(); - poolNames = new String[pools.size()]; - int i = 0; - for (MemoryPoolMXBean m : pools) { - poolNames[i++] = m.getName(); - } - } - return poolNames; - } - - // Sun JDK extension - private GcInfoBuilder gcInfoBuilder; - - private synchronized GcInfoBuilder getGcInfoBuilder() { - if(gcInfoBuilder == null) { - gcInfoBuilder = new GcInfoBuilder(this, getAllPoolNames()); - } - return gcInfoBuilder; - } - - public GcInfo getLastGcInfo() { - GcInfo info = getGcInfoBuilder().getLastGcInfo(); - return info; - } - - private final static String notifName = - "javax.management.Notification"; - - private final static String[] gcNotifTypes = { - GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION - }; - - private MBeanNotificationInfo[] notifInfo = null; - public MBeanNotificationInfo[] getNotificationInfo() { - synchronized (this) { - if (notifInfo == null) { - notifInfo = new MBeanNotificationInfo[1]; - notifInfo[0] = new MBeanNotificationInfo(gcNotifTypes, - notifName, - "GC Notification"); - } - } - return notifInfo; - } - - private static long seqNumber = 0; - private static long getNextSeqNumber() { - return ++seqNumber; - } - - void createGCNotification(long timestamp, - String gcName, - String gcAction, - String gcCause, - GcInfo gcInfo) { - - if (!hasListeners()) { - return; - } - - Notification notif = new Notification(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION, - getObjectName(), - getNextSeqNumber(), - timestamp, - gcName); - GarbageCollectionNotificationInfo info = - new GarbageCollectionNotificationInfo(gcName, - gcAction, - gcCause, - gcInfo); - - CompositeData cd = - GarbageCollectionNotifInfoCompositeData.toCompositeData(info); - notif.setUserData(cd); - sendNotification(notif); - } - - public synchronized void addNotificationListener(NotificationListener listener, - NotificationFilter filter, - Object handback) - { - boolean before = hasListeners(); - super.addNotificationListener(listener, filter, handback); - boolean after = hasListeners(); - if (!before && after) { - setNotificationEnabled(this, true); - } - } - - public synchronized void removeNotificationListener(NotificationListener listener) - throws ListenerNotFoundException { - boolean before = hasListeners(); - super.removeNotificationListener(listener); - boolean after = hasListeners(); - if (before && !after) { - setNotificationEnabled(this,false); - } - } - - public synchronized void removeNotificationListener(NotificationListener listener, - NotificationFilter filter, - Object handback) - throws ListenerNotFoundException - { - boolean before = hasListeners(); - super.removeNotificationListener(listener,filter,handback); - boolean after = hasListeners(); - if (before && !after) { - setNotificationEnabled(this,false); - } - } - + @Override public ObjectName getObjectName() { return Util.newObjectName(ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE, getName()); } - - native void setNotificationEnabled(GarbageCollectorMXBean gc, - boolean enabled); - } diff --git a/jdk/src/java.management/share/classes/sun/management/LazyCompositeData.java b/jdk/src/java.management/share/classes/sun/management/LazyCompositeData.java index 935f09a156b..8d9c4c03b5f 100644 --- a/jdk/src/java.management/share/classes/sun/management/LazyCompositeData.java +++ b/jdk/src/java.management/share/classes/sun/management/LazyCompositeData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -115,28 +115,28 @@ public abstract class LazyCompositeData protected abstract CompositeData getCompositeData(); // Helper methods - static String getString(CompositeData cd, String itemName) { + public static String getString(CompositeData cd, String itemName) { if (cd == null) throw new IllegalArgumentException("Null CompositeData"); return (String) cd.get(itemName); } - static boolean getBoolean(CompositeData cd, String itemName) { + public static boolean getBoolean(CompositeData cd, String itemName) { if (cd == null) throw new IllegalArgumentException("Null CompositeData"); return ((Boolean) cd.get(itemName)).booleanValue(); } - static long getLong(CompositeData cd, String itemName) { + public static long getLong(CompositeData cd, String itemName) { if (cd == null) throw new IllegalArgumentException("Null CompositeData"); return ((Long) cd.get(itemName)).longValue(); } - static int getInt(CompositeData cd, String itemName) { + public static int getInt(CompositeData cd, String itemName) { if (cd == null) throw new IllegalArgumentException("Null CompositeData"); diff --git a/jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java b/jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java index c06fb71b27d..a8d4279d862 100644 --- a/jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java +++ b/jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,6 @@ package sun.management; import java.lang.management.*; - -import javax.management.DynamicMBean; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.MBeanServer; @@ -38,30 +36,35 @@ import javax.management.RuntimeOperationsException; import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; - import sun.util.logging.LoggingSupport; - import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import com.sun.management.DiagnosticCommandMBean; -import com.sun.management.HotSpotDiagnosticMXBean; /** * ManagementFactoryHelper provides static factory methods to create * instances of the management interface. */ public class ManagementFactoryHelper { + static { + // make sure that the management lib is loaded within + // java.lang.management.ManagementFactory + sun.misc.Unsafe.getUnsafe().ensureClassInitialized(ManagementFactory.class); + } + + private static final VMManagement jvm = new VMManagementImpl(); + private ManagementFactoryHelper() {}; - private static VMManagement jvm; + public static VMManagement getVMManagement() { + return jvm; + } private static ClassLoadingImpl classMBean = null; private static MemoryImpl memoryMBean = null; private static ThreadImpl threadMBean = null; private static RuntimeImpl runtimeMBean = null; private static CompilationImpl compileMBean = null; - private static OperatingSystemImpl osMBean = null; + private static BaseOperatingSystemImpl osMBean = null; public static synchronized ClassLoadingMXBean getClassLoadingMXBean() { if (classMBean == null) { @@ -100,7 +103,7 @@ public class ManagementFactoryHelper { public static synchronized OperatingSystemMXBean getOperatingSystemMXBean() { if (osMBean == null) { - osMBean = new OperatingSystemImpl(jvm); + osMBean = new BaseOperatingSystemImpl(jvm); } return osMBean; } @@ -123,7 +126,7 @@ public class ManagementFactoryHelper { return result; } - public static List getGarbageCollectorMXBeans() { + public static List getGarbageCollectorMXBeans() { MemoryManagerMXBean[] mgrs = MemoryImpl.getMemoryManagers(); List result = new ArrayList<>(mgrs.length); for (MemoryManagerMXBean m : mgrs) { @@ -257,20 +260,11 @@ public class ManagementFactoryHelper { }; } - private static HotSpotDiagnostic hsDiagMBean = null; private static HotspotRuntime hsRuntimeMBean = null; private static HotspotClassLoading hsClassMBean = null; private static HotspotThread hsThreadMBean = null; private static HotspotCompilation hsCompileMBean = null; private static HotspotMemory hsMemoryMBean = null; - private static DiagnosticCommandImpl hsDiagCommandMBean = null; - - public static synchronized HotSpotDiagnosticMXBean getDiagnosticMXBean() { - if (hsDiagMBean == null) { - hsDiagMBean = new HotSpotDiagnostic(); - } - return hsDiagMBean; - } /** * This method is for testing only. @@ -312,14 +306,6 @@ public class ManagementFactoryHelper { return hsMemoryMBean; } - public static synchronized DiagnosticCommandMBean getDiagnosticCommandMBean() { - // Remote Diagnostic Commands may not be supported - if (hsDiagCommandMBean == null && jvm.isRemoteDiagnosticCommandsSupported()) { - hsDiagCommandMBean = new DiagnosticCommandImpl(jvm); - } - return hsDiagCommandMBean; - } - /** * This method is for testing only. */ @@ -374,18 +360,6 @@ public class ManagementFactoryHelper { private final static String HOTSPOT_THREAD_MBEAN_NAME = "sun.management:type=HotspotThreading"; - final static String HOTSPOT_DIAGNOSTIC_COMMAND_MBEAN_NAME = - "com.sun.management:type=DiagnosticCommand"; - - public static HashMap getPlatformDynamicMBeans() { - HashMap map = new HashMap<>(); - DiagnosticCommandMBean diagMBean = getDiagnosticCommandMBean(); - if (diagMBean != null) { - map.put(Util.newObjectName(HOTSPOT_DIAGNOSTIC_COMMAND_MBEAN_NAME), diagMBean); - } - return map; - } - static void registerInternalMBeans(MBeanServer mbs) { // register all internal MBeans if not registered // No exception is thrown if a MBean with that object name @@ -441,17 +415,6 @@ public class ManagementFactoryHelper { } } - static { - AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Void run() { - System.loadLibrary("management"); - return null; - } - }); - jvm = new VMManagementImpl(); - } - public static boolean isThreadSuspended(int state) { return ((state & JMM_THREAD_STATE_FLAG_SUSPENDED) != 0); } @@ -471,4 +434,20 @@ public class ManagementFactoryHelper { private static final int JMM_THREAD_STATE_FLAG_SUSPENDED = 0x00100000; private static final int JMM_THREAD_STATE_FLAG_NATIVE = 0x00400000; + // Invoked by the VM + private static MemoryPoolMXBean createMemoryPool + (String name, boolean isHeap, long uThreshold, long gcThreshold) { + return new MemoryPoolImpl(name, isHeap, uThreshold, gcThreshold); + } + + private static MemoryManagerMXBean createMemoryManager(String name) { + return new MemoryManagerImpl(name); + } + + private static GarbageCollectorMXBean + createGarbageCollector(String name, String type) { + + // ignore type parameter which is for future extension + return new GarbageCollectorImpl(name); + } } diff --git a/jdk/src/java.management/share/classes/sun/management/MappedMXBeanType.java b/jdk/src/java.management/share/classes/sun/management/MappedMXBeanType.java index 04ab87153f8..85cdfdf1833 100644 --- a/jdk/src/java.management/share/classes/sun/management/MappedMXBeanType.java +++ b/jdk/src/java.management/share/classes/sun/management/MappedMXBeanType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,10 +38,8 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; -import javax.management.*; import javax.management.openmbean.*; import static javax.management.openmbean.SimpleType.*; -import com.sun.management.VMOption; /** * A mapped mxbean type maps a Java type to an open type. @@ -113,7 +111,7 @@ public abstract class MappedMXBeanType { return mt; } - static synchronized MappedMXBeanType getMappedType(Type t) + public static synchronized MappedMXBeanType getMappedType(Type t) throws OpenDataException { MappedMXBeanType mt = convertedTypes.get(t); if (mt == null) { @@ -152,7 +150,7 @@ public abstract class MappedMXBeanType { } // Return the mapped open type - OpenType getOpenType() { + public OpenType getOpenType() { return openType; } @@ -177,10 +175,10 @@ public abstract class MappedMXBeanType { // return name of the class or the generic type abstract String getName(); - abstract Object toOpenTypeData(Object javaTypeData) + public abstract Object toOpenTypeData(Object javaTypeData) throws OpenDataException; - abstract Object toJavaTypeData(Object openTypeData) + public abstract Object toJavaTypeData(Object openTypeData) throws OpenDataException, InvalidObjectException; // Basic Types - Classes that do not require data conversion @@ -208,11 +206,11 @@ public abstract class MappedMXBeanType { return basicType.getName(); } - Object toOpenTypeData(Object data) throws OpenDataException { + public Object toOpenTypeData(Object data) throws OpenDataException { return data; } - Object toJavaTypeData(Object data) + public Object toJavaTypeData(Object data) throws OpenDataException, InvalidObjectException { return data; @@ -243,11 +241,11 @@ public abstract class MappedMXBeanType { return enumClass.getName(); } - Object toOpenTypeData(Object data) throws OpenDataException { + public Object toOpenTypeData(Object data) throws OpenDataException { return ((Enum) data).name(); } - Object toJavaTypeData(Object data) + public Object toJavaTypeData(Object data) throws OpenDataException, InvalidObjectException { try { @@ -315,7 +313,7 @@ public abstract class MappedMXBeanType { return arrayClass.getName(); } - Object toOpenTypeData(Object data) throws OpenDataException { + public Object toOpenTypeData(Object data) throws OpenDataException { // If the base element type is a basic type // return the data as no conversion is needed. // Primitive types are not converted to wrappers. @@ -340,7 +338,7 @@ public abstract class MappedMXBeanType { } - Object toJavaTypeData(Object data) + public Object toJavaTypeData(Object data) throws OpenDataException, InvalidObjectException { // If the base element type is a basic type @@ -457,7 +455,7 @@ public abstract class MappedMXBeanType { return typeName; } - Object toOpenTypeData(Object data) throws OpenDataException { + public Object toOpenTypeData(Object data) throws OpenDataException { final List list = (List) data; final Object[] openArray = (Object[]) @@ -470,7 +468,7 @@ public abstract class MappedMXBeanType { return openArray; } - Object toJavaTypeData(Object data) + public Object toJavaTypeData(Object data) throws OpenDataException, InvalidObjectException { final Object[] openArray = (Object[]) data; @@ -538,7 +536,7 @@ public abstract class MappedMXBeanType { return typeName; } - Object toOpenTypeData(Object data) throws OpenDataException { + public Object toOpenTypeData(Object data) throws OpenDataException { final Map map = (Map) data; final TabularType tabularType = (TabularType) openType; final TabularData table = new TabularDataSupport(tabularType); @@ -556,7 +554,7 @@ public abstract class MappedMXBeanType { return table; } - Object toJavaTypeData(Object data) + public Object toJavaTypeData(Object data) throws OpenDataException, InvalidObjectException { final TabularData td = (TabularData) data; @@ -605,8 +603,9 @@ public abstract class MappedMXBeanType { // static class CompositeDataMXBeanType extends MappedMXBeanType { final Class javaClass; - final boolean isCompositeData; + boolean isCompositeData = false; Method fromMethod = null; + Method toMethod = null; CompositeDataMXBeanType(Class c) throws OpenDataException { this.javaClass = c; @@ -624,6 +623,26 @@ public abstract class MappedMXBeanType { // that has no from method to be embeded in another class. } + // check if a static "toCompositeData" method exists + try { + toMethod = AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Method run() throws NoSuchMethodException { + Method m = javaClass.getDeclaredMethod("toCompositeData", javaClass); + if (m != null + && CompositeData.class.isAssignableFrom(m.getReturnType()) + && Modifier.isStatic(m.getModifiers())) { + m.setAccessible(true); + return m; + } else { + return null; + } + } + }); + } catch (PrivilegedActionException e) { + // ignore NoSuchMethodException since we allow classes + // that has no from method to be embeded in another class. + } + if (COMPOSITE_DATA_CLASS.isAssignableFrom(c)) { // c implements CompositeData - set openType to null // defer generating the CompositeType @@ -636,16 +655,16 @@ public abstract class MappedMXBeanType { // Make a CompositeData containing all the getters final Method[] methods = AccessController.doPrivileged(new PrivilegedAction() { - public Method[] run() { - return javaClass.getMethods(); - } - }); + public Method[] run() { + return javaClass.getMethods(); + } + }); final List names = new ArrayList<>(); final List> types = new ArrayList<>(); /* Select public methods that look like "T getX()" or "boolean - isX()", where T is not void and X is not the empty - string. Exclude "Class getClass()" inherited from Object. */ + isX()", where T is not void and X is not the empty + string. Exclude "Class getClass()" inherited from Object. */ for (int i = 0; i < methods.length; i++) { final Method method = methods[i]; final String name = method.getName(); @@ -676,10 +695,10 @@ public abstract class MappedMXBeanType { final String[] nameArray = names.toArray(new String[0]); openType = new CompositeType(c.getName(), - c.getName(), - nameArray, // field names - nameArray, // field descriptions - types.toArray(new OpenType[0])); + c.getName(), + nameArray, // field names + nameArray, // field descriptions + types.toArray(new OpenType[0])); } } @@ -691,7 +710,23 @@ public abstract class MappedMXBeanType { return javaClass.getName(); } - Object toOpenTypeData(Object data) throws OpenDataException { + public Object toOpenTypeData(Object data) throws OpenDataException { + if (toMethod != null) { + try { + return toMethod.invoke(null, data); + } catch (IllegalAccessException e) { + // should never reach here + throw new AssertionError(e); + } catch (InvocationTargetException e) { + final OpenDataException ode + = new OpenDataException("Failed to invoke " + + toMethod.getName() + " to convert " + javaClass.getName() + + " to CompositeData"); + ode.initCause(e); + throw ode; + } + } + if (data instanceof MemoryUsage) { return MemoryUsageCompositeData.toCompositeData((MemoryUsage) data); } @@ -712,10 +747,6 @@ public abstract class MappedMXBeanType { toCompositeData((MemoryNotificationInfo) data); } - if (data instanceof VMOption) { - return VMOptionCompositeData.toCompositeData((VMOption) data); - } - if (isCompositeData) { // Classes that implement CompositeData // @@ -732,7 +763,7 @@ public abstract class MappedMXBeanType { " is not supported for platform MXBeans"); } - Object toJavaTypeData(Object data) + public Object toJavaTypeData(Object data) throws OpenDataException, InvalidObjectException { if (fromMethod == null) { diff --git a/jdk/src/java.management/share/classes/sun/management/NotificationEmitterSupport.java b/jdk/src/java.management/share/classes/sun/management/NotificationEmitterSupport.java index cff7ac39217..a78b3453b0d 100644 --- a/jdk/src/java.management/share/classes/sun/management/NotificationEmitterSupport.java +++ b/jdk/src/java.management/share/classes/sun/management/NotificationEmitterSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,13 +34,12 @@ import javax.management.NotificationListener; import java.util.List; import java.util.ArrayList; -import java.util.ListIterator; import java.util.Collections; /** * Abstract helper class for notification emitter support. */ -abstract class NotificationEmitterSupport implements NotificationEmitter { +public abstract class NotificationEmitterSupport implements NotificationEmitter { protected NotificationEmitterSupport() { } @@ -135,7 +134,7 @@ abstract class NotificationEmitterSupport implements NotificationEmitter { } } - void sendNotification(Notification notification) { + public void sendNotification(Notification notification) { if (notification == null) { return; @@ -162,7 +161,7 @@ abstract class NotificationEmitterSupport implements NotificationEmitter { } } - boolean hasListeners() { + public boolean hasListeners() { synchronized (listenerLock) { return !listenerList.isEmpty(); } diff --git a/jdk/src/java.management/share/classes/sun/management/ThreadImpl.java b/jdk/src/java.management/share/classes/sun/management/ThreadImpl.java index 019646ad4fe..129ecfcc5da 100644 --- a/jdk/src/java.management/share/classes/sun/management/ThreadImpl.java +++ b/jdk/src/java.management/share/classes/sun/management/ThreadImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,20 +26,18 @@ package sun.management; import java.lang.management.ManagementFactory; - import java.lang.management.ThreadInfo; - +import java.lang.management.ThreadMXBean; import javax.management.ObjectName; /** - * Implementation class for the thread subsystem. - * Standard and committed hotspot-specific metrics if any. - * - * ManagementFactory.getThreadMXBean() returns an instance - * of this class. + * Implementation for java.lang.management.ThreadMXBean as well as providing the + * supporting method for com.sun.management.ThreadMXBean. + * The supporting method for com.sun.management.ThreadMXBean can be moved to + * jdk.management in the future. */ -class ThreadImpl implements com.sun.management.ThreadMXBean { +public class ThreadImpl implements ThreadMXBean { private final VMManagement jvm; // default for thread contention monitoring is disabled. @@ -50,32 +48,38 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { /** * Constructor of ThreadImpl class. */ - ThreadImpl(VMManagement vm) { + protected ThreadImpl(VMManagement vm) { this.jvm = vm; this.cpuTimeEnabled = jvm.isThreadCpuTimeEnabled(); this.allocatedMemoryEnabled = jvm.isThreadAllocatedMemoryEnabled(); } + @Override public int getThreadCount() { return jvm.getLiveThreadCount(); } + @Override public int getPeakThreadCount() { return jvm.getPeakThreadCount(); } + @Override public long getTotalStartedThreadCount() { return jvm.getTotalThreadCount(); } + @Override public int getDaemonThreadCount() { return jvm.getDaemonThreadCount(); } + @Override public boolean isThreadContentionMonitoringSupported() { return jvm.isThreadContentionMonitoringSupported(); } + @Override public synchronized boolean isThreadContentionMonitoringEnabled() { if (!isThreadContentionMonitoringSupported()) { throw new UnsupportedOperationException( @@ -84,18 +88,21 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return contentionMonitoringEnabled; } + @Override public boolean isThreadCpuTimeSupported() { return jvm.isOtherThreadCpuTimeSupported(); } + @Override public boolean isCurrentThreadCpuTimeSupported() { return jvm.isCurrentThreadCpuTimeSupported(); } - public boolean isThreadAllocatedMemorySupported() { + protected boolean isThreadAllocatedMemorySupported() { return jvm.isThreadAllocatedMemorySupported(); } + @Override public boolean isThreadCpuTimeEnabled() { if (!isThreadCpuTimeSupported() && !isCurrentThreadCpuTimeSupported()) { @@ -105,7 +112,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return cpuTimeEnabled; } - public boolean isThreadAllocatedMemoryEnabled() { + protected boolean isThreadAllocatedMemoryEnabled() { if (!isThreadAllocatedMemorySupported()) { throw new UnsupportedOperationException( "Thread allocated memory measurement is not supported"); @@ -113,6 +120,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return allocatedMemoryEnabled; } + @Override public long[] getAllThreadIds() { Util.checkMonitorAccess(); @@ -126,6 +134,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return ids; } + @Override public ThreadInfo getThreadInfo(long id) { long[] ids = new long[1]; ids[0] = id; @@ -133,6 +142,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return infos[0]; } + @Override public ThreadInfo getThreadInfo(long id, int maxDepth) { long[] ids = new long[1]; ids[0] = id; @@ -140,6 +150,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return infos[0]; } + @Override public ThreadInfo[] getThreadInfo(long[] ids) { return getThreadInfo(ids, 0); } @@ -157,6 +168,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { } } + @Override public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth) { verifyThreadIds(ids); @@ -165,6 +177,10 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { "Invalid maxDepth parameter: " + maxDepth); } + // ids has been verified to be non-null + // an empty array of ids should return an empty array of ThreadInfos + if (ids.length == 0) return new ThreadInfo[0]; + Util.checkMonitorAccess(); ThreadInfo[] infos = new ThreadInfo[ids.length]; // nulls @@ -176,6 +192,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return infos; } + @Override public void setThreadContentionMonitoringEnabled(boolean enable) { if (!isThreadContentionMonitoringSupported()) { throw new UnsupportedOperationException( @@ -209,6 +226,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return isThreadCpuTimeEnabled(); } + @Override public long getCurrentThreadCpuTime() { if (verifyCurrentThreadCpuTime()) { return getThreadTotalCpuTime0(0); @@ -216,6 +234,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return -1; } + @Override public long getThreadCpuTime(long id) { long[] ids = new long[1]; ids[0] = id; @@ -247,7 +266,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return isThreadCpuTimeEnabled(); } - public long[] getThreadCpuTime(long[] ids) { + protected long[] getThreadCpuTime(long[] ids) { boolean verified = verifyThreadCpuTime(ids); int length = ids.length; @@ -268,6 +287,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return times; } + @Override public long getCurrentThreadUserTime() { if (verifyCurrentThreadCpuTime()) { return getThreadUserCpuTime0(0); @@ -275,6 +295,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return -1; } + @Override public long getThreadUserTime(long id) { long[] ids = new long[1]; ids[0] = id; @@ -282,7 +303,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return times[0]; } - public long[] getThreadUserTime(long[] ids) { + protected long[] getThreadUserTime(long[] ids) { boolean verified = verifyThreadCpuTime(ids); int length = ids.length; @@ -303,6 +324,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return times; } + @Override public void setThreadCpuTimeEnabled(boolean enable) { if (!isThreadCpuTimeSupported() && !isCurrentThreadCpuTimeSupported()) { @@ -320,7 +342,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { } } - public long getThreadAllocatedBytes(long id) { + protected long getThreadAllocatedBytes(long id) { long[] ids = new long[1]; ids[0] = id; final long[] sizes = getThreadAllocatedBytes(ids); @@ -339,7 +361,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return isThreadAllocatedMemoryEnabled(); } - public long[] getThreadAllocatedBytes(long[] ids) { + protected long[] getThreadAllocatedBytes(long[] ids) { boolean verified = verifyThreadAllocatedMemory(ids); long[] sizes = new long[ids.length]; @@ -351,7 +373,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return sizes; } - public void setThreadAllocatedMemoryEnabled(boolean enable) { + protected void setThreadAllocatedMemoryEnabled(boolean enable) { if (!isThreadAllocatedMemorySupported()) { throw new UnsupportedOperationException( "Thread allocated memory measurement is not supported."); @@ -367,6 +389,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { } } + @Override public long[] findMonitorDeadlockedThreads() { Util.checkMonitorAccess(); @@ -383,6 +406,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return ids; } + @Override public long[] findDeadlockedThreads() { if (!isSynchronizerUsageSupported()) { throw new UnsupportedOperationException( @@ -404,15 +428,18 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { return ids; } + @Override public void resetPeakThreadCount() { Util.checkControlAccess(); resetPeakThreadCount0(); } + @Override public boolean isObjectMonitorUsageSupported() { return jvm.isObjectMonitorUsageSupported(); } + @Override public boolean isSynchronizerUsageSupported() { return jvm.isSynchronizerUsageSupported(); } @@ -432,14 +459,20 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { Util.checkMonitorAccess(); } + @Override public ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors, boolean lockedSynchronizers) { verifyThreadIds(ids); + // ids has been verified to be non-null + // an empty array of ids should return an empty array of ThreadInfos + if (ids.length == 0) return new ThreadInfo[0]; + verifyDumpThreads(lockedMonitors, lockedSynchronizers); return dumpThreads0(ids, lockedMonitors, lockedSynchronizers); } + @Override public ThreadInfo[] dumpAllThreads(boolean lockedMonitors, boolean lockedSynchronizers) { verifyDumpThreads(lockedMonitors, lockedSynchronizers); @@ -469,6 +502,7 @@ class ThreadImpl implements com.sun.management.ThreadMXBean { // tid == 0 to reset contention times for all threads private static native void resetContentionTimes0(long tid); + @Override public ObjectName getObjectName() { return Util.newObjectName(ManagementFactory.THREAD_MXBEAN_NAME); } diff --git a/jdk/src/java.management/share/classes/sun/management/Util.java b/jdk/src/java.management/share/classes/sun/management/Util.java index 6350408735e..145749e40f2 100644 --- a/jdk/src/java.management/share/classes/sun/management/Util.java +++ b/jdk/src/java.management/share/classes/sun/management/Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -81,7 +81,7 @@ public class Util { static void checkMonitorAccess() throws SecurityException { checkAccess(monitorPermission); } - static void checkControlAccess() throws SecurityException { + public static void checkControlAccess() throws SecurityException { checkAccess(controlPermission); } } diff --git a/jdk/src/java.management/share/classes/sun/management/spi/PlatformMBeanProvider.java b/jdk/src/java.management/share/classes/sun/management/spi/PlatformMBeanProvider.java index 6f224c95e68..0ce516511bb 100644 --- a/jdk/src/java.management/share/classes/sun/management/spi/PlatformMBeanProvider.java +++ b/jdk/src/java.management/share/classes/sun/management/spi/PlatformMBeanProvider.java @@ -205,7 +205,7 @@ public abstract class PlatformMBeanProvider { * Instantiates a new PlatformMBeanProvider. * * @throws SecurityException if the subclass (and calling code) does not - * have {@code RuntimePermission("sun.management.spi.PlatformMBeanProvider", "subclass")} + * have {@code RuntimePermission("sun.management.spi.PlatformMBeanProvider.subclass")} */ protected PlatformMBeanProvider () { this(checkSubclassPermission()); @@ -226,7 +226,7 @@ public abstract class PlatformMBeanProvider { private static Void checkSubclassPermission() { SecurityManager sm = System.getSecurityManager(); if (sm != null) { - sm.checkPermission(new RuntimePermission(PlatformMBeanProvider.class.getName(), "subclass")); + sm.checkPermission(new RuntimePermission(PlatformMBeanProvider.class.getName()+".subclass")); } return null; } diff --git a/jdk/src/java.management/share/native/libmanagement/GarbageCollectorImpl.c b/jdk/src/java.management/share/native/libmanagement/GarbageCollectorImpl.c index 020335d32ea..3f2e3e75eba 100644 --- a/jdk/src/java.management/share/native/libmanagement/GarbageCollectorImpl.c +++ b/jdk/src/java.management/share/native/libmanagement/GarbageCollectorImpl.c @@ -36,17 +36,3 @@ JNIEXPORT jlong JNICALL Java_sun_management_GarbageCollectorImpl_getCollectionTi (JNIEnv *env, jobject mgr) { return jmm_interface->GetLongAttribute(env, mgr, JMM_GC_TIME_MS); } - - -JNIEXPORT void JNICALL Java_sun_management_GarbageCollectorImpl_setNotificationEnabled -(JNIEnv *env, jobject dummy, jobject gc,jboolean enabled) { - - if (gc == NULL) { - JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean"); - return; - } - if((jmm_version > JMM_VERSION_1_2) - || (jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF)>=1))) { - jmm_interface->SetGCNotificationEnabled(env, gc, enabled); - } -} diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java index da7e55a2d9f..0f263ad3537 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/InterfaceTypeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -130,6 +130,15 @@ final public class InterfaceTypeImpl extends InvokableTypeImpl return null; } + @Override + boolean isAssignableTo(ReferenceType type) { + if (type.name().equals("java.lang.Object")) { + // interfaces are always assignable to j.l.Object + return true; + } + return super.isAssignableTo(type); + } + @Override List interfaces() { return superinterfaces(); @@ -140,4 +149,4 @@ final public class InterfaceTypeImpl extends InvokableTypeImpl // method must be directly in this interface return this.equals(method.declaringType()); } -} \ No newline at end of file +} diff --git a/jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/Jstatd.java b/jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/Jstatd.java index 09a17803cfa..160314aa7a3 100644 --- a/jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/Jstatd.java +++ b/jdk/src/jdk.jvmstat/share/classes/sun/tools/jstatd/Jstatd.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,15 +64,9 @@ public class Jstatd { int localport = (port < 0) ? Registry.REGISTRY_PORT : port; registry = LocateRegistry.createRegistry(localport); bind(name, remoteHost); + } else { + throw e; } - else { - System.out.println("Could not contact registry\n" - + e.getMessage()); - e.printStackTrace(); - } - } catch (RemoteException e) { - System.err.println("Could not bind " + name + " to RMI Registry"); - e.printStackTrace(); } } @@ -142,23 +136,28 @@ public class Jstatd { RemoteHost stub = (RemoteHost) UnicastRemoteObject.exportObject( remoteHost, 0); bind(name.toString(), remoteHost); + System.out.println("jstatd started (bound to " + name.toString() + ")"); + System.out.flush(); } catch (MalformedURLException e) { if (rminame != null) { System.out.println("Bad RMI server name: " + rminame); } else { - System.out.println("Bad RMI URL: " + name + " : " - + e.getMessage()); + System.out.println("Bad RMI URL: " + name); } + e.printStackTrace(System.out); System.exit(1); } catch (java.rmi.ConnectException e) { // could not attach to or create a registry - System.out.println("Could not contact RMI registry\n" - + e.getMessage()); + System.out.println("Could not contact RMI registry"); + e.printStackTrace(System.out); + System.exit(1); + } catch (RemoteException e) { + System.out.println("Could not bind " + name + " to RMI Registry"); + e.printStackTrace(System.out); System.exit(1); } catch (Exception e) { - System.out.println("Could not create remote object\n" - + e.getMessage()); - e.printStackTrace(); + System.out.println("Could not create remote object"); + e.printStackTrace(System.out); System.exit(1); } } diff --git a/jdk/src/java.management/unix/native/libmanagement/LinuxOperatingSystem.c b/jdk/src/jdk.management/linux/native/libmanagement_ext/UnixOperatingSystem.c similarity index 97% rename from jdk/src/java.management/unix/native/libmanagement/LinuxOperatingSystem.c rename to jdk/src/jdk.management/linux/native/libmanagement_ext/UnixOperatingSystem.c index 9029bd0a660..95d3eae2da4 100644 --- a/jdk/src/java.management/unix/native/libmanagement/LinuxOperatingSystem.c +++ b/jdk/src/jdk.management/linux/native/libmanagement_ext/UnixOperatingSystem.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ #include #include #include -#include "sun_management_OperatingSystemImpl.h" +#include "com_sun_management_internal_OperatingSystemImpl.h" struct ticks { uint64_t used; @@ -311,7 +311,7 @@ double get_process_load() { } JNIEXPORT jdouble JNICALL -Java_sun_management_OperatingSystemImpl_getSystemCpuLoad0 +Java_com_sun_management_internal_OperatingSystemImpl_getSystemCpuLoad0 (JNIEnv *env, jobject dummy) { if(perfInit() == 0) { @@ -322,7 +322,7 @@ Java_sun_management_OperatingSystemImpl_getSystemCpuLoad0 } JNIEXPORT jdouble JNICALL -Java_sun_management_OperatingSystemImpl_getProcessCpuLoad0 +Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuLoad0 (JNIEnv *env, jobject dummy) { if(perfInit() == 0) { diff --git a/jdk/src/java.management/unix/native/libmanagement/MacosxOperatingSystem.c b/jdk/src/jdk.management/macosx/native/libmanagement_ext/UnixOperatingSystem.c similarity index 94% rename from jdk/src/java.management/unix/native/libmanagement/MacosxOperatingSystem.c rename to jdk/src/jdk.management/macosx/native/libmanagement_ext/UnixOperatingSystem.c index 7771ccd5cb4..edfa7649d46 100644 --- a/jdk/src/java.management/unix/native/libmanagement/MacosxOperatingSystem.c +++ b/jdk/src/jdk.management/macosx/native/libmanagement_ext/UnixOperatingSystem.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ * questions. */ -#include "sun_management_OperatingSystemImpl.h" +#include "com_sun_management_internal_OperatingSystemImpl.h" #include #include @@ -32,7 +32,7 @@ #include "jvm.h" JNIEXPORT jdouble JNICALL -Java_sun_management_OperatingSystemImpl_getSystemCpuLoad0 +Java_com_sun_management_internal_OperatingSystemImpl_getSystemCpuLoad0 (JNIEnv *env, jobject dummy) { // This code is influenced by the darwin top source @@ -84,7 +84,7 @@ Java_sun_management_OperatingSystemImpl_getSystemCpuLoad0 JNIEXPORT jdouble JNICALL -Java_sun_management_OperatingSystemImpl_getProcessCpuLoad0 +Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuLoad0 (JNIEnv *env, jobject dummy) { // This code is influenced by the darwin top source diff --git a/jdk/src/java.management/share/classes/META-INF/services/sun.management.spi.PlatformMBeanProvider b/jdk/src/jdk.management/share/classes/META-INF/services/sun.management.spi.PlatformMBeanProvider similarity index 100% rename from jdk/src/java.management/share/classes/META-INF/services/sun.management.spi.PlatformMBeanProvider rename to jdk/src/jdk.management/share/classes/META-INF/services/sun.management.spi.PlatformMBeanProvider diff --git a/jdk/src/java.management/share/classes/com/sun/management/DiagnosticCommandMBean.java b/jdk/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java similarity index 100% rename from jdk/src/java.management/share/classes/com/sun/management/DiagnosticCommandMBean.java rename to jdk/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java diff --git a/jdk/src/java.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java b/jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java similarity index 97% rename from jdk/src/java.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java rename to jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java index 68e88b79544..8396a850202 100644 --- a/jdk/src/java.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectionNotificationInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,10 @@ package com.sun.management; -import javax.management.Notification; import javax.management.openmbean.CompositeData; import javax.management.openmbean.CompositeDataView; import javax.management.openmbean.CompositeType; -import java.util.Collection; -import java.util.Collections; -import sun.management.GarbageCollectionNotifInfoCompositeData; +import com.sun.management.internal.GarbageCollectionNotifInfoCompositeData; /** * The information about a garbage collection diff --git a/jdk/src/java.management/share/classes/com/sun/management/GarbageCollectorMXBean.java b/jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectorMXBean.java similarity index 100% rename from jdk/src/java.management/share/classes/com/sun/management/GarbageCollectorMXBean.java rename to jdk/src/jdk.management/share/classes/com/sun/management/GarbageCollectorMXBean.java diff --git a/jdk/src/java.management/share/classes/com/sun/management/GcInfo.java b/jdk/src/jdk.management/share/classes/com/sun/management/GcInfo.java similarity index 98% rename from jdk/src/java.management/share/classes/com/sun/management/GcInfo.java rename to jdk/src/jdk.management/share/classes/com/sun/management/GcInfo.java index 5dc732d84f8..f256b086a88 100644 --- a/jdk/src/java.management/share/classes/com/sun/management/GcInfo.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/GcInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,9 +33,8 @@ import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import java.util.List; -import sun.management.GcInfoCompositeData; -import sun.management.GcInfoBuilder; +import com.sun.management.internal.GcInfoCompositeData; +import com.sun.management.internal.GcInfoBuilder; /** * Garbage collection information. It contains the following diff --git a/jdk/src/java.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java b/jdk/src/jdk.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java similarity index 100% rename from jdk/src/java.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java rename to jdk/src/jdk.management/share/classes/com/sun/management/HotSpotDiagnosticMXBean.java diff --git a/jdk/src/java.management/share/classes/com/sun/management/OperatingSystemMXBean.java b/jdk/src/jdk.management/share/classes/com/sun/management/OperatingSystemMXBean.java similarity index 100% rename from jdk/src/java.management/share/classes/com/sun/management/OperatingSystemMXBean.java rename to jdk/src/jdk.management/share/classes/com/sun/management/OperatingSystemMXBean.java diff --git a/jdk/src/java.management/share/classes/com/sun/management/ThreadMXBean.java b/jdk/src/jdk.management/share/classes/com/sun/management/ThreadMXBean.java similarity index 100% rename from jdk/src/java.management/share/classes/com/sun/management/ThreadMXBean.java rename to jdk/src/jdk.management/share/classes/com/sun/management/ThreadMXBean.java diff --git a/jdk/src/java.management/share/classes/com/sun/management/UnixOperatingSystemMXBean.java b/jdk/src/jdk.management/share/classes/com/sun/management/UnixOperatingSystemMXBean.java similarity index 100% rename from jdk/src/java.management/share/classes/com/sun/management/UnixOperatingSystemMXBean.java rename to jdk/src/jdk.management/share/classes/com/sun/management/UnixOperatingSystemMXBean.java diff --git a/jdk/src/java.management/share/classes/com/sun/management/VMOption.java b/jdk/src/jdk.management/share/classes/com/sun/management/VMOption.java similarity index 96% rename from jdk/src/java.management/share/classes/com/sun/management/VMOption.java rename to jdk/src/jdk.management/share/classes/com/sun/management/VMOption.java index b1ba961923d..bebe1974010 100644 --- a/jdk/src/java.management/share/classes/com/sun/management/VMOption.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/VMOption.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ package com.sun.management; -import sun.management.VMOptionCompositeData; +import com.sun.management.internal.VMOptionCompositeData; import javax.management.openmbean.CompositeData; /** @@ -241,5 +241,8 @@ public class VMOption { } - + // for sun.management.MappedMXBeanType + static CompositeData toCompositeData(VMOption option) { + return VMOptionCompositeData.toCompositeData(option); + } } diff --git a/jdk/src/java.management/share/classes/sun/management/DiagnosticCommandArgumentInfo.java b/jdk/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandArgumentInfo.java similarity index 97% rename from jdk/src/java.management/share/classes/sun/management/DiagnosticCommandArgumentInfo.java rename to jdk/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandArgumentInfo.java index 1ad267b1ecf..3c956a49172 100644 --- a/jdk/src/java.management/share/classes/sun/management/DiagnosticCommandArgumentInfo.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandArgumentInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ * questions. */ -package sun.management; +package com.sun.management.internal; /** * Diagnostic Command Argument information. It contains the description diff --git a/jdk/src/java.management/share/classes/sun/management/DiagnosticCommandImpl.java b/jdk/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandImpl.java similarity index 90% rename from jdk/src/java.management/share/classes/sun/management/DiagnosticCommandImpl.java rename to jdk/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandImpl.java index 27730898f1b..a0718a3c2f3 100644 --- a/jdk/src/java.management/share/classes/sun/management/DiagnosticCommandImpl.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,21 +23,41 @@ * questions. */ -package sun.management; +package com.sun.management.internal; import com.sun.management.DiagnosticCommandMBean; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.security.Permission; import java.util.*; -import javax.management.*; +import javax.management.Attribute; +import javax.management.AttributeList; +import javax.management.AttributeNotFoundException; +import javax.management.Descriptor; +import javax.management.ImmutableDescriptor; +import javax.management.InvalidAttributeValueException; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanException; +import javax.management.MBeanInfo; +import javax.management.MBeanNotificationInfo; +import javax.management.MBeanOperationInfo; +import javax.management.MBeanParameterInfo; +import javax.management.MalformedObjectNameException; +import javax.management.Notification; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.ObjectName; +import javax.management.ReflectionException; +import sun.management.ManagementFactoryHelper; +import sun.management.NotificationEmitterSupport; +import sun.management.VMManagement; /** * Implementation class for the diagnostic commands subsystem. * * @since 1.8 */ -class DiagnosticCommandImpl extends NotificationEmitterSupport +public class DiagnosticCommandImpl extends NotificationEmitterSupport implements DiagnosticCommandMBean { private final VMManagement jvm; @@ -45,6 +65,17 @@ class DiagnosticCommandImpl extends NotificationEmitterSupport private static final String strClassName = "".getClass().getName(); private static final String strArrayClassName = String[].class.getName(); private final boolean isSupported; + private static DiagnosticCommandImpl diagCommandMBean = null; + + static synchronized DiagnosticCommandMBean getDiagnosticCommandMBean() { + VMManagement jvm = ManagementFactoryHelper.getVMManagement(); + + // Remote Diagnostic Commands may not be supported + if (diagCommandMBean == null && jvm.isRemoteDiagnosticCommandsSupported()) { + diagCommandMBean = new DiagnosticCommandImpl(jvm); + } + return diagCommandMBean; + } @Override public Object getAttribute(String attribute) throws AttributeNotFoundException, @@ -327,7 +358,7 @@ class DiagnosticCommandImpl extends NotificationEmitterSupport } ObjectName on = null; try { - on = ObjectName.getInstance(ManagementFactoryHelper.HOTSPOT_DIAGNOSTIC_COMMAND_MBEAN_NAME); + on = ObjectName.getInstance(PlatformMBeanProviderImpl.DIAGNOSTIC_COMMAND_MBEAN_NAME); } catch (MalformedObjectNameException e) { } Notification notif = new Notification("jmx.mbean.info.changed", on, diff --git a/jdk/src/java.management/share/classes/sun/management/DiagnosticCommandInfo.java b/jdk/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandInfo.java similarity index 97% rename from jdk/src/java.management/share/classes/sun/management/DiagnosticCommandInfo.java rename to jdk/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandInfo.java index 08541b3d276..1184a40b64c 100644 --- a/jdk/src/java.management/share/classes/sun/management/DiagnosticCommandInfo.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ * questions. */ -package sun.management; +package com.sun.management.internal; import java.util.List; diff --git a/jdk/src/java.management/share/classes/sun/management/Flag.java b/jdk/src/jdk.management/share/classes/com/sun/management/internal/Flag.java similarity index 97% rename from jdk/src/java.management/share/classes/sun/management/Flag.java rename to jdk/src/jdk.management/share/classes/com/sun/management/internal/Flag.java index 52da43e8408..3b5402fb040 100644 --- a/jdk/src/java.management/share/classes/sun/management/Flag.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/Flag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ * questions. */ -package sun.management; +package com.sun.management.internal; import java.util.*; import com.sun.management.VMOption; diff --git a/jdk/src/java.management/share/classes/sun/management/GarbageCollectionNotifInfoCompositeData.java b/jdk/src/jdk.management/share/classes/com/sun/management/internal/GarbageCollectionNotifInfoCompositeData.java similarity index 96% rename from jdk/src/java.management/share/classes/sun/management/GarbageCollectionNotifInfoCompositeData.java rename to jdk/src/jdk.management/share/classes/com/sun/management/internal/GarbageCollectionNotifInfoCompositeData.java index 722c0dfc55f..ff11d7b5aef 100644 --- a/jdk/src/java.management/share/classes/sun/management/GarbageCollectionNotifInfoCompositeData.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/GarbageCollectionNotifInfoCompositeData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,11 +23,10 @@ * questions. */ -package sun.management; +package com.sun.management.internal; import com.sun.management.GarbageCollectionNotificationInfo; import com.sun.management.GcInfo; -import java.lang.reflect.Method; import javax.management.openmbean.CompositeData; import javax.management.openmbean.CompositeType; import javax.management.openmbean.CompositeDataSupport; @@ -38,6 +37,9 @@ import java.security.AccessController; import java.security.PrivilegedAction; import java.lang.reflect.Field; import java.util.HashMap; +import sun.management.LazyCompositeData; +import static sun.management.LazyCompositeData.getString; +import sun.management.Util; /** * A CompositeData for GarbageCollectionNotificationInfo for the local management support. @@ -95,7 +97,7 @@ public class GarbageCollectionNotifInfoCompositeData extends LazyCompositeData { compositeTypeByBuilder.put(builder,gict); } catch (OpenDataException e) { // shouldn't reach here - throw Util.newException(e); + throw new RuntimeException(e); } } } @@ -205,7 +207,7 @@ public class GarbageCollectionNotifInfoCompositeData extends LazyCompositeData { baseGcNotifInfoItemTypes); } catch (OpenDataException e) { // shouldn't reach here - throw Util.newException(e); + throw new RuntimeException(e); } } return baseGcNotifInfoCompositeType; diff --git a/jdk/src/jdk.management/share/classes/com/sun/management/internal/GarbageCollectorExtImpl.java b/jdk/src/jdk.management/share/classes/com/sun/management/internal/GarbageCollectorExtImpl.java new file mode 100644 index 00000000000..8e0512dde5f --- /dev/null +++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/GarbageCollectorExtImpl.java @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.management.internal; + +import com.sun.management.GarbageCollectionNotificationInfo; +import com.sun.management.GarbageCollectorMXBean; +import com.sun.management.GcInfo; +import java.lang.management.ManagementFactory; +import java.lang.management.MemoryPoolMXBean; +import java.util.List; +import javax.management.ListenerNotFoundException; +import javax.management.MBeanNotificationInfo; +import javax.management.Notification; +import javax.management.NotificationFilter; +import javax.management.NotificationListener; +import javax.management.openmbean.CompositeData; +import sun.management.GarbageCollectorImpl; + +/** + * Implementation class for the garbage collector. + * Standard and committed hotspot-specific metrics if any. + * + * ManagementFactory.getGarbageCollectorMXBeans() returns a list + * of instances of this class. + */ +public class GarbageCollectorExtImpl extends GarbageCollectorImpl + implements GarbageCollectorMXBean { + + public GarbageCollectorExtImpl(String name) { + super(name); + } + + // The memory pools are static and won't be changed. + // TODO: If the hotspot implementation begins to have pools + // dynamically created and removed, this needs to be modified. + private String[] poolNames = null; + private synchronized String[] getAllPoolNames() { + if (poolNames == null) { + List pools = ManagementFactory.getMemoryPoolMXBeans(); + poolNames = new String[pools.size()]; + int i = 0; + for (MemoryPoolMXBean m : pools) { + poolNames[i++] = m.getName(); + } + } + return poolNames; + } + + public GcInfo getLastGcInfo() { + GcInfo info = getGcInfoBuilder().getLastGcInfo(); + return info; + } + + private final static String notifName = + "javax.management.Notification"; + + private final static String[] gcNotifTypes = { + GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION + }; + + private MBeanNotificationInfo[] notifInfo = null; + public MBeanNotificationInfo[] getNotificationInfo() { + synchronized (this) { + if (notifInfo == null) { + notifInfo = new MBeanNotificationInfo[1]; + notifInfo[0] = new MBeanNotificationInfo(gcNotifTypes, + notifName, + "GC Notification"); + } + } + return notifInfo; + } + + private static long seqNumber = 0; + private static long getNextSeqNumber() { + return ++seqNumber; + } + + protected void createGCNotification(long timestamp, + String gcName, + String gcAction, + String gcCause, + GcInfo gcInfo) { + if (!hasListeners()) { + return; + } + Notification notif = new Notification(GarbageCollectionNotificationInfo.GARBAGE_COLLECTION_NOTIFICATION, + getObjectName(), + getNextSeqNumber(), + timestamp, + gcName); + GarbageCollectionNotificationInfo info = + new GarbageCollectionNotificationInfo(gcName, + gcAction, + gcCause, + gcInfo); + + CompositeData cd = + GarbageCollectionNotifInfoCompositeData.toCompositeData(info); + notif.setUserData(cd); + sendNotification(notif); + } + + public synchronized void addNotificationListener(NotificationListener listener, + NotificationFilter filter, + Object handback) + { + boolean before = hasListeners(); + super.addNotificationListener(listener, filter, handback); + boolean after = hasListeners(); + if (!before && after) { + setNotificationEnabled(this, true); + } + } + + public synchronized void removeNotificationListener(NotificationListener listener) + throws ListenerNotFoundException { + boolean before = hasListeners(); + super.removeNotificationListener(listener); + boolean after = hasListeners(); + + if (before && !after) { + setNotificationEnabled(this,false); + } + } + + public synchronized void removeNotificationListener(NotificationListener listener, + NotificationFilter filter, + Object handback) + throws ListenerNotFoundException + { + boolean before = hasListeners(); + super.removeNotificationListener(listener,filter,handback); + boolean after = hasListeners(); + if (before && !after) { + setNotificationEnabled(this,false); + } + } + + private GcInfoBuilder gcInfoBuilder; + // Invoked also by the VM + private synchronized GcInfoBuilder getGcInfoBuilder() { + if(gcInfoBuilder == null) { + gcInfoBuilder = new GcInfoBuilder(this, getAllPoolNames()); + } + return gcInfoBuilder; + } + + private native void setNotificationEnabled(GarbageCollectorMXBean gc, + boolean enabled); + + // Invoked by the VM + private static java.lang.management.GarbageCollectorMXBean + createGarbageCollector(String name, String type) { + + return new GarbageCollectorExtImpl(name); + } +} diff --git a/jdk/src/java.management/share/classes/sun/management/GcInfoBuilder.java b/jdk/src/jdk.management/share/classes/com/sun/management/internal/GcInfoBuilder.java similarity index 95% rename from jdk/src/java.management/share/classes/sun/management/GcInfoBuilder.java rename to jdk/src/jdk.management/share/classes/com/sun/management/internal/GcInfoBuilder.java index b503df57ad9..ab5f795f147 100644 --- a/jdk/src/java.management/share/classes/sun/management/GcInfoBuilder.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/GcInfoBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,20 +22,16 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package sun.management; +package com.sun.management.internal; import java.lang.management.GarbageCollectorMXBean; import java.lang.management.MemoryUsage; import javax.management.openmbean.OpenType; import javax.management.openmbean.SimpleType; -import javax.management.openmbean.TabularType; -import javax.management.openmbean.TabularData; -import javax.management.openmbean.TabularDataSupport; import javax.management.openmbean.CompositeType; -import javax.management.openmbean.CompositeData; -import javax.management.openmbean.CompositeDataSupport; import javax.management.openmbean.OpenDataException; import com.sun.management.GcInfo; +import sun.management.Util; /** * Helper class to build composite data. @@ -164,7 +160,7 @@ public class GcInfoBuilder { allItemTypes); } catch (OpenDataException e) { // shouldn't reach here - throw Util.newException(e); + throw new RuntimeException(e); } gcInfoCompositeType = gict; diff --git a/jdk/src/java.management/share/classes/sun/management/GcInfoCompositeData.java b/jdk/src/jdk.management/share/classes/com/sun/management/internal/GcInfoCompositeData.java similarity index 97% rename from jdk/src/java.management/share/classes/sun/management/GcInfoCompositeData.java rename to jdk/src/jdk.management/share/classes/com/sun/management/internal/GcInfoCompositeData.java index b1cb38e16b1..67444a4b5d6 100644 --- a/jdk/src/java.management/share/classes/sun/management/GcInfoCompositeData.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/GcInfoCompositeData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,16 +23,12 @@ * questions. */ -package sun.management; +package com.sun.management.internal; import java.lang.management.MemoryUsage; import java.lang.reflect.Method; import java.lang.reflect.Field; -import java.util.Iterator; import java.util.Map; -import java.util.HashMap; -import java.util.List; -import java.util.Collections; import java.io.InvalidObjectException; import javax.management.openmbean.CompositeType; import javax.management.openmbean.CompositeData; @@ -42,9 +38,12 @@ import javax.management.openmbean.SimpleType; import javax.management.openmbean.OpenType; import javax.management.openmbean.OpenDataException; import com.sun.management.GcInfo; -import com.sun.management.GarbageCollectionNotificationInfo; import java.security.AccessController; import java.security.PrivilegedAction; +import sun.management.LazyCompositeData; +import static sun.management.LazyCompositeData.getLong; +import sun.management.MappedMXBeanType; +import sun.management.Util; /** * A CompositeData for GcInfo for the local management support. @@ -266,7 +265,7 @@ public class GcInfoCompositeData extends LazyCompositeData { getBaseGcInfoItemTypes()); } catch (OpenDataException e) { // shouldn't reach here - throw Util.newException(e); + throw new RuntimeException(e); } } return baseGcInfoCompositeType; diff --git a/jdk/src/java.management/share/classes/sun/management/HotSpotDiagnostic.java b/jdk/src/jdk.management/share/classes/com/sun/management/internal/HotSpotDiagnostic.java similarity index 97% rename from jdk/src/java.management/share/classes/sun/management/HotSpotDiagnostic.java rename to jdk/src/jdk.management/share/classes/com/sun/management/internal/HotSpotDiagnostic.java index 7c39ea7e9d3..5b9d8efdafc 100644 --- a/jdk/src/java.management/share/classes/sun/management/HotSpotDiagnostic.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/HotSpotDiagnostic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ * questions. */ -package sun.management; +package com.sun.management.internal; import java.io.IOException; import java.util.ArrayList; @@ -32,6 +32,7 @@ import javax.management.ObjectName; import com.sun.management.HotSpotDiagnosticMXBean; import com.sun.management.VMOption; +import sun.management.Util; /** * Implementation of the diagnostic MBean for Hotspot VM. diff --git a/jdk/src/jdk.management/share/classes/com/sun/management/internal/HotSpotThreadImpl.java b/jdk/src/jdk.management/share/classes/com/sun/management/internal/HotSpotThreadImpl.java new file mode 100644 index 00000000000..e31947e4647 --- /dev/null +++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/HotSpotThreadImpl.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.sun.management.internal; + +import com.sun.management.ThreadMXBean; +import sun.management.ManagementFactoryHelper; +import sun.management.ThreadImpl; +import sun.management.VMManagement; + +/** + * + */ +public class HotSpotThreadImpl extends ThreadImpl implements ThreadMXBean { + public HotSpotThreadImpl(VMManagement vm) { + super(ManagementFactoryHelper.getVMManagement()); + } + + @Override + public boolean isThreadAllocatedMemorySupported() { + return super.isThreadAllocatedMemorySupported(); + } + + @Override + public boolean isThreadAllocatedMemoryEnabled() { + return super.isThreadAllocatedMemoryEnabled(); + } + + @Override + public long[] getThreadCpuTime(long[] ids) { + return super.getThreadCpuTime(ids); + } + + @Override + public long[] getThreadUserTime(long[] ids) { + return super.getThreadUserTime(ids); + } + + @Override + public long getThreadAllocatedBytes(long id) { + return super.getThreadAllocatedBytes(id); + } + + @Override + public long[] getThreadAllocatedBytes(long[] ids) { + return super.getThreadAllocatedBytes(ids); + } + + @Override + public void setThreadAllocatedMemoryEnabled(boolean enable) { + super.setThreadAllocatedMemoryEnabled(enable); + } +} diff --git a/jdk/src/java.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java b/jdk/src/jdk.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java similarity index 63% rename from jdk/src/java.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java rename to jdk/src/jdk.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java index 42d41b65992..24fbbb54c93 100644 --- a/jdk/src/java.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java @@ -24,7 +24,14 @@ */ package com.sun.management.internal; +import com.sun.management.DiagnosticCommandMBean; +import com.sun.management.HotSpotDiagnosticMXBean; +import com.sun.management.ThreadMXBean; import java.lang.management.ManagementFactory; +import java.lang.management.MemoryManagerMXBean; +import java.lang.management.OperatingSystemMXBean; +import java.security.AccessController; +import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -34,12 +41,23 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; import javax.management.DynamicMBean; -import javax.management.ObjectName; import sun.management.ManagementFactoryHelper; import sun.management.spi.PlatformMBeanProvider; public final class PlatformMBeanProviderImpl extends PlatformMBeanProvider { + final static String DIAGNOSTIC_COMMAND_MBEAN_NAME = + "com.sun.management:type=DiagnosticCommand"; + private final List> mxbeanList; + private static HotSpotDiagnostic hsDiagMBean = null; + private static OperatingSystemMXBean osMBean = null; + + static { + AccessController.doPrivileged((PrivilegedAction) () -> { + System.loadLibrary("management_ext"); + return null; + }); + } public PlatformMBeanProviderImpl() { mxbeanList = Collections.unmodifiableList(init()); @@ -55,7 +73,7 @@ public final class PlatformMBeanProviderImpl extends PlatformMBeanProvider { /** * Garbage Collector in the Java virtual machine. */ - initMBeanList.add(new PlatformComponent() { + initMBeanList.add(new PlatformComponent() { private final Set garbageCollectorMXBeanInterfaceNames = Collections.unmodifiableSet( Stream.of("java.lang.management.MemoryManagerMXBean", @@ -64,8 +82,8 @@ public final class PlatformMBeanProviderImpl extends PlatformMBeanProvider { .collect(Collectors.toSet())); @Override - public Set> mbeanInterfaces() { - return Stream.of(java.lang.management.MemoryManagerMXBean.class, + public Set> mbeanInterfaces() { + return Stream.of(MemoryManagerMXBean.class, java.lang.management.GarbageCollectorMXBean.class, com.sun.management.GarbageCollectorMXBean.class) .collect(Collectors.toSet()); @@ -87,27 +105,67 @@ public final class PlatformMBeanProviderImpl extends PlatformMBeanProvider { } @Override - public Map nameToMBeanMap() { + public Map nameToMBeanMap() { List list - = ManagementFactoryHelper.getGarbageCollectorMXBeans();; - Map map; + = ManagementFactoryHelper.getGarbageCollectorMXBeans(); + Map map; if (list.isEmpty()) { - map = Collections.emptyMap(); + map = Collections.emptyMap(); } else { map = new HashMap<>(list.size()); - for (java.lang.management.MemoryManagerMXBean gcm : list) { + for (MemoryManagerMXBean gcm : list) { map.put(gcm.getObjectName().getCanonicalName(), gcm); } } + return map; } }); + /** + * Threading system of the Java virtual machine. + */ + initMBeanList.add(new PlatformComponent() { + private final Set threadMXBeanInterfaceNames + = Collections.unmodifiableSet( + Stream.of("java.lang.management.ThreadMXBean", + "com.sun.management.ThreadMXBean") + .collect(Collectors.toSet())); + private ThreadMXBean threadMBean = null; + + @Override + public Set> mbeanInterfaces() { + return Stream.of(java.lang.management.ThreadMXBean.class, + com.sun.management.ThreadMXBean.class) + .collect(Collectors.toSet()); + } + + @Override + public Set mbeanInterfaceNames() { + return threadMXBeanInterfaceNames; + } + + @Override + public String getObjectNamePattern() { + return ManagementFactory.THREAD_MXBEAN_NAME; + } + + @Override + public synchronized Map nameToMBeanMap() { + if (threadMBean == null) { + threadMBean = new HotSpotThreadImpl(ManagementFactoryHelper.getVMManagement()); + } + return Collections.singletonMap( + ManagementFactory.THREAD_MXBEAN_NAME, + threadMBean); + } + }); + /** * OperatingSystemMXBean */ - initMBeanList.add(new PlatformComponent() { + initMBeanList.add(new PlatformComponent() { private final Set operatingSystemMXBeanInterfaceNames = Collections.unmodifiableSet( Stream.of("java.lang.management.OperatingSystemMXBean", @@ -116,7 +174,7 @@ public final class PlatformMBeanProviderImpl extends PlatformMBeanProvider { .collect(Collectors.toSet())); @Override - public Set> mbeanInterfaces() { + public Set> mbeanInterfaces() { return Stream.of(java.lang.management.OperatingSystemMXBean.class, com.sun.management.OperatingSystemMXBean.class, com.sun.management.UnixOperatingSystemMXBean.class) @@ -137,7 +195,7 @@ public final class PlatformMBeanProviderImpl extends PlatformMBeanProvider { public Map nameToMBeanMap() { return Collections.singletonMap( ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME, - ManagementFactoryHelper.getOperatingSystemMXBean()); + getOperatingSystemMXBean()); } }); @@ -146,7 +204,8 @@ public final class PlatformMBeanProviderImpl extends PlatformMBeanProvider { */ initMBeanList.add(new PlatformComponent() { private final Set hotSpotDiagnosticMXBeanInterfaceNames = - Collections.unmodifiableSet(Collections.singleton("com.sun.management.HotSpotDiagnosticMXBean")); + Collections.unmodifiableSet(Collections.singleton( + "com.sun.management.HotSpotDiagnosticMXBean")); @Override public Set> mbeanInterfaces() { @@ -167,19 +226,20 @@ public final class PlatformMBeanProviderImpl extends PlatformMBeanProvider { public Map nameToMBeanMap() { return Collections.singletonMap( "com.sun.management:type=HotSpotDiagnostic", - ManagementFactoryHelper.getDiagnosticMXBean()); + getDiagnosticMXBean()); } }); /** - * DynamicMBean + * Diagnostic command MBean */ - HashMap dynmbeans - = ManagementFactoryHelper.getPlatformDynamicMBeans(); - final Set dynamicMBeanInterfaceNames = - Collections.unmodifiableSet(Collections.singleton("javax.management.DynamicMBean")); - for (Map.Entry e : dynmbeans.entrySet()) { + DiagnosticCommandMBean diagMBean = DiagnosticCommandImpl.getDiagnosticCommandMBean(); + if (diagMBean != null) { initMBeanList.add(new PlatformComponent() { + final Set dynamicMBeanInterfaceNames + = Collections.unmodifiableSet(Collections.singleton( + "javax.management.DynamicMBean")); + @Override public Set mbeanInterfaceNames() { return dynamicMBeanInterfaceNames; @@ -187,23 +247,39 @@ public final class PlatformMBeanProviderImpl extends PlatformMBeanProvider { @Override public Set> mbeanInterfaces() { - return Collections.emptySet(); // DynamicMBean cannot be used to find an MBean by ManagementFactory + // DynamicMBean cannot be used to find an MBean by ManagementFactory + return Collections.emptySet(); } @Override public String getObjectNamePattern() { - return e.getKey().getCanonicalName(); + return DIAGNOSTIC_COMMAND_MBEAN_NAME; } @Override public Map nameToMBeanMap() { return Collections.singletonMap( - e.getKey().getCanonicalName(), - e.getValue()); + DIAGNOSTIC_COMMAND_MBEAN_NAME, + diagMBean); } }); } + initMBeanList.trimToSize(); return initMBeanList; } + + private static synchronized HotSpotDiagnosticMXBean getDiagnosticMXBean() { + if (hsDiagMBean == null) { + hsDiagMBean = new HotSpotDiagnostic(); + } + return hsDiagMBean; + } + + private static synchronized OperatingSystemMXBean getOperatingSystemMXBean() { + if (osMBean == null) { + osMBean = new OperatingSystemImpl(ManagementFactoryHelper.getVMManagement()); + } + return osMBean; + } } diff --git a/jdk/src/java.management/share/classes/sun/management/VMOptionCompositeData.java b/jdk/src/jdk.management/share/classes/com/sun/management/internal/VMOptionCompositeData.java similarity index 96% rename from jdk/src/java.management/share/classes/sun/management/VMOptionCompositeData.java rename to jdk/src/jdk.management/share/classes/com/sun/management/internal/VMOptionCompositeData.java index 6eeac787000..9ca81a4d6ea 100644 --- a/jdk/src/java.management/share/classes/sun/management/VMOptionCompositeData.java +++ b/jdk/src/jdk.management/share/classes/com/sun/management/internal/VMOptionCompositeData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ * questions. */ -package sun.management; +package com.sun.management.internal; import com.sun.management.VMOption; import com.sun.management.VMOption.Origin; @@ -31,6 +31,8 @@ import javax.management.openmbean.CompositeType; import javax.management.openmbean.CompositeData; import javax.management.openmbean.CompositeDataSupport; import javax.management.openmbean.OpenDataException; +import sun.management.LazyCompositeData; +import sun.management.MappedMXBeanType; /** * A CompositeData for VMOption for the local management support. diff --git a/jdk/src/java.management/share/classes/com/sun/management/package-info.java b/jdk/src/jdk.management/share/classes/com/sun/management/package-info.java similarity index 100% rename from jdk/src/java.management/share/classes/com/sun/management/package-info.java rename to jdk/src/jdk.management/share/classes/com/sun/management/package-info.java diff --git a/jdk/src/java.management/share/native/libmanagement/DiagnosticCommandImpl.c b/jdk/src/jdk.management/share/native/libmanagement_ext/DiagnosticCommandImpl.c similarity index 89% rename from jdk/src/java.management/share/native/libmanagement/DiagnosticCommandImpl.c rename to jdk/src/jdk.management/share/native/libmanagement_ext/DiagnosticCommandImpl.c index 4c1eeea2f0b..f0267dd3ee3 100644 --- a/jdk/src/java.management/share/native/libmanagement/DiagnosticCommandImpl.c +++ b/jdk/src/jdk.management/share/native/libmanagement_ext/DiagnosticCommandImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,10 +25,10 @@ #include #include -#include "management.h" -#include "sun_management_DiagnosticCommandImpl.h" +#include "management_ext.h" +#include "com_sun_management_internal_DiagnosticCommandImpl.h" -JNIEXPORT void JNICALL Java_sun_management_DiagnosticCommandImpl_setNotificationEnabled +JNIEXPORT void JNICALL Java_com_sun_management_internal_DiagnosticCommandImpl_setNotificationEnabled (JNIEnv *env, jobject dummy, jboolean enabled) { if (jmm_version <= JMM_VERSION_1_2_2) { JNU_ThrowByName(env, "java/lang/UnsupportedOperationException", @@ -39,7 +39,7 @@ JNIEXPORT void JNICALL Java_sun_management_DiagnosticCommandImpl_setNotification } JNIEXPORT jobjectArray JNICALL -Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommands +Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommands (JNIEnv *env, jobject dummy) { return jmm_interface->GetDiagnosticCommands(env); @@ -64,7 +64,7 @@ jobject getDiagnosticCommandArgumentInfoArray(JNIEnv *env, jstring command, jmm_interface->GetDiagnosticCommandArgumentsInfo(env, command, dcmd_arg_info_array); dcmdArgInfoCls = (*env)->FindClass(env, - "sun/management/DiagnosticCommandArgumentInfo"); + "com/sun/management/internal/DiagnosticCommandArgumentInfo"); if ((*env)->ExceptionCheck(env)) { free(dcmd_arg_info_array); return NULL; @@ -77,7 +77,7 @@ jobject getDiagnosticCommandArgumentInfoArray(JNIEnv *env, jstring command, } for (i=0; iNewStringUTF(env,dcmd_arg_info_array[i].name), (*env)->NewStringUTF(env,dcmd_arg_info_array[i].description), @@ -113,7 +113,7 @@ jobject getDiagnosticCommandArgumentInfoArray(JNIEnv *env, jstring command, * passed in argument is not supported by the JVM */ JNIEXPORT jobjectArray JNICALL -Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo +Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommandInfo (JNIEnv *env, jobject dummy, jobjectArray commands) { int i; @@ -132,7 +132,7 @@ Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo } num_commands = (*env)->GetArrayLength(env, commands); dcmdInfoCls = (*env)->FindClass(env, - "sun/management/DiagnosticCommandInfo"); + "com/sun/management/internal/DiagnosticCommandInfo"); if ((*env)->ExceptionCheck(env)) { return NULL; } @@ -163,7 +163,7 @@ Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo return NULL; } obj = JNU_NewObjectByName(env, - "sun/management/DiagnosticCommandInfo", + "com/sun/management/internal/DiagnosticCommandInfo", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/util/List;)V", (*env)->NewStringUTF(env,dcmd_info_array[i].name), (*env)->NewStringUTF(env,dcmd_info_array[i].description), @@ -188,7 +188,7 @@ Java_sun_management_DiagnosticCommandImpl_getDiagnosticCommandInfo * passed in argument is not supported by the JVM */ JNIEXPORT jstring JNICALL -Java_sun_management_DiagnosticCommandImpl_executeDiagnosticCommand +Java_com_sun_management_internal_DiagnosticCommandImpl_executeDiagnosticCommand (JNIEnv *env, jobject dummy, jstring command) { return jmm_interface->ExecuteDiagnosticCommand(env, command); } diff --git a/jdk/src/java.management/share/native/libmanagement/Flag.c b/jdk/src/jdk.management/share/native/libmanagement_ext/Flag.c similarity index 91% rename from jdk/src/java.management/share/native/libmanagement/Flag.c rename to jdk/src/jdk.management/share/native/libmanagement_ext/Flag.c index 00828f34967..1629468f398 100644 --- a/jdk/src/java.management/share/native/libmanagement/Flag.c +++ b/jdk/src/jdk.management/share/native/libmanagement_ext/Flag.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,8 @@ #include #include #include -#include "management.h" -#include "sun_management_Flag.h" +#include "management_ext.h" +#include "com_sun_management_internal_Flag.h" static jobject default_origin = NULL; static jobject vm_creation_origin = NULL; @@ -40,7 +40,7 @@ static jobject attach_origin = NULL; static jobject other_origin = NULL; JNIEXPORT jint JNICALL -Java_sun_management_Flag_getInternalFlagCount +Java_com_sun_management_internal_Flag_getInternalFlagCount (JNIEnv *env, jclass cls) { jlong count = jmm_interface->GetLongAttribute(env, NULL, @@ -49,7 +49,7 @@ Java_sun_management_Flag_getInternalFlagCount } JNIEXPORT jobjectArray JNICALL - Java_sun_management_Flag_getAllFlagNames + Java_com_sun_management_internal_Flag_getAllFlagNames (JNIEnv *env, jclass cls) { return jmm_interface->GetVMGlobalNames(env); @@ -66,7 +66,7 @@ static jobject find_origin_constant(JNIEnv* env, const char* enum_name) { } JNIEXPORT void JNICALL -Java_sun_management_Flag_initialize +Java_com_sun_management_internal_Flag_initialize (JNIEnv *env, jclass cls) { default_origin = find_origin_constant(env, "DEFAULT"); @@ -80,13 +80,13 @@ Java_sun_management_Flag_initialize } JNIEXPORT jint JNICALL -Java_sun_management_Flag_getFlags +Java_com_sun_management_internal_Flag_getFlags (JNIEnv *env, jclass cls, jobjectArray names, jobjectArray flags, jint count) { jint num_flags, i, index; jmmVMGlobal* globals; size_t gsize; - const char* class_name = "sun/management/Flag"; + const char* class_name = "com/sun/management/internal/Flag"; const char* signature = "(Ljava/lang/String;Ljava/lang/Object;ZZLcom/sun/management/VMOption$Origin;)V"; jobject origin; jobject valueObj; @@ -196,7 +196,7 @@ Java_sun_management_Flag_getFlags } JNIEXPORT void JNICALL -Java_sun_management_Flag_setLongValue +Java_com_sun_management_internal_Flag_setLongValue (JNIEnv *env, jclass cls, jstring name, jlong value) { jvalue v; @@ -206,7 +206,7 @@ Java_sun_management_Flag_setLongValue } JNIEXPORT void JNICALL -Java_sun_management_Flag_setDoubleValue +Java_com_sun_management_internal_Flag_setDoubleValue (JNIEnv *env, jclass cls, jstring name, jdouble value) { jvalue v; @@ -216,7 +216,7 @@ Java_sun_management_Flag_setDoubleValue } JNIEXPORT void JNICALL -Java_sun_management_Flag_setBooleanValue +Java_com_sun_management_internal_Flag_setBooleanValue (JNIEnv *env, jclass cls, jstring name, jboolean value) { jvalue v; @@ -226,7 +226,7 @@ Java_sun_management_Flag_setBooleanValue } JNIEXPORT void JNICALL -Java_sun_management_Flag_setStringValue +Java_com_sun_management_internal_Flag_setStringValue (JNIEnv *env, jclass cls, jstring name, jstring value) { jvalue v; diff --git a/jdk/src/jdk.management/share/native/libmanagement_ext/GarbageCollectorExtImpl.c b/jdk/src/jdk.management/share/native/libmanagement_ext/GarbageCollectorExtImpl.c new file mode 100644 index 00000000000..f34d1959a32 --- /dev/null +++ b/jdk/src/jdk.management/share/native/libmanagement_ext/GarbageCollectorExtImpl.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include +#include "management_ext.h" +#include "com_sun_management_internal_GarbageCollectorExtImpl.h" + +JNIEXPORT void JNICALL Java_com_sun_management_internal_GarbageCollectorExtImpl_setNotificationEnabled +(JNIEnv *env, jobject dummy, jobject gc,jboolean enabled) { + + if (gc == NULL) { + JNU_ThrowNullPointerException(env, "Invalid GarbageCollectorMBean"); + return; + } + if((jmm_version > JMM_VERSION_1_2) + || (jmm_version == JMM_VERSION_1_2 && ((jmm_version&0xFF)>=1))) { + jmm_interface->SetGCNotificationEnabled(env, gc, enabled); + } +} diff --git a/jdk/src/java.management/share/native/libmanagement/GcInfoBuilder.c b/jdk/src/jdk.management/share/native/libmanagement_ext/GcInfoBuilder.c similarity index 94% rename from jdk/src/java.management/share/native/libmanagement/GcInfoBuilder.c rename to jdk/src/jdk.management/share/native/libmanagement_ext/GcInfoBuilder.c index 672cc6a7782..8fb337b8ecd 100644 --- a/jdk/src/java.management/share/native/libmanagement/GcInfoBuilder.c +++ b/jdk/src/jdk.management/share/native/libmanagement_ext/GcInfoBuilder.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,10 +26,10 @@ #include #include #include -#include "management.h" -#include "sun_management_GcInfoBuilder.h" +#include "management_ext.h" +#include "com_sun_management_internal_GcInfoBuilder.h" -JNIEXPORT jint JNICALL Java_sun_management_GcInfoBuilder_getNumGcExtAttributes +JNIEXPORT jint JNICALL Java_com_sun_management_internal_GcInfoBuilder_getNumGcExtAttributes (JNIEnv *env, jobject dummy, jobject gc) { jlong value; @@ -42,7 +42,7 @@ JNIEXPORT jint JNICALL Java_sun_management_GcInfoBuilder_getNumGcExtAttributes return (jint) value; } -JNIEXPORT void JNICALL Java_sun_management_GcInfoBuilder_fillGcAttributeInfo +JNIEXPORT void JNICALL Java_com_sun_management_internal_GcInfoBuilder_fillGcAttributeInfo (JNIEnv *env, jobject dummy, jobject gc, jint num_attributes, jobjectArray attributeNames, jcharArray types, jobjectArray descriptions) { @@ -173,7 +173,7 @@ static void setCharValueAtObjectArray(JNIEnv *env, jobjectArray array, (*env)->SetObjectArrayElement(env, array, index, obj); } -JNIEXPORT jobject JNICALL Java_sun_management_GcInfoBuilder_getLastGcInfo0 +JNIEXPORT jobject JNICALL Java_com_sun_management_internal_GcInfoBuilder_getLastGcInfo0 (JNIEnv *env, jobject builder, jobject gc, jint ext_att_count, jobjectArray ext_att_values, jcharArray ext_att_types, jobjectArray usageBeforeGC, jobjectArray usageAfterGC) { @@ -273,7 +273,7 @@ JNIEXPORT jobject JNICALL Java_sun_management_GcInfoBuilder_getLastGcInfo0 return JNU_NewObjectByName(env, "com/sun/management/GcInfo", - "(Lsun/management/GcInfoBuilder;JJJ[Ljava/lang/management/MemoryUsage;[Ljava/lang/management/MemoryUsage;[Ljava/lang/Object;)V", + "(Lcom/sun/management/internal/GcInfoBuilder;JJJ[Ljava/lang/management/MemoryUsage;[Ljava/lang/management/MemoryUsage;[Ljava/lang/Object;)V", builder, gc_stat.gc_index, gc_stat.start_time, diff --git a/jdk/src/java.management/share/native/libmanagement/HotSpotDiagnostic.c b/jdk/src/jdk.management/share/native/libmanagement_ext/HotSpotDiagnostic.c similarity index 86% rename from jdk/src/java.management/share/native/libmanagement/HotSpotDiagnostic.c rename to jdk/src/jdk.management/share/native/libmanagement_ext/HotSpotDiagnostic.c index fe6b2c6e7d2..d4b26771be6 100644 --- a/jdk/src/java.management/share/native/libmanagement/HotSpotDiagnostic.c +++ b/jdk/src/jdk.management/share/native/libmanagement_ext/HotSpotDiagnostic.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,11 +25,11 @@ #include #include "jvm.h" -#include "management.h" -#include "sun_management_HotSpotDiagnostic.h" +#include "management_ext.h" +#include "com_sun_management_internal_HotSpotDiagnostic.h" JNIEXPORT void JNICALL -Java_sun_management_HotSpotDiagnostic_dumpHeap0 +Java_com_sun_management_internal_HotSpotDiagnostic_dumpHeap0 (JNIEnv *env, jobject dummy, jstring outputfile, jboolean live) { jmm_interface->DumpHeap0(env, outputfile, live); diff --git a/jdk/src/java.management/share/classes/sun/management/ManagementFactory.java b/jdk/src/jdk.management/share/native/libmanagement_ext/management_ext.c similarity index 53% rename from jdk/src/java.management/share/classes/sun/management/ManagementFactory.java rename to jdk/src/jdk.management/share/native/libmanagement_ext/management_ext.c index b12a1c80b08..9d22c0a10a6 100644 --- a/jdk/src/java.management/share/classes/sun/management/ManagementFactory.java +++ b/jdk/src/jdk.management/share/native/libmanagement_ext/management_ext.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,33 +23,39 @@ * questions. */ -package sun.management; +#include +#include +#include "jvm.h" +#include "management_ext.h" -import java.lang.management.MemoryManagerMXBean; -import java.lang.management.MemoryPoolMXBean; -import java.lang.management.GarbageCollectorMXBean; +#define ERR_MSG_SIZE 128 -/** - * ManagementFactory class provides the methods that the HotSpot VM - * will invoke. So the class and method names cannot be renamed. - */ -class ManagementFactory { - private ManagementFactory() {}; +const JmmInterface* jmm_interface = NULL; +JavaVM* jvm = NULL; +jint jmm_version = 0; - // Invoked by the VM - private static MemoryPoolMXBean createMemoryPool - (String name, boolean isHeap, long uThreshold, long gcThreshold) { - return new MemoryPoolImpl(name, isHeap, uThreshold, gcThreshold); +JNIEXPORT jint JNICALL + JNI_OnLoad(JavaVM *vm, void *reserved) { + JNIEnv* env; + + jvm = vm; + if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) { + return JNI_ERR; } - private static MemoryManagerMXBean createMemoryManager(String name) { - return new MemoryManagerImpl(name); + jmm_interface = (JmmInterface*) JVM_GetManagement(JMM_VERSION_1_0); + if (jmm_interface == NULL) { + JNU_ThrowInternalError(env, "Unsupported Management version"); + return JNI_ERR; } - private static GarbageCollectorMXBean - createGarbageCollector(String name, String type) { - - // ignore type parameter which is for future extension - return new GarbageCollectorImpl(name); - } + jmm_version = jmm_interface->GetVersion(env); + return (*env)->GetVersion(env); +} + +void throw_internal_error(JNIEnv* env, const char* msg) { + char errmsg[128]; + + sprintf(errmsg, "errno: %d error: %s\n", errno, msg); + JNU_ThrowInternalError(env, errmsg); } diff --git a/jdk/src/jdk.management/share/native/libmanagement_ext/management_ext.h b/jdk/src/jdk.management/share/native/libmanagement_ext/management_ext.h new file mode 100644 index 00000000000..843de66872b --- /dev/null +++ b/jdk/src/jdk.management/share/native/libmanagement_ext/management_ext.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include + +#include "jni_util.h" +#include "jmm.h" + +#ifndef _MANAGEMENT_EXT_H_ +#define _MANAGEMENT_EXT_H_ + +extern const JmmInterface* jmm_interface; +extern jint jmm_version; +extern void throw_internal_error(JNIEnv* env, const char* msg); + +#endif diff --git a/jdk/src/java.management/unix/native/libmanagement/SolarisOperatingSystem.c b/jdk/src/jdk.management/solaris/native/libmanagement_ext/UnixOperatingSystem.c similarity index 95% rename from jdk/src/java.management/unix/native/libmanagement/SolarisOperatingSystem.c rename to jdk/src/jdk.management/solaris/native/libmanagement_ext/UnixOperatingSystem.c index d13a1b3d814..7628ed770a5 100644 --- a/jdk/src/java.management/unix/native/libmanagement/SolarisOperatingSystem.c +++ b/jdk/src/jdk.management/solaris/native/libmanagement_ext/UnixOperatingSystem.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,7 @@ #include #include #include "jvm.h" -#include "sun_management_OperatingSystemImpl.h" +#include "com_sun_management_internal_OperatingSystemImpl.h" typedef struct { kstat_t *kstat; @@ -226,14 +226,14 @@ double get_process_load(void) { } JNIEXPORT jdouble JNICALL -Java_sun_management_OperatingSystemImpl_getSystemCpuLoad0 +Java_com_sun_management_internal_OperatingSystemImpl_getSystemCpuLoad0 (JNIEnv *env, jobject dummy) { return get_cpu_load(-1); } JNIEXPORT jdouble JNICALL -Java_sun_management_OperatingSystemImpl_getProcessCpuLoad0 +Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuLoad0 (JNIEnv *env, jobject dummy) { return get_process_load(); diff --git a/jdk/src/java.management/unix/classes/sun/management/OperatingSystemImpl.java b/jdk/src/jdk.management/unix/classes/com/sun/management/internal/OperatingSystemImpl.java similarity index 94% rename from jdk/src/java.management/unix/classes/sun/management/OperatingSystemImpl.java rename to jdk/src/jdk.management/unix/classes/com/sun/management/internal/OperatingSystemImpl.java index b99c8008b1d..d1ce39c854b 100644 --- a/jdk/src/java.management/unix/classes/sun/management/OperatingSystemImpl.java +++ b/jdk/src/jdk.management/unix/classes/com/sun/management/internal/OperatingSystemImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,10 @@ * questions. */ -package sun.management; +package com.sun.management.internal; +import sun.management.BaseOperatingSystemImpl; +import sun.management.VMManagement; /** * Implementation class for the operating system. * Standard and committed hotspot-specific metrics if any. diff --git a/jdk/src/java.management/unix/native/libmanagement/OperatingSystemImpl.c b/jdk/src/jdk.management/unix/native/libmanagement_ext/OperatingSystemImpl.c similarity index 93% rename from jdk/src/java.management/unix/native/libmanagement/OperatingSystemImpl.c rename to jdk/src/jdk.management/unix/native/libmanagement_ext/OperatingSystemImpl.c index 00c4d558c96..1adeaf7bb53 100644 --- a/jdk/src/java.management/unix/native/libmanagement/OperatingSystemImpl.c +++ b/jdk/src/jdk.management/unix/native/libmanagement_ext/OperatingSystemImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,8 @@ #include "jni_util.h" #include "jlong.h" #include "jvm.h" -#include "management.h" -#include "sun_management_OperatingSystemImpl.h" +#include "management_ext.h" +#include "com_sun_management_internal_OperatingSystemImpl.h" #include #include @@ -179,14 +179,14 @@ static jlong get_total_or_available_swap_space_size(JNIEnv* env, jboolean availa } JNIEXPORT void JNICALL -Java_sun_management_OperatingSystemImpl_initialize0 +Java_com_sun_management_internal_OperatingSystemImpl_initialize0 (JNIEnv *env, jclass cls) { page_size = sysconf(_SC_PAGESIZE); } JNIEXPORT jlong JNICALL -Java_sun_management_OperatingSystemImpl_getCommittedVirtualMemorySize0 +Java_com_sun_management_internal_OperatingSystemImpl_getCommittedVirtualMemorySize0 (JNIEnv *env, jobject mbean) { #ifdef __solaris__ @@ -256,21 +256,21 @@ Java_sun_management_OperatingSystemImpl_getCommittedVirtualMemorySize0 } JNIEXPORT jlong JNICALL -Java_sun_management_OperatingSystemImpl_getTotalSwapSpaceSize0 +Java_com_sun_management_internal_OperatingSystemImpl_getTotalSwapSpaceSize0 (JNIEnv *env, jobject mbean) { return get_total_or_available_swap_space_size(env, JNI_FALSE); } JNIEXPORT jlong JNICALL -Java_sun_management_OperatingSystemImpl_getFreeSwapSpaceSize0 +Java_com_sun_management_internal_OperatingSystemImpl_getFreeSwapSpaceSize0 (JNIEnv *env, jobject mbean) { return get_total_or_available_swap_space_size(env, JNI_TRUE); } JNIEXPORT jlong JNICALL -Java_sun_management_OperatingSystemImpl_getProcessCpuTime0 +Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuTime0 (JNIEnv *env, jobject mbean) { #ifdef __APPLE__ @@ -312,7 +312,7 @@ Java_sun_management_OperatingSystemImpl_getProcessCpuTime0 } JNIEXPORT jlong JNICALL -Java_sun_management_OperatingSystemImpl_getFreePhysicalMemorySize0 +Java_com_sun_management_internal_OperatingSystemImpl_getFreePhysicalMemorySize0 (JNIEnv *env, jobject mbean) { #ifdef __APPLE__ @@ -346,7 +346,7 @@ Java_sun_management_OperatingSystemImpl_getFreePhysicalMemorySize0 } JNIEXPORT jlong JNICALL -Java_sun_management_OperatingSystemImpl_getTotalPhysicalMemorySize0 +Java_com_sun_management_internal_OperatingSystemImpl_getTotalPhysicalMemorySize0 (JNIEnv *env, jobject mbean) { #ifdef _ALLBSD_SOURCE @@ -377,7 +377,7 @@ Java_sun_management_OperatingSystemImpl_getTotalPhysicalMemorySize0 JNIEXPORT jlong JNICALL -Java_sun_management_OperatingSystemImpl_getOpenFileDescriptorCount0 +Java_com_sun_management_internal_OperatingSystemImpl_getOpenFileDescriptorCount0 (JNIEnv *env, jobject mbean) { #ifdef __APPLE__ @@ -466,7 +466,7 @@ Java_sun_management_OperatingSystemImpl_getOpenFileDescriptorCount0 } JNIEXPORT jlong JNICALL -Java_sun_management_OperatingSystemImpl_getMaxFileDescriptorCount0 +Java_com_sun_management_internal_OperatingSystemImpl_getMaxFileDescriptorCount0 (JNIEnv *env, jobject mbean) { struct rlimit rlp; diff --git a/jdk/src/java.management/windows/classes/sun/management/OperatingSystemImpl.java b/jdk/src/jdk.management/windows/classes/com/sun/management/internal/OperatingSystemImpl.java similarity index 91% rename from jdk/src/java.management/windows/classes/sun/management/OperatingSystemImpl.java rename to jdk/src/jdk.management/windows/classes/com/sun/management/internal/OperatingSystemImpl.java index 52fb709b923..3ab491d422f 100644 --- a/jdk/src/java.management/windows/classes/sun/management/OperatingSystemImpl.java +++ b/jdk/src/jdk.management/windows/classes/com/sun/management/internal/OperatingSystemImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,9 +23,11 @@ * questions. */ -package sun.management; +package com.sun.management.internal; import com.sun.management.OperatingSystemMXBean; +import sun.management.BaseOperatingSystemImpl; +import sun.management.VMManagement; /** * Implementation class for the operating system. @@ -45,36 +47,44 @@ class OperatingSystemImpl extends BaseOperatingSystemImpl super(vm); } + @Override public long getCommittedVirtualMemorySize() { synchronized (psapiLock) { return getCommittedVirtualMemorySize0(); } } + @Override public long getTotalSwapSpaceSize() { return getTotalSwapSpaceSize0(); } + @Override public long getFreeSwapSpaceSize() { return getFreeSwapSpaceSize0(); } + @Override public long getProcessCpuTime() { return getProcessCpuTime0(); } + @Override public long getFreePhysicalMemorySize() { return getFreePhysicalMemorySize0(); } + @Override public long getTotalPhysicalMemorySize() { return getTotalPhysicalMemorySize0(); } + @Override public double getSystemCpuLoad() { return getSystemCpuLoad0(); } + @Override public double getProcessCpuLoad() { return getProcessCpuLoad0(); } diff --git a/jdk/src/java.management/windows/native/libmanagement/OperatingSystemImpl.c b/jdk/src/jdk.management/windows/native/libmanagement_ext/OperatingSystemImpl.c similarity index 98% rename from jdk/src/java.management/windows/native/libmanagement/OperatingSystemImpl.c rename to jdk/src/jdk.management/windows/native/libmanagement_ext/OperatingSystemImpl.c index 04dbf8497c8..9ff4980f0ba 100644 --- a/jdk/src/java.management/windows/native/libmanagement/OperatingSystemImpl.c +++ b/jdk/src/jdk.management/windows/native/libmanagement_ext/OperatingSystemImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,8 @@ #include "jni_util.h" #include "jlong.h" #include "jvm.h" -#include "management.h" -#include "sun_management_OperatingSystemImpl.h" +#include "management_ext.h" +#include "com_sun_management_internal_OperatingSystemImpl.h" #include #include @@ -75,7 +75,7 @@ static HANDLE main_process; static void perfInit(void); JNIEXPORT void JNICALL -Java_sun_management_OperatingSystemImpl_initialize0 +Java_com_sun_management_internal_OperatingSystemImpl_initialize0 (JNIEnv *env, jclass cls) { main_process = GetCurrentProcess(); @@ -83,7 +83,7 @@ Java_sun_management_OperatingSystemImpl_initialize0 } JNIEXPORT jlong JNICALL -Java_sun_management_OperatingSystemImpl_getCommittedVirtualMemorySize0 +Java_com_sun_management_internal_OperatingSystemImpl_getCommittedVirtualMemorySize0 (JNIEnv *env, jobject mbean) { PROCESS_MEMORY_COUNTERS pmc; @@ -95,7 +95,7 @@ Java_sun_management_OperatingSystemImpl_getCommittedVirtualMemorySize0 } JNIEXPORT jlong JNICALL -Java_sun_management_OperatingSystemImpl_getTotalSwapSpaceSize0 +Java_com_sun_management_internal_OperatingSystemImpl_getTotalSwapSpaceSize0 (JNIEnv *env, jobject mbean) { MEMORYSTATUSEX ms; @@ -105,7 +105,7 @@ Java_sun_management_OperatingSystemImpl_getTotalSwapSpaceSize0 } JNIEXPORT jlong JNICALL -Java_sun_management_OperatingSystemImpl_getFreeSwapSpaceSize0 +Java_com_sun_management_internal_OperatingSystemImpl_getFreeSwapSpaceSize0 (JNIEnv *env, jobject mbean) { MEMORYSTATUSEX ms; @@ -115,7 +115,7 @@ Java_sun_management_OperatingSystemImpl_getFreeSwapSpaceSize0 } JNIEXPORT jlong JNICALL -Java_sun_management_OperatingSystemImpl_getProcessCpuTime0 +Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuTime0 (JNIEnv *env, jobject mbean) { @@ -134,7 +134,7 @@ Java_sun_management_OperatingSystemImpl_getProcessCpuTime0 } JNIEXPORT jlong JNICALL -Java_sun_management_OperatingSystemImpl_getFreePhysicalMemorySize0 +Java_com_sun_management_internal_OperatingSystemImpl_getFreePhysicalMemorySize0 (JNIEnv *env, jobject mbean) { MEMORYSTATUSEX ms; @@ -144,7 +144,7 @@ Java_sun_management_OperatingSystemImpl_getFreePhysicalMemorySize0 } JNIEXPORT jlong JNICALL -Java_sun_management_OperatingSystemImpl_getTotalPhysicalMemorySize0 +Java_com_sun_management_internal_OperatingSystemImpl_getTotalPhysicalMemorySize0 (JNIEnv *env, jobject mbean) { MEMORYSTATUSEX ms; @@ -1349,14 +1349,14 @@ perfGetCPULoad(int which) { } JNIEXPORT jdouble JNICALL -Java_sun_management_OperatingSystemImpl_getSystemCpuLoad0 +Java_com_sun_management_internal_OperatingSystemImpl_getSystemCpuLoad0 (JNIEnv *env, jobject dummy) { return perfGetCPULoad(-1); } JNIEXPORT jdouble JNICALL -Java_sun_management_OperatingSystemImpl_getProcessCpuLoad0 +Java_com_sun_management_internal_OperatingSystemImpl_getProcessCpuLoad0 (JNIEnv *env, jobject dummy) { return perfGetProcessCPULoad(); diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index fb8d79c7b5e..474047a1d69 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -136,13 +136,6 @@ java/lang/instrument/BootClassPath/BootClassPathTest.sh macosx-all ############################################################################ -# jdk_management - -# 8058492 -java/lang/management/ThreadMXBean/FindDeadlocks.java generic-all - -############################################################################ - # jdk_jmx # 8030957 @@ -353,9 +346,6 @@ com/sun/jdi/RedefinePop.sh generic-all # 8068645 com/sun/jdi/CatchPatternTest.sh generic-all -# 8069402 -com/sun/jdi/ConnectedVMs.java generic-all - # 8067354 com/sun/jdi/GetLocalVariables4Test.sh windows-all @@ -380,13 +370,7 @@ sun/tools/jcmd/TestJcmdSanity.java windows-all # 8072131 sun/tools/jmap/heapconfig/JMapHeapConfigTest.java macosx-all -# 8027668 -sun/tools/jstatd/TestJstatdDefaults.java generic-all -sun/tools/jstatd/TestJstatdServer.java generic-all -sun/tools/jstatd/TestJstatdPort.java generic-all -sun/tools/jstatd/TestJstatdPortAndServer.java generic-all - -# 8046285 8027668 +# 8046285 sun/tools/jstatd/TestJstatdExternalRegistry.java generic-all # 6456333 diff --git a/jdk/test/com/sun/jdi/InstanceFilter.java b/jdk/test/com/sun/jdi/InstanceFilter.java index a8d7da33ab9..0c9dc322cf5 100644 --- a/jdk/test/com/sun/jdi/InstanceFilter.java +++ b/jdk/test/com/sun/jdi/InstanceFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2002, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,7 +104,10 @@ public class InstanceFilter extends TestScaffold { return; } if (theThis == null) { - // This happens when the thread has exited. + // This happens when the thread has exited or when a + // static method is called. Setting an instance + // filter does not prevent this event from being + // emitted with a this that is null. methodEntryRequest.disable(); return; } @@ -138,6 +141,10 @@ public class InstanceFilter extends TestScaffold { EventRequestManager mgr = vm().eventRequestManager(); methodEntryRequest = mgr.createMethodEntryRequest(); methodEntryRequest.addInstanceFilter(theInstance); + // Thread filter is needed to prevent MethodEntry events + // to be emitted by the debugee when a static method + // is called on any thread. + methodEntryRequest.addThreadFilter(bpe.thread()); methodEntryRequest.enable(); listenUntilVMDisconnect(); diff --git a/jdk/test/com/sun/jdi/InvokeVarArgs.java b/jdk/test/com/sun/jdi/InvokeVarArgs.java new file mode 100644 index 00000000000..45af920db9f --- /dev/null +++ b/jdk/test/com/sun/jdi/InvokeVarArgs.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8075331 + * @summary Verify that we can call varargs methods + * @run build TestScaffold VMConnection TargetAdapter TargetListener + * @run compile -g InvokeVarArgs.java + * @run driver InvokeVarArgs + */ + +import com.sun.jdi.*; +import com.sun.jdi.event.*; +import java.util.Arrays; + +interface MyInterface { +} + +class SomeClass implements MyInterface { +} + +class InvokeVarArgsTarg { + + public static void main(String args[]) { + new InvokeVarArgsTarg().run(); + } + + SomeClass someClass1 = new SomeClass(); + SomeClass someClass2 = new SomeClass(); + + MyInterface[] array = new MyInterface[]{someClass1, someClass2}; + SomeClass[] array2 = new SomeClass[]{someClass1, someClass2}; + + public void run() { + System.out.println("size(array) : " + size(array)); + System.out.println("size(array2) : " + size(array2)); + } + + int size(Object... value) { + return value.length; + } +} + +public class InvokeVarArgs extends TestScaffold { + + public static void main(String args[]) throws Exception { + new InvokeVarArgs(args).startTests(); + } + + InvokeVarArgs(String args[]) throws Exception { + super(args); + } + + protected void runTests() throws Exception { + + BreakpointEvent bpe = startTo("InvokeVarArgsTarg", "run", "()V"); + StackFrame frame = bpe.thread().frame(0); + ObjectReference targetObj = frame.thisObject(); + ReferenceType targetType = (ReferenceType) targetObj.type(); + Value arrayVal = targetObj.getValue(targetType.fieldByName("array")); + Value array2Val = targetObj.getValue(targetType.fieldByName("array2")); + Method sizeMethod = targetType.methodsByName("size", "([Ljava/lang/Object;)I").get(0); + + IntegerValue size = (IntegerValue) targetObj.invokeMethod(bpe.thread(), sizeMethod, Arrays.asList(new Value[]{arrayVal}), 0); + if (size.value() != 2) { + throw new Exception("size(array) should be 2, but was " + size.value()); + } + + size = (IntegerValue) targetObj.invokeMethod(bpe.thread(), sizeMethod, Arrays.asList(new Value[]{array2Val}), 0); + if (size.value() != 2) { + throw new Exception("size(array2) should be 2, but was " + size.value()); + } + + listenUntilVMDisconnect(); + } +} diff --git a/jdk/test/com/sun/management/CheckSomeMXBeanImplPackage.java b/jdk/test/com/sun/management/CheckSomeMXBeanImplPackage.java new file mode 100644 index 00000000000..4879a01bc82 --- /dev/null +++ b/jdk/test/com/sun/management/CheckSomeMXBeanImplPackage.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.lang.management.ManagementFactory; +import java.lang.management.PlatformManagedObject; + +/* + * @test + * @bug 8042901 + * @summary If jdk.management is present, GarbageCollectorMXBean and ThreadMXBean + * must be from com.sun.management.internal + * @author Shanliang Jiang + */ +public class CheckSomeMXBeanImplPackage { + private static String implPackageName = "com.sun.management.internal"; + + public static void main(String[] args) throws Exception { + boolean present = false; + try { + Class.forName("com.sun.management.GarbageCollectorMXBean"); + present = true; + } catch (ClassNotFoundException cnfe) {} + + if (present) { + Class klazz = + java.lang.management.GarbageCollectorMXBean.class; + for (Object obj : + ManagementFactory.getPlatformMXBeans(klazz)) { + check(klazz.getName(), obj); + } + + klazz = com.sun.management.GarbageCollectorMXBean.class; + for (Object obj : + ManagementFactory.getPlatformMXBeans(klazz)) { + check(klazz.getName(), obj); + } + + klazz = java.lang.management.ThreadMXBean.class; + check(klazz.getName(), + ManagementFactory.getPlatformMXBean(klazz)); + + klazz = com.sun.management.ThreadMXBean.class; + check(klazz.getName(), + ManagementFactory.getPlatformMXBean(klazz)); + + System.out.println("--- PASSED!"); + } else { + System.out.println("--- Skip the test, jdk.management module is not present!"); + } + } + + private static void check(String mbeanName, Object impl) { + if (!impl.getClass().getName().startsWith(implPackageName)) { + throw new RuntimeException(mbeanName+" implementation package " + + "should be: " + implPackageName + + ", but got: " + impl.getClass()); + } else { + System.out.println("--- Good, "+mbeanName+" got right implementation: " + impl); + } + } +} diff --git a/jdk/test/com/sun/management/VMOptionOpenDataTest.java b/jdk/test/com/sun/management/VMOptionOpenDataTest.java new file mode 100644 index 00000000000..7f90fd5c705 --- /dev/null +++ b/jdk/test/com/sun/management/VMOptionOpenDataTest.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.management.VMOption; +import java.io.InvalidObjectException; +import java.util.Objects; +import javax.management.openmbean.OpenDataException; +import sun.management.MappedMXBeanType; + +/* + * @test + * @bug 8042901 + * @summary Check that MappedMXBeanType.toOpenTypeData supports VMOption + * @author Shanliang Jiang + */ +public class VMOptionOpenDataTest { + public static void main(String[] args) throws Exception { + System.out.println("--- VMOptionOpenDataTest-main: Checking that " + + "MappedMXBeanType.toOpenTypeData supports VMOption"); + Exception failed = null; + try { + VMOption vo = new VMOption("toto", "titi", true, VMOption.Origin.OTHER); + System.out.println("--- Construct a VMOption object: \"" + vo + "\""); + + Object open = MappedMXBeanType.toOpenTypeData(vo, VMOption.class); + System.out.println("--- Map it to an open type: \"" + open +" \""); + + Object back = MappedMXBeanType.toJavaTypeData(open, VMOption.class); + System.out.println("--- Map it back to java type: \"" + back +" \""); + + if (back == null) { + failed = new RuntimeException("Failed, mapping back got null."); + } else if (!(back instanceof VMOption)) { + failed = new RuntimeException("Failed, not mapped back to a VMOption: " + +back.getClass()); + } else { + VMOption mapBack = (VMOption)back; + if (!Objects.equals(vo.getName(), mapBack.getName()) || + !Objects.equals(vo.getOrigin(), mapBack.getOrigin()) || + !Objects.equals(vo.getValue(), mapBack.getValue()) || + vo.isWriteable() != mapBack.isWriteable()) { + failed = new RuntimeException( + "Failed, failed to map back the original VMOtion."); + } + } + } catch (OpenDataException | InvalidObjectException ode) { + failed = ode; + } + if (failed == null) { + System.out.println("--- PASSED!"); + } else { + System.out.println("--- Failed: "+failed.getMessage()); + throw failed; + } + } +} diff --git a/jdk/test/java/lang/Class/getSimpleName/GetSimpleNameTest.java b/jdk/test/java/lang/Class/getSimpleName/GetSimpleNameTest.java new file mode 100644 index 00000000000..69382710191 --- /dev/null +++ b/jdk/test/java/lang/Class/getSimpleName/GetSimpleNameTest.java @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* @test + * @bug 8057919 + * @summary Class.getSimpleName() should work for non-JLS compliant class names + */ +import jdk.internal.org.objectweb.asm.*; +import static jdk.internal.org.objectweb.asm.Opcodes.*; + +public class GetSimpleNameTest { + static class NestedClass {} + class InnerClass {} + + static Class f1() { + class LocalClass {} + return LocalClass.class; + } + + public static void main(String[] args) throws Exception { + assertEquals(NestedClass.class.getSimpleName(), "NestedClass"); + assertEquals( InnerClass.class.getSimpleName(), "InnerClass"); + assertEquals( f1().getSimpleName(), "LocalClass"); + + java.io.Serializable anon = new java.io.Serializable() {}; + assertEquals(anon.getClass().getSimpleName(), ""); + + // Java class names, prepended enclosing class name. + testNested("p.Outer$Nested", "p.Outer", "Nested"); + testInner( "p.Outer$Inner", "p.Inner", "Inner"); + testLocal( "p.Outer$1Local", "p.Outer", "Local"); + testAnon( "p.Outer$1", "p.Outer", ""); + + // Non-Java class names, prepended enclosing class name. + testNested("p.$C1$Nested", "p.$C1$", "Nested"); + testInner( "p.$C1$Inner", "p.$C1$", "Inner"); + testLocal( "p.$C1$Local", "p.$C1$", "Local"); + testAnon( "p.$C1$1", "p.$C1$", ""); + + // Non-Java class names, unrelated class names. + testNested("p1.$Nested$", "p2.$C1$", "Nested"); + testInner( "p1.$Inner$", "p2.$C1$", "Inner"); + testLocal( "p1.$Local$", "p2.$C1$", "Local"); + testAnon( "p1.$anon$", "p2.$C1$", ""); + } + + static void testNested(String innerName, String outerName, String simpleName) throws Exception { + BytecodeGenerator bg = new BytecodeGenerator(innerName, outerName, simpleName); + CustomCL cl = new CustomCL(innerName, outerName, bg.getNestedClasses(true), bg.getNestedClasses(false)); + assertEquals(cl.loadClass(innerName).getSimpleName(), simpleName); + } + + static void testInner(String innerName, String outerName, String simpleName) throws Exception { + BytecodeGenerator bg = new BytecodeGenerator(innerName, outerName, simpleName); + CustomCL cl = new CustomCL(innerName, outerName, bg.getInnerClasses(true), bg.getInnerClasses(false)); + assertEquals(cl.loadClass(innerName).getSimpleName(), simpleName); + } + + static void testLocal(String innerName, String outerName, String simpleName) throws Exception { + BytecodeGenerator bg = new BytecodeGenerator(innerName, outerName, simpleName); + CustomCL cl = new CustomCL(innerName, outerName, bg.getLocalClasses(true), bg.getLocalClasses(false)); + assertEquals(cl.loadClass(innerName).getSimpleName(), simpleName); + } + + static void testAnon(String innerName, String outerName, String simpleName) throws Exception { + BytecodeGenerator bg = new BytecodeGenerator(innerName, outerName, simpleName); + CustomCL cl = new CustomCL(innerName, outerName, bg.getAnonymousClasses(true), bg.getAnonymousClasses(false)); + assertEquals(cl.loadClass(innerName).getSimpleName(), simpleName); + } + + static void assertEquals(Object o1, Object o2) { + if (!java.util.Objects.equals(o1, o2)) { + throw new AssertionError(o1 + " != " + o2); + } + } + + static class CustomCL extends ClassLoader { + final String innerName; + final String outerName; + + final byte[] innerClassFile; + final byte[] outerClassFile; + + CustomCL(String innerName, String outerName, byte[] innerClassFile, byte[] outerClassFile) { + this.innerName = innerName; + this.outerName = outerName; + this.innerClassFile = innerClassFile; + this.outerClassFile = outerClassFile; + } + @Override + protected Class findClass(String name) throws ClassNotFoundException { + if (innerName.equals(name)) { + return defineClass(innerName, innerClassFile, 0, innerClassFile.length); + } else if (outerName.equals(name)) { + return defineClass(outerName, outerClassFile, 0, outerClassFile.length); + } else { + throw new ClassNotFoundException(name); + } + } + } + + static class BytecodeGenerator { + final String innerName; + final String outerName; + final String simpleName; + + BytecodeGenerator(String innerName, String outerName, String simpleName) { + this.innerName = intl(innerName); + this.outerName = intl(outerName); + this.simpleName = simpleName; + } + + static String intl(String name) { return name.replace('.', '/'); } + + static void makeDefaultCtor(ClassWriter cw) { + MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); + mv.visitInsn(RETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + } + + void makeCtxk(ClassWriter cw, boolean isInner) { + if (isInner) { + cw.visitOuterClass(outerName, "f", "()V"); + } else { + MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "f", "()V", null, null); + mv.visitCode(); + mv.visitInsn(RETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + } + + byte[] getNestedClasses(boolean isInner) { + String name = (isInner ? innerName : outerName); + ClassWriter cw = new ClassWriter(0); + cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, name, null, "java/lang/Object", null); + + cw.visitInnerClass(innerName, outerName, simpleName, ACC_PUBLIC | ACC_STATIC); + + makeDefaultCtor(cw); + cw.visitEnd(); + return cw.toByteArray(); + } + + byte[] getInnerClasses(boolean isInner) { + String name = (isInner ? innerName : outerName); + ClassWriter cw = new ClassWriter(0); + cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, name, null, "java/lang/Object", null); + + cw.visitInnerClass(innerName, outerName, simpleName, ACC_PUBLIC); + + makeDefaultCtor(cw); + cw.visitEnd(); + return cw.toByteArray(); + } + + byte[] getLocalClasses(boolean isInner) { + String name = (isInner ? innerName : outerName); + ClassWriter cw = new ClassWriter(0); + cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, name, null, "java/lang/Object", null); + + cw.visitInnerClass(innerName, null, simpleName, ACC_PUBLIC | ACC_STATIC); + makeCtxk(cw, isInner); + + makeDefaultCtor(cw); + cw.visitEnd(); + return cw.toByteArray(); + } + + byte[] getAnonymousClasses(boolean isInner) { + String name = (isInner ? innerName : outerName); + ClassWriter cw = new ClassWriter(0); + cw.visit(V1_7, ACC_PUBLIC + ACC_SUPER, name, null, "java/lang/Object", null); + + cw.visitInnerClass(innerName, null, null, ACC_PUBLIC | ACC_STATIC); + makeCtxk(cw, isInner); + + makeDefaultCtor(cw); + cw.visitEnd(); + return cw.toByteArray(); + } + } +} diff --git a/jdk/test/java/lang/Thread/ThreadStateController.java b/jdk/test/java/lang/Thread/ThreadStateController.java index e2c6341b471..728a115c271 100644 --- a/jdk/test/java/lang/Thread/ThreadStateController.java +++ b/jdk/test/java/lang/Thread/ThreadStateController.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015 Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.LockSupport; import jdk.testlibrary.LockFreeLogManager; +import jdk.testlibrary.Utils; /** * ThreadStateController allows a thread to request this thread to transition @@ -73,7 +74,7 @@ public class ThreadStateController extends Thread { public static void pause(long ms) { try { - Thread.sleep(ms); + Thread.sleep(Utils.adjustTimeout(ms)); } catch (InterruptedException e) { throw new RuntimeException(e); } @@ -135,7 +136,7 @@ public class ThreadStateController extends Thread { try { // this thread has escaped the BLOCKED state // release the lock and a short wait before continue - lock.wait(10); + lock.wait(Utils.adjustTimeout(10)); } catch (InterruptedException e) { // ignore interrupted.incrementAndGet(); @@ -165,7 +166,7 @@ public class ThreadStateController extends Thread { getId(), getName(), iterations.get(), interrupted.get()); try { stateChange(nextState); - lock.wait(10000); + lock.wait(Integer.MAX_VALUE); log("%d: %s wakes up from timed waiting (iterations %d interrupted %d)%n", getId(), getName(), iterations.get(), interrupted.get()); } catch (InterruptedException e) { @@ -185,7 +186,8 @@ public class ThreadStateController extends Thread { case S_TIMED_PARKED: { log("%d: %s is going to timed park (iterations %d)%n", getId(), getName(), iterations.get()); - long deadline = System.currentTimeMillis() + 10000*1000; + long deadline = System.currentTimeMillis() + + Utils.adjustTimeout(10000*1000); stateChange(nextState); LockSupport.parkUntil(deadline); break; @@ -195,7 +197,7 @@ public class ThreadStateController extends Thread { getId(), getName(), iterations.get(), interrupted.get()); try { stateChange(nextState); - Thread.sleep(1000000); + Thread.sleep(Utils.adjustTimeout(1000000)); } catch (InterruptedException e) { // finish sleeping interrupted.incrementAndGet(); diff --git a/jdk/test/java/lang/instrument/NMTHelper.java b/jdk/test/java/lang/instrument/NMTHelper.java index ee5d1e1b882..09e60e4a623 100644 --- a/jdk/test/java/lang/instrument/NMTHelper.java +++ b/jdk/test/java/lang/instrument/NMTHelper.java @@ -27,8 +27,9 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.Arrays; import java.util.stream.Collectors; -import sun.management.ManagementFactoryHelper; -import com.sun.management.DiagnosticCommandMBean; +import java.lang.management.ManagementFactory; +import javax.management.MalformedObjectNameException; +import javax.management.ObjectName; public class NMTHelper { @@ -53,7 +54,12 @@ public class NMTHelper } private static String executeDcmd(String cmd, String ... args) { - DiagnosticCommandMBean dcmd = ManagementFactoryHelper.getDiagnosticCommandMBean(); + ObjectName oname = null; + try { + oname = ObjectName.getInstance("com.sun.management:type=DiagnosticCommand"); + } catch (MalformedObjectNameException mone) { + throw new RuntimeException(mone); + } Object[] dcmdArgs = {args}; String[] signature = {String[].class.getName()}; @@ -63,7 +69,8 @@ public class NMTHelper System.out.println("Output from Dcmd '" + cmdString + "' is being written to file " + f); try (FileWriter fw = new FileWriter(f)) { fw.write("> " + cmdString + ":"); - String result = (String) dcmd.invoke(cmd, dcmdArgs, signature); + String result = (String)ManagementFactory.getPlatformMBeanServer(). + invoke(oname, cmd, dcmdArgs, signature); fw.write(result); return result; } catch(Exception ex) { diff --git a/jdk/test/java/lang/instrument/RedefineMethodInBacktrace.sh b/jdk/test/java/lang/instrument/RedefineMethodInBacktrace.sh index 4ebaaa8e73b..439a7f72776 100644 --- a/jdk/test/java/lang/instrument/RedefineMethodInBacktrace.sh +++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktrace.sh @@ -77,7 +77,7 @@ fi cat output.log -MESG="Exception" +MESG="Test failed" grep "$MESG" output.log result=$? if [ "$result" = 0 ]; then diff --git a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceApp.java b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceApp.java index 7f7ddbf19b1..d406ae0ceed 100644 --- a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceApp.java +++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceApp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,8 @@ import java.lang.management.ThreadInfo; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.concurrent.CountDownLatch; -import sun.management.ManagementFactoryHelper; +import javax.management.JMX; +import javax.management.ObjectName; /** * When an exception is thrown, the JVM collects just enough information @@ -46,12 +47,15 @@ import sun.management.ManagementFactoryHelper; * could be freed, since class redefinition didn't know about the backtraces. */ public class RedefineMethodInBacktraceApp { + static boolean failed = false; + public static void main(String args[]) throws Exception { System.out.println("Hello from RedefineMethodInBacktraceApp!"); - new RedefineMethodInBacktraceApp().doTest(); - System.exit(0); + if (failed) { + throw new Exception("ERROR: RedefineMethodInBacktraceApp failed."); + } } public static CountDownLatch stop = new CountDownLatch(1); @@ -63,13 +67,18 @@ public class RedefineMethodInBacktraceApp { } private void doMethodInBacktraceTest() throws Exception { - Throwable t = getThrowableFromMethodToRedefine(); + Throwable t1 = getThrowableFromMethodToRedefine(); + Throwable t2 = getThrowableFromMethodToDelete(); doRedefine(RedefineMethodInBacktraceTarget.class); doClassUnloading(); - touchRedefinedMethodInBacktrace(t); + System.out.println("checking backtrace for throwable from methodToRedefine"); + touchRedefinedMethodInBacktrace(t1); + + System.out.println("checking backtrace for throwable from methodToDelete"); + touchRedefinedMethodInBacktrace(t2); } private void doMethodInBacktraceTestB() throws Exception { @@ -95,8 +104,11 @@ public class RedefineMethodInBacktraceApp { String[] threadPrintArgs = {}; Object[] dcmdArgs = {threadPrintArgs}; String[] signature = {String[].class.getName()}; - DiagnosticCommandMBean dcmd = ManagementFactoryHelper.getDiagnosticCommandMBean(); - System.out.println(dcmd.invoke("threadPrint", dcmdArgs, signature)); + System.out.println(ManagementFactory.getPlatformMBeanServer().invoke( + ObjectName.getInstance("com.sun.management:type=DiagnosticCommand"), + "threadPrint", + dcmdArgs, + signature)); // release the thread stop.countDown(); @@ -115,6 +127,10 @@ public class RedefineMethodInBacktraceApp { if (!(thrownFromMethodToRedefine instanceof RuntimeException)) { throw e; } + } catch (Exception e) { + e.printStackTrace(); + System.out.println("\nTest failed: unexpected exception: " + e.toString()); + failed = true; } method = null; c = null; @@ -122,15 +138,49 @@ public class RedefineMethodInBacktraceApp { return thrownFromMethodToRedefine; } + private static Throwable getThrowableFromMethodToDelete() throws Exception { + Class c = + RedefineMethodInBacktraceTarget.class; + Method method = c.getMethod("callMethodToDelete"); + + Throwable thrownFromMethodToDelete = null; + try { + method.invoke(null); + } catch (InvocationTargetException e) { + thrownFromMethodToDelete = e.getCause(); + if (!(thrownFromMethodToDelete instanceof RuntimeException)) { + throw e; + } + } catch (Exception e) { + e.printStackTrace(); + System.out.println("\nTest failed: unexpected exception: " + e.toString()); + failed = true; + } + return thrownFromMethodToDelete; + } + + private static void doClassUnloading() { // This will clean out old, unused redefined methods. System.gc(); } private static void touchRedefinedMethodInBacktrace(Throwable throwable) { + throwable.printStackTrace(); // Make sure that we can convert the backtrace, which is referring to // the redefined method, to a StrackTraceElement[] without crashing. - throwable.getStackTrace(); + StackTraceElement[] stackTrace = throwable.getStackTrace(); + for (int i = 0; i < stackTrace.length; i++) { + StackTraceElement frame = stackTrace[i]; + if (frame.getClassName() == null) { + System.out.println("\nTest failed: trace[" + i + "].getClassName() returned null"); + failed = true; + } + if (frame.getMethodName() == null) { + System.out.println("\nTest failed: trace[" + i + "].getMethodName() returned null"); + failed = true; + } + } } private static void doRedefine(Class clazz) throws Exception { diff --git a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget.java b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget.java index fad881137c8..d1c1e33078d 100644 --- a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget.java +++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget.java @@ -29,4 +29,13 @@ public class RedefineMethodInBacktraceTarget { public static void methodToRedefine() { throw new RuntimeException("Test exception"); } + + public static void callMethodToDelete() { + methodToDelete(); + } + + private static void methodToDelete() { + throw new RuntimeException("Test exception in methodToDelete"); + } + } diff --git a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB.java b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB.java index baefeb78703..d7fb6f7857a 100644 --- a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB.java +++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB.java @@ -37,4 +37,16 @@ public class RedefineMethodInBacktraceTargetB { // ignore, test will fail } } + + public static void callMethodToDelete() { + try { + // signal that we are here + RedefineMethodInBacktraceApp.called.countDown(); + + // wait until test is done + RedefineMethodInBacktraceApp.stop.await(); + } catch (InterruptedException ex) { + // ignore, test will fail + } + } } diff --git a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB_2.java b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB_2.java index de98206a8dd..33c6e7103e2 100644 --- a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB_2.java +++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTargetB_2.java @@ -28,4 +28,7 @@ public class RedefineMethodInBacktraceTargetB { public static void methodToRedefine() { } + + public static void callMethodToDelete() { + } } diff --git a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget_2.java b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget_2.java index d2ba2259932..a7d9dc666a1 100644 --- a/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget_2.java +++ b/jdk/test/java/lang/instrument/RedefineMethodInBacktraceTarget_2.java @@ -29,4 +29,8 @@ public class RedefineMethodInBacktraceTarget { public static void methodToRedefine() { throw new RuntimeException("Test exception 2"); } + + public static void callMethodToDelete() { + throw new RuntimeException("Test exception 2 in callMethodToDelete"); + } } diff --git a/jdk/test/java/lang/management/ThreadMXBean/FindDeadlocks.java b/jdk/test/java/lang/management/ThreadMXBean/FindDeadlocks.java index 0bdcd7ae4de..c2fd2a651e4 100644 --- a/jdk/test/java/lang/management/ThreadMXBean/FindDeadlocks.java +++ b/jdk/test/java/lang/management/ThreadMXBean/FindDeadlocks.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ /* * @test * @bug 5086470 + * @key intermittent * @summary Basic Test for the following methods: * - ThreadMXBean.findDeadlockedThreads() * - ThreadMXBean.findMonitorDeadlockedThreads() diff --git a/jdk/test/java/lang/management/ThreadMXBean/ThreadInfoArray.java b/jdk/test/java/lang/management/ThreadMXBean/ThreadInfoArray.java index 8b504344143..14ff9857b6b 100644 --- a/jdk/test/java/lang/management/ThreadMXBean/ThreadInfoArray.java +++ b/jdk/test/java/lang/management/ThreadMXBean/ThreadInfoArray.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,11 +23,12 @@ /* * @test - * @bug 5058327 - * @summary Test if getThreadInfo(long[]) returns a ThreadInfo[] - * with null elements with no exception. + * @bug 5058327 8074368 + * @summary Tests the correct behaviour of getThreadInfo(long[]) for non-existent + * thread IDs and the empty thread id array. * * @author Mandy Chung + * @author Jaroslav Bachorik * * @build ThreadInfoArray * @run main ThreadInfoArray @@ -35,15 +36,30 @@ import java.lang.management.*; import javax.management.*; -import java.util.*; import static java.lang.management.ManagementFactory.*; public class ThreadInfoArray { public static void main(String[] argv) throws Exception { - ThreadMXBean mbean = ManagementFactory.getThreadMXBean(); + MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); + ObjectName on = new ObjectName(THREAD_MXBEAN_NAME); + ThreadMXBean mbean = ManagementFactory.getThreadMXBean(); + ThreadMXBean proxy = newPlatformMXBeanProxy(mbs, + on.toString(), + ThreadMXBean.class); + + checkNullElement(mbean, proxy, mbs, on); + checkEmptyArray(mbean, proxy, mbs, on); + System.out.println("Test passed"); + } + + private static void checkNullElement(ThreadMXBean mbean, ThreadMXBean proxy, + MBeanServer mbs, ObjectName on) + throws Exception { + System.out.println("--- Check null element"); // ID for a new thread long [] ids = {new Thread().getId()}; + // direct call ThreadInfo[] tinfos = mbean.getThreadInfo(ids); if (tinfos[0] != null) { @@ -52,8 +68,6 @@ public class ThreadInfoArray { } // call getThreadInfo through MBeanServer - MBeanServer mbs = ManagementFactory.getPlatformMBeanServer(); - ObjectName on = new ObjectName(THREAD_MXBEAN_NAME); Object[] params = {ids}; String[] sigs = {"[J"}; Object[] result = (Object[]) mbs.invoke(on, "getThreadInfo", params, sigs); @@ -64,14 +78,57 @@ public class ThreadInfoArray { } // call getThreadInfo through proxy - ThreadMXBean proxy = newPlatformMXBeanProxy(mbs, - on.toString(), - ThreadMXBean.class); tinfos = proxy.getThreadInfo(ids); if (tinfos[0] != null) { throw new RuntimeException("TEST FAILED: " + "Expected to have a null element"); } - System.out.println("Test passed"); + System.out.println("--- PASSED"); + } + + private static void checkEmptyArray(ThreadMXBean mbean, ThreadMXBean proxy, + MBeanServer mbs, ObjectName on) + throws Exception { + System.out.println("--- Check empty TID array"); + + long[] ids = new long[0]; + // direct call + assertEmptyArray(mbean.getThreadInfo(ids), "Expected empty ThreadInfo array"); + assertEmptyArray(mbean.getThreadInfo(ids, 1), "Expected empty ThreadInfo array"); + assertEmptyArray(mbean.getThreadInfo(ids, true, true), "Expected empty ThreadInfo array"); + + // call getThreadInfo through MBeanServer + assertEmptyArray( + (Object[]) mbs.invoke( + on, "getThreadInfo", new Object[]{ids}, new String[]{"[J"} + ), + "Expected empty ThreadInfo array via MBeanServer" + ); + assertEmptyArray( + (Object[]) mbs.invoke( + on, "getThreadInfo", new Object[]{ids, 1}, + new String[]{"[J", "int"} + ), + "Expected empty ThreadInfo array via MBeanServer" + ); + assertEmptyArray( + (Object[]) mbs.invoke( + on, "getThreadInfo", new Object[]{ids, true, true}, + new String[]{"[J", "boolean", "boolean"} + ), + "Expected empty ThreadInfo array via MBeanServer" + ); + + // call getThreadInfo through proxy + assertEmptyArray(proxy.getThreadInfo(ids), "Expected empty ThreadInfo array"); + assertEmptyArray(proxy.getThreadInfo(ids, 1), "Expected empty ThreadInfo array"); + assertEmptyArray(proxy.getThreadInfo(ids, true, true), "Expected empty ThreadInfo array"); + System.out.println("--- PASSED"); + } + + private static void assertEmptyArray(Object[] arr, String message) throws Exception { + if (arr.length > 0) { + throw new RuntimeException("TEST FAILED: " + message); + } } } diff --git a/jdk/test/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java b/jdk/test/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java index a273bfdd309..249e55a8877 100644 --- a/jdk/test/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java +++ b/jdk/test/java/lang/management/ThreadMXBean/ThreadMXBeanStateTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,60 +64,61 @@ public class ThreadMXBeanStateTest { Thread.currentThread().getState(); ThreadStateController thread = new ThreadStateController("StateChanger", globalLock); thread.setDaemon(true); - - // before myThread starts - thread.checkThreadState(NEW); - - thread.start(); - thread.transitionTo(RUNNABLE); - thread.checkThreadState(RUNNABLE); - checkLockInfo(thread, RUNNABLE, null, null); - - thread.suspend(); - ThreadStateController.pause(10); - thread.checkThreadState(RUNNABLE); - checkSuspendedThreadState(thread, RUNNABLE); - thread.resume(); - - synchronized (globalLock) { - thread.transitionTo(BLOCKED); - thread.checkThreadState(BLOCKED); - checkLockInfo(thread, BLOCKED, - globalLock, Thread.currentThread()); - } - - thread.transitionTo(WAITING); - thread.checkThreadState(WAITING); - checkLockInfo(thread, Thread.State.WAITING, - globalLock, null); - - thread.transitionTo(TIMED_WAITING); - thread.checkThreadState(TIMED_WAITING); - checkLockInfo(thread, TIMED_WAITING, - globalLock, null); - - - thread.transitionToPark(true /* timed park */); - thread.checkThreadState(TIMED_WAITING); - checkLockInfo(thread, TIMED_WAITING, null, null); - - thread.transitionToPark(false /* indefinite park */); - thread.checkThreadState(WAITING); - checkLockInfo(thread, WAITING, null, null); - - thread.transitionToSleep(); - thread.checkThreadState(TIMED_WAITING); - checkLockInfo(thread, TIMED_WAITING, null, null); - - thread.transitionTo(TERMINATED); - thread.checkThreadState(TERMINATED); - try { - System.out.println(thread.getLog()); - } catch (InterruptedException e) { - e.printStackTrace(); - System.out.println("TEST FAILED: Unexpected exception."); - throw new RuntimeException(e); + // before myThread starts + thread.checkThreadState(NEW); + + thread.start(); + thread.transitionTo(RUNNABLE); + thread.checkThreadState(RUNNABLE); + checkLockInfo(thread, RUNNABLE, null, null); + + thread.suspend(); + ThreadStateController.pause(10); + thread.checkThreadState(RUNNABLE); + checkSuspendedThreadState(thread, RUNNABLE); + thread.resume(); + + synchronized (globalLock) { + thread.transitionTo(BLOCKED); + thread.checkThreadState(BLOCKED); + checkLockInfo(thread, BLOCKED, + globalLock, Thread.currentThread()); + } + + thread.transitionTo(WAITING); + thread.checkThreadState(WAITING); + checkLockInfo(thread, Thread.State.WAITING, + globalLock, null); + + thread.transitionTo(TIMED_WAITING); + thread.checkThreadState(TIMED_WAITING); + checkLockInfo(thread, TIMED_WAITING, + globalLock, null); + + + thread.transitionToPark(true /* timed park */); + thread.checkThreadState(TIMED_WAITING); + checkLockInfo(thread, TIMED_WAITING, null, null); + + thread.transitionToPark(false /* indefinite park */); + thread.checkThreadState(WAITING); + checkLockInfo(thread, WAITING, null, null); + + thread.transitionToSleep(); + thread.checkThreadState(TIMED_WAITING); + checkLockInfo(thread, TIMED_WAITING, null, null); + + thread.transitionTo(TERMINATED); + thread.checkThreadState(TERMINATED); + } finally { + try { + System.out.println(thread.getLog()); + } catch (InterruptedException e) { + e.printStackTrace(); + System.out.println("TEST FAILED: Unexpected exception."); + throw new RuntimeException(e); + } } System.out.println("Test passed."); } diff --git a/jdk/test/java/lang/management/ThreadMXBean/ThreadStackTrace.java b/jdk/test/java/lang/management/ThreadMXBean/ThreadStackTrace.java index 12cef4a978b..4842d623c35 100644 --- a/jdk/test/java/lang/management/ThreadMXBean/ThreadStackTrace.java +++ b/jdk/test/java/lang/management/ThreadMXBean/ThreadStackTrace.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,25 +28,26 @@ * ThreadInfo.getThreadState() * @author Mandy Chung * - * @run build Semaphore Utils + * @run build Utils * @run main ThreadStackTrace */ import java.lang.management.*; +import java.util.concurrent.Phaser; public class ThreadStackTrace { - private static ThreadMXBean mbean + private static final ThreadMXBean mbean = ManagementFactory.getThreadMXBean(); private static boolean notified = false; - private static Object lockA = new Object(); - private static Object lockB = new Object(); + private static final Object lockA = new Object(); + private static final Object lockB = new Object(); private static volatile boolean testFailed = false; - private static String[] blockedStack = {"run", "test", "A", "B", "C", "D"}; - private static int bsDepth = 6; - private static int methodB = 4; - private static String[] examinerStack = {"run", "examine1", "examine2"}; - private static int esDepth = 3; - private static int methodExamine1= 2; + private static final String[] blockedStack = {"run", "test", "A", "B", "C", "D"}; + private static final int bsDepth = 6; + private static final int methodB = 4; + private static final String[] examinerStack = {"run", "examine1", "examine2"}; + private static final int esDepth = 3; + private static final int methodExamine1= 2; private static void checkNullThreadInfo(Thread t) throws Exception { ThreadInfo ti = mbean.getThreadInfo(t.getId()); @@ -69,8 +70,10 @@ public class ThreadStackTrace { trace = true; } - Examiner examiner = new Examiner("Examiner"); - BlockedThread blocked = new BlockedThread("BlockedThread"); + final Phaser p = new Phaser(2); + + Examiner examiner = new Examiner("Examiner", p); + BlockedThread blocked = new BlockedThread("BlockedThread", p); examiner.setThread(blocked); checkNullThreadInfo(examiner); @@ -79,8 +82,8 @@ public class ThreadStackTrace { // Start the threads and check them in Blocked and Waiting states examiner.start(); - // block until examiner begins doing its real work - examiner.waitForStarted(); + // #1 - block until examiner begins doing its real work + p.arriveAndAwaitAdvance(); System.out.println("Checking stack trace for the examiner thread " + "is waiting to begin."); @@ -145,35 +148,11 @@ public class ThreadStackTrace { } static class BlockedThread extends Thread { - private Semaphore handshake = new Semaphore(); + private final Phaser phaser; - BlockedThread(String name) { + BlockedThread(String name, Phaser phaser) { super(name); - } - boolean hasWaitersForBlocked() { - return (handshake.getWaiterCount() > 0); - } - - void waitUntilBlocked() { - handshake.semaP(); - - // give a chance for the examiner thread to really wait - Utils.goSleep(20); - } - - void waitUntilLockAReleased() { - handshake.semaP(); - - // give a chance for the examiner thread to really wait - Utils.goSleep(50); - } - - private void notifyWaiter() { - // wait until the examiner waits on the semaphore - while (handshake.getWaiterCount() == 0) { - Utils.goSleep(20); - } - handshake.semaV(); + this.phaser = phaser; } private void test() { @@ -185,25 +164,24 @@ public class ThreadStackTrace { private void B() { C(); - // notify the examiner about to block on lockB - notifyWaiter(); + // #4 - notify the examiner about to block on lockB + phaser.arriveAndAwaitAdvance(); - synchronized (lockB) { - }; + synchronized (lockB) {}; } private void C() { D(); } private void D() { - // Notify that examiner about to enter lockA - notifyWaiter(); + // #2 - Notify that examiner about to enter lockA + phaser.arriveAndAwaitAdvance(); synchronized (lockA) { notified = false; while (!notified) { try { - // notify the examiner about to release lockA - notifyWaiter(); + // #3 - notify the examiner about to release lockA + phaser.arriveAndAwaitAdvance(); // Wait and let examiner thread check the mbean lockA.wait(); } catch (InterruptedException e) { @@ -216,6 +194,7 @@ public class ThreadStackTrace { } } + @Override public void run() { test(); } // run() @@ -223,28 +202,17 @@ public class ThreadStackTrace { static class Examiner extends Thread { private static BlockedThread blockedThread; - private Semaphore handshake = new Semaphore(); + private final Phaser phaser; - Examiner(String name) { + Examiner(String name, Phaser phaser) { super(name); + this.phaser = phaser; } public void setThread(BlockedThread thread) { blockedThread = thread; } - public synchronized void waitForStarted() { - // wait until the examiner is about to block - handshake.semaP(); - - // wait until the examiner is waiting for blockedThread's notification - while (!blockedThread.hasWaitersForBlocked()) { - Utils.goSleep(50); - } - // give a chance for the examiner thread to really wait - Utils.goSleep(20); - } - private Thread itself; private void examine1() { synchronized (lockB) { @@ -254,8 +222,9 @@ public class ThreadStackTrace { Utils.checkThreadState(itself, Thread.State.RUNNABLE); checkStack(itself, examinerStack, methodExamine1); - // wait until blockedThread is blocked on lockB - blockedThread.waitUntilBlocked(); + // #4 - wait until blockedThread is blocked on lockB + phaser.arriveAndAwaitAdvance(); + Utils.waitForThreadState(blockedThread, State.BLOCKED); System.out.println("Checking stack trace for " + "BlockedThread - should be blocked on lockB."); @@ -271,15 +240,12 @@ public class ThreadStackTrace { private void examine2() { synchronized (lockA) { - // wait until main thread gets signalled of the semaphore - while (handshake.getWaiterCount() == 0) { - Utils.goSleep(20); - } - - handshake.semaV(); // notify the main thread + // #1 - examiner ready to do the real work + phaser.arriveAndAwaitAdvance(); try { - // Wait until BlockedThread is about to block on lockA - blockedThread.waitUntilBlocked(); + // #2 - Wait until BlockedThread is about to block on lockA + phaser.arriveAndAwaitAdvance(); + Utils.waitForThreadState(blockedThread, State.BLOCKED); System.out.println("Checking examiner's its own stack trace"); Utils.checkThreadState(itself, Thread.State.RUNNABLE); @@ -297,9 +263,10 @@ public class ThreadStackTrace { } } - // release lockA and let BlockedThread to get the lock + // #3 - release lockA and let BlockedThread to get the lock // and wait on lockA - blockedThread.waitUntilLockAReleased(); + phaser.arriveAndAwaitAdvance(); + Utils.waitForThreadState(blockedThread, State.WAITING); synchronized (lockA) { try { @@ -321,6 +288,7 @@ public class ThreadStackTrace { Utils.goSleep(50); } // examine2() + @Override public void run() { itself = Thread.currentThread(); examine1(); diff --git a/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java index 31c2e3327cc..98239775661 100644 --- a/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java +++ b/jdk/test/lib/testlibrary/jdk/testlibrary/ProcessTools.java @@ -227,7 +227,8 @@ public final class ProcessTools { * The default redirects of STDOUT and STDERR are started *

* It is possible to wait for the process to get to a warmed-up state - * via {@linkplain Predicate} condition on the STDOUT + * via {@linkplain Predicate} condition on the STDOUT. The warm-up will + * wait indefinitely. *

* @param name The process name * @param processBuilder The process builder diff --git a/jdk/test/sun/management/PlatformMBeanProviderConstructorCheck.java b/jdk/test/sun/management/PlatformMBeanProviderConstructorCheck.java new file mode 100644 index 00000000000..3c806864419 --- /dev/null +++ b/jdk/test/sun/management/PlatformMBeanProviderConstructorCheck.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.security.AccessControlException; +import java.security.Permission; +import java.security.Policy; +import java.security.ProtectionDomain; +import java.util.List; + +/* + * @test + * @bug 8042901 + * @summary Check permission for PlatformMBeanProvider Constructor + * @author Shanliang Jiang + */ +public class PlatformMBeanProviderConstructorCheck { + public static void main(String[] args) throws Exception { + Policy origPolicy = Policy.getPolicy(); + SecurityManager origSM = System.getSecurityManager(); + try { + System.out.println("---PlatformMBeanProviderConstructorCheck starting..."); + + Policy.setPolicy(new MyPolicy()); + System.setSecurityManager(new SecurityManager()); + + System.out.println("---PlatformMBeanProviderConstructorCheck Testing without permission..."); + try { + new MyProvider(); + throw new RuntimeException("Does not get expected AccessControlException!"); + } catch (AccessControlException ace) { + System.out.println("---PlatformMBeanProviderConstructorCheck got the expected exception: " + + ace); + } + + System.out.println("---PlatformMBeanProviderConstructorCheck Testing with permission..."); + MyPolicy.allowed = true; + new MyProvider(); + + System.out.println("---PlatformMBeanProviderConstructorCheck PASSED!"); + } finally { + System.setSecurityManager(origSM); + Policy.setPolicy(origPolicy); + } + } + + private static class MyPolicy extends Policy { + private static String permName = "sun.management.spi.PlatformMBeanProvider.subclass"; + private static boolean allowed = false; + + @Override + public boolean implies(ProtectionDomain domain, Permission permission) { + if (permName.equals(permission.getName())) { + System.out.println("---MyPolicy-implies checks permission for " + +permName+" and returns "+allowed); + + return allowed; + } else { + return true; + } + } + } + + private static class MyProvider extends sun.management.spi.PlatformMBeanProvider { + @Override + public List> getPlatformComponentList() { + return null; + } + } +} diff --git a/jdk/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java b/jdk/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java index 1306f4e31a6..9abb9d38ae2 100644 --- a/jdk/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java +++ b/jdk/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -120,9 +120,7 @@ public class LocalManagementTest { return true; } return false; - }, - 5, - TimeUnit.SECONDS + } ); System.out.println("Attaching test manager:"); @@ -142,9 +140,7 @@ public class LocalManagementTest { clientPrc = ProcessTools.startProcess( "TestManager", client, - (String line) -> line.startsWith("Starting TestManager for PID"), - 10, - TimeUnit.SECONDS + (String line) -> line.startsWith("Starting TestManager for PID") ); int clientExitCode = clientPrc.waitFor(); diff --git a/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java index de5e9b6bbcd..2e2ca1b3c66 100644 --- a/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java +++ b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java @@ -35,20 +35,16 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Objects; -import java.util.Random; import java.util.Set; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; -import java.util.stream.Collectors; import javax.management.*; import javax.management.remote.*; import javax.net.ssl.SSLHandshakeException; import jdk.testlibrary.ProcessTools; -import jdk.testlibrary.JDKToolLauncher; import sun.management.Agent; import sun.management.AgentConfigurationError; @@ -56,46 +52,20 @@ import sun.management.AgentConfigurationError; * @test * @bug 7110104 * @library /lib/testlibrary - * @build jdk.testlibrary.* JMXStartStopTest JMXStartStopDoSomething + * @build jdk.testlibrary.* JMXStartStopTest PortAllocator TestApp ManagementAgentJcmd * @run main/othervm/timeout=600 -XX:+UsePerfData JMXStartStopTest * @summary Makes sure that enabling/disabling the management agent through JCMD * achieves the desired results * @key randomness */ public class JMXStartStopTest { + private static final String TEST_APP_NAME = "TestApp"; private static final String TEST_SRC = System.getProperty("test.src"); private static final boolean verbose = false; - /** - * Dynamically allocates distinct ports from the ephemeral range 49152-65535 - */ - private static class PortAllocator { - - private final static int LOWER_BOUND = 49152; - private final static int UPPER_BOUND = 65535; - - private final static Random RND = new Random(System.currentTimeMillis()); - - private static int[] allocatePorts(final int numPorts) { - int[] ports = new int[numPorts]; - for (int i = 0; i < numPorts; i++) { - int port = -1; - while (port == -1) { - port = RND.nextInt(UPPER_BOUND - LOWER_BOUND + 1) + LOWER_BOUND; - for (int j = 0; j < i; j++) { - if (ports[j] == port) { - port = -1; - break; - } - } - } - ports[i] = port; - } - return ports; - } - } + private static ManagementAgentJcmd jcmd = new ManagementAgentJcmd(TEST_APP_NAME, verbose); private static void dbg_print(String msg) { if (verbose) { @@ -318,14 +288,14 @@ public class JMXStartStopTest { } } - private static class Something { + private static class TestAppRun { private Process p; private final ProcessBuilder pb; private final String name; private final AtomicBoolean started = new AtomicBoolean(false); private volatile long pid = -1; - public Something(ProcessBuilder pb, String name) { + public TestAppRun(ProcessBuilder pb, String name) { this.pb = pb; this.name = name; } @@ -335,16 +305,14 @@ public class JMXStartStopTest { try { AtomicBoolean error = new AtomicBoolean(false); p = ProcessTools.startProcess( - "JMXStartStopDoSomething{" + name + "}", + TEST_APP_NAME + "{" + name + "}", pb, (line) -> { boolean ok = line.equals("main enter"); error.set(line.contains("BindException")); return ok || error.get(); - }, - 5, - TimeUnit.SECONDS + } ); if (error.get()) { throw new BindException("Starting process failed due to " + @@ -352,8 +320,10 @@ public class JMXStartStopTest { } pid = p.getPid(); } catch (TimeoutException e) { - p.destroy(); - p.waitFor(); + if (p != null) { + p.destroy(); + p.waitFor(); + } throw e; } } @@ -382,105 +352,32 @@ public class JMXStartStopTest { } /** - * Runs the test application "JMXStartStopDoSomething" + * Runs the test application "TestApp" * @param name Test run name * @param args Additional arguments - * @return Returns a {@linkplain Something} instance representing the run + * @return Returns a {@linkplain TestAppRun} instance representing the run * @throws IOException * @throws InterruptedException * @throws TimeoutException */ - private static Something doSomething(String name, String ... args) + private static TestAppRun doTest(String name, String ... args) throws Exception { List pbArgs = new ArrayList<>(Arrays.asList( "-cp", - System.getProperty("test.class.path") + System.getProperty("test.class.path"), + "-XX:+UsePerfData" )); pbArgs.addAll(Arrays.asList(args)); - pbArgs.add("JMXStartStopDoSomething"); + pbArgs.add(TEST_APP_NAME); ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( pbArgs.toArray(new String[pbArgs.size()]) ); - Something s = new Something(pb, name); + TestAppRun s = new TestAppRun(pb, name); s.start(); return s; } - /** - * Run the "jcmd" command - * - * @param command Command with parameters; space separated string - * @throws IOException - * @throws InterruptedException - */ - private static void jcmd(String ... command) throws IOException, InterruptedException { - if (command.length == 0) { - jcmd(null, c->{}); - } else { - jcmd(null, command); - } - } - - /** - * Run the "jcmd" command - * - * @param c {@linkplain Consumer} instance - * @param command Command with parameters; space separated string - * @throws IOException - * @throws InterruptedException - */ - private static void jcmd(Consumer c, String ... command) throws IOException, InterruptedException { - jcmd("JMXStartStopDoSomething", c, command); - } - - /** - * Run the "jcmd" command - * - * @param target The target application name (or PID) - * @param c {@linkplain Consumer} instance - * @param command Command with parameters; space separated string - * @throws IOException - * @throws InterruptedException - */ - private static void jcmd(String target, final Consumer c, String ... command) throws IOException, InterruptedException { - dbg_print("[jcmd] " + (command.length > 0 ? command[0] : "list")); - - JDKToolLauncher l = JDKToolLauncher.createUsingTestJDK("jcmd"); - l.addToolArg(target); - for (String cmd : command) { - l.addToolArg(cmd); - } - - AtomicBoolean portUnavailable = new AtomicBoolean(false); - Process p = ProcessTools.startProcess( - "jcmd", - new ProcessBuilder(l.getCommand()), - line -> { - if (line.contains("BindException") || - line.contains(Agent.getText(AgentConfigurationError.CONNECTOR_SERVER_IO_ERROR))) { - portUnavailable.set(true); - } else { - c.accept(line); - } - } - ); - - p.waitFor(); - dbg_print("[jcmd] --------"); - if (portUnavailable.get()) { - String cmd = Arrays.asList(l.getCommand()).stream() - .collect( - Collectors.joining(" ", "", ": Unable to bind address") - ); - throw new BindException(cmd); - } - } - - private static final String CMD_STOP = "ManagementAgent.stop"; - private static final String CMD_START = "ManagementAgent.start"; - private static final String CMD_START_LOCAL = "ManagementAgent.start_local"; - static void test_01() throws Exception { // Run an app with JMX enabled stop it and // restart on other port @@ -488,7 +385,7 @@ public class JMXStartStopTest { System.out.println("**** Test one ****"); int ports[] = PortAllocator.allocatePorts(2); - Something s = doSomething( + TestAppRun s = doTest( "test_01", "-Dcom.sun.management.jmxremote.port=" + ports[0], "-Dcom.sun.management.jmxremote.authenticate=false", @@ -497,10 +394,10 @@ public class JMXStartStopTest { try { testConnect(ports[0]); - jcmd(CMD_STOP); + jcmd.stop(); testNoConnect(ports[0]); - jcmd(CMD_START, "jmxremote.port=" + ports[1]); + jcmd.start("jmxremote.port=" + ports[1]); testConnect(ports[1]); } finally { s.stop(); @@ -514,12 +411,13 @@ public class JMXStartStopTest { System.out.println("**** Test two ****"); int[] ports = PortAllocator.allocatePorts(1); - Something s = doSomething("test_02"); + TestAppRun s = doTest("test_02"); try { - jcmd(CMD_START, - "jmxremote.port=" + ports[0], - "jmxremote.authenticate=false", - "jmxremote.ssl=false"); + jcmd.start( + "jmxremote.port=" + ports[0], + "jmxremote.authenticate=false", + "jmxremote.ssl=false" + ); testConnect(ports[0]); } finally { @@ -535,18 +433,20 @@ public class JMXStartStopTest { System.out.println("**** Test three ****"); int[] ports = PortAllocator.allocatePorts(2); - Something s = doSomething("test_03"); + TestAppRun s = doTest("test_03"); try { - jcmd(CMD_START, - "jmxremote.port=" + ports[0], - "jmxremote.authenticate=false", - "jmxremote.ssl=false"); + jcmd.start( + "jmxremote.port=" + ports[0], + "jmxremote.authenticate=false", + "jmxremote.ssl=false" + ); // Second agent shouldn't start - jcmd(CMD_START, - "jmxremote.port=" + ports[1], - "jmxremote.authenticate=false", - "jmxremote.ssl=false"); + jcmd.start( + "jmxremote.port=" + ports[1], + "jmxremote.authenticate=false", + "jmxremote.ssl=false" + ); // First agent should connect testConnect(ports[0]); @@ -565,13 +465,14 @@ public class JMXStartStopTest { System.out.println("**** Test four ****"); int[] ports = PortAllocator.allocatePorts(2); - Something s = doSomething("test_04"); + TestAppRun s = doTest("test_04"); try { - jcmd(CMD_START, - "jmxremote.port=" + ports[0], - "jmxremote.rmi.port=" + ports[1], - "jmxremote.authenticate=false", - "jmxremote.ssl=false"); + jcmd.start( + "jmxremote.port=" + ports[0], + "jmxremote.rmi.port=" + ports[1], + "jmxremote.authenticate=false", + "jmxremote.ssl=false" + ); testConnect(ports[0], ports[1]); } finally { @@ -585,9 +486,9 @@ public class JMXStartStopTest { System.out.println("**** Test five ****"); int[] ports = PortAllocator.allocatePorts(1); - Something s = doSomething("test_05"); + TestAppRun s = doTest("test_05"); try { - jcmd(CMD_START_LOCAL); + jcmd.startLocal(); testNoConnect(ports[0]); testConnectLocal(s.getPid()); @@ -605,26 +506,27 @@ public class JMXStartStopTest { System.out.println("**** Test six ****"); int[] ports = PortAllocator.allocatePorts(2); - Something s = doSomething("test_06"); + TestAppRun s = doTest("test_06"); try { - jcmd(CMD_START, - "jmxremote.port=" + ports[0], - "jmxremote.authenticate=false", - "jmxremote.ssl=false"); + jcmd.start( + "jmxremote.port=" + ports[0], + "jmxremote.authenticate=false", + "jmxremote.ssl=false" + ); testConnect(ports[0], ports[1]); final AtomicBoolean checks = new AtomicBoolean(false); - jcmd( - line -> { - if (line.contains("java.lang.RuntimeException: Invalid agent state")) { - checks.set(true); - } - }, - CMD_START, - "jmxremote.port=" + ports[0], - "jmxremote.authenticate=false", - "jmxremote.ssl=false"); + jcmd.start( + line -> { + if (line.contains("java.lang.RuntimeException: Invalid agent state")) { + checks.set(true); + } + }, + "jmxremote.port=" + ports[0], + "jmxremote.authenticate=false", + "jmxremote.ssl=false" + ); if (!checks.get()) { throw new Exception("Starting agent on port " + ports[0] + " should " @@ -644,27 +546,28 @@ public class JMXStartStopTest { System.out.println("**** Test seven ****"); int[] ports = PortAllocator.allocatePorts(2); - Something s = doSomething("test_07"); + TestAppRun s = doTest("test_07"); try { - jcmd(CMD_START, - "jmxremote.port=" + ports[0], - "jmxremote.authenticate=false", - "jmxremote.ssl=false"); + jcmd.start( + "jmxremote.port=" + ports[0], + "jmxremote.authenticate=false", + "jmxremote.ssl=false" + ); testConnect(ports[0], ports[1]); final AtomicBoolean checks = new AtomicBoolean(false); - jcmd( - line -> { - if (line.contains("java.lang.RuntimeException: Invalid agent state")) { - checks.set(true); - } - }, - CMD_START, - "jmxremote.port=" + ports[1], - "jmxremote.authenticate=false", - "jmxremote.ssl=false"); + jcmd.start( + line -> { + if (line.contains("java.lang.RuntimeException: Invalid agent state")) { + checks.set(true); + } + }, + "jmxremote.port=" + ports[1], + "jmxremote.authenticate=false", + "jmxremote.ssl=false" + ); if (!checks.get()) { throw new Exception("Starting agent on poprt " + ports[1] + " should " @@ -684,17 +587,18 @@ public class JMXStartStopTest { System.out.println("**** Test eight ****"); int[] ports = PortAllocator.allocatePorts(2); - Something s = doSomething("test_08"); + TestAppRun s = doTest("test_08"); try { - jcmd(CMD_START, - "jmxremote.port=" + ports[0], - "jmxremote.authenticate=false", - "jmxremote.ssl=false"); + jcmd.start( + "jmxremote.port=" + ports[0], + "jmxremote.authenticate=false", + "jmxremote.ssl=false" + ); testConnect(ports[0], ports[1]); - jcmd(CMD_STOP); - jcmd(CMD_STOP); + jcmd.stop(); + jcmd.stop(); } finally { s.stop(); } @@ -707,7 +611,7 @@ public class JMXStartStopTest { System.out.println("**** Test nine ****"); - Something s = doSomething("test_09"); + TestAppRun s = doTest("test_09"); try (ServerSocket ss = new ServerSocket(0)) { int localPort = ss.getLocalPort(); @@ -723,13 +627,12 @@ public class JMXStartStopTest { final AtomicBoolean retry = new AtomicBoolean(false); try { - jcmd( + jcmd.start( line -> { if (line.contains(Agent.getText(AgentConfigurationError.AGENT_EXCEPTION))) { retry.set(true); } }, - CMD_START, "jmxremote.port=" + ports[0], "jmxremote.rmi.port=" + localPort, "jmxremote.authenticate=false", @@ -764,18 +667,17 @@ public class JMXStartStopTest { System.out.println("**** Test ten ****"); int[] ports = PortAllocator.allocatePorts(2); - Something s = doSomething( + TestAppRun s = doTest( "test_10", "-Dcom.sun.management.jmxremote.authenticate=false", "-Dcom.sun.management.jmxremote.ssl=true"); try { testNoConnect(ports[0]); - jcmd( - CMD_START, - "jmxremote.port=" + ports[1], - "jmxremote.authenticate=false", - "jmxremote.ssl=false" + jcmd.start( + "jmxremote.port=" + ports[1], + "jmxremote.authenticate=false", + "jmxremote.ssl=false" ); testConnect(ports[1]); } finally { @@ -791,7 +693,7 @@ public class JMXStartStopTest { System.out.println("**** Test eleven ****"); int[] ports = PortAllocator.allocatePorts(2); - Something s = doSomething( + TestAppRun s = doTest( "test_11", "-Dcom.sun.management.jmxremote.port=" + ports[0], "-Dcom.sun.management.jmxremote.authenticate=false", @@ -800,15 +702,14 @@ public class JMXStartStopTest { try { testNoConnect(ports[0]); - jcmd(CMD_STOP); + jcmd.stop(); testNoConnect(ports[0]); - jcmd( - CMD_START, - "jmxremote.port=" + ports[1], - "jmxremote.authenticate=false", - "jmxremote.ssl=false" + jcmd.start( + "jmxremote.port=" + ports[1], + "jmxremote.authenticate=false", + "jmxremote.ssl=false" ); testConnect(ports[1]); @@ -828,7 +729,7 @@ public class JMXStartStopTest { System.out.println("**** Test twelve ****"); int[] ports = PortAllocator.allocatePorts(2); - Something s = doSomething("test_12", + TestAppRun s = doTest("test_12", "-Dcom.sun.management.config.file=" + TEST_SRC + File.separator + "management_cl.properties", "-Dcom.sun.management.jmxremote.authenticate=false" @@ -837,15 +738,15 @@ public class JMXStartStopTest { try { testNoConnect(ports[0]); - jcmd(CMD_STOP); + jcmd.stop(); testNoConnect(ports[0]); - jcmd(CMD_START, - "config.file=" + TEST_SRC + File.separator - + "management_jcmd.properties", - "jmxremote.authenticate=false", - "jmxremote.port=" + ports[1] + jcmd.start( + "config.file=" + TEST_SRC + File.separator + + "management_jcmd.properties", + "jmxremote.authenticate=false", + "jmxremote.port=" + ports[1] ); testConnect(ports[1]); @@ -863,7 +764,7 @@ public class JMXStartStopTest { System.out.println("**** Test thirteen ****"); int[] ports = PortAllocator.allocatePorts(1); - Something s = doSomething( + TestAppRun s = doTest( "test_13", "-Dcom.sun.management.jmxremote.port=" + ports[0], "-Dcom.sun.management.jmxremote.authenticate=false", @@ -872,16 +773,16 @@ public class JMXStartStopTest { try { testNoConnect(ports[0]); - jcmd(CMD_STOP); - jcmd(CMD_START, - "jmxremote.ssl=false", - "jmxremote.port=" + ports[0] + jcmd.stop(); + jcmd.start( + "jmxremote.ssl=false", + "jmxremote.port=" + ports[0] ); testConnect(ports[0]); - jcmd(CMD_STOP); - jcmd(CMD_START, - "jmxremote.port=" + ports[0] + jcmd.stop(); + jcmd.start( + "jmxremote.port=" + ports[0] ); testNoConnect(ports[0]); @@ -897,14 +798,14 @@ public class JMXStartStopTest { System.out.println("**** Test fourteen ****"); int[] ports = PortAllocator.allocatePorts(1); - Something s = doSomething( + TestAppRun s = doTest( "test_14", "-Dcom.sun.management.jmxremote.port=" + ports[0], "-Dcom.sun.management.jmxremote.authenticate=false", "-Dcom.sun.management.jmxremote.ssl=false"); try { testConnect(ports[0]); - jcmd(CMD_STOP); + jcmd.stop(); testConnectLocal(s.getPid()); } finally { s.stop(); @@ -918,11 +819,11 @@ public class JMXStartStopTest { System.out.println("**** Test fifteen ****"); int[] ports = PortAllocator.allocatePorts(1); - Something s = doSomething("test_15"); + TestAppRun s = doTest("test_15"); try { testNoConnect(ports[0]); - jcmd(CMD_START + "_local"); + jcmd.startLocal(); testConnectLocal(s.getPid()); diff --git a/jdk/test/sun/management/jmxremote/startstop/JMXStatusTest.java b/jdk/test/sun/management/jmxremote/startstop/JMXStatusTest.java new file mode 100644 index 00000000000..808b5a3c339 --- /dev/null +++ b/jdk/test/sun/management/jmxremote/startstop/JMXStatusTest.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.net.BindException; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import org.testng.annotations.*; +import static org.testng.Assert.*; + +import jdk.testlibrary.ProcessTools; + +/** + * @test + * @bug 8023093 + * @summary Performs a sanity test for the ManagementAgent.status diagnostic command. + * Management agent may be disable, started (only local connections) and started. + * The test asserts that the expected text is being printed. + * @library /lib/testlibrary + * @build jdk.testlibrary.* PortAllocator TestApp ManagementAgentJcmd + * @run testng/othervm -XX:+UsePerfData JMXStatusTest + */ +public class JMXStatusTest { + private final static String TEST_APP_NAME = "TestApp"; + + private final static Pattern DISABLE_AGENT_STATUS = Pattern.compile( + "Agent\\s*\\: disabled$" + ); + + private final static Pattern LOCAL_AGENT_STATUS = Pattern.compile( + "Agent\\s*\\:\\s*enabled\\n+" + + "Connection Type\\s*\\:\\s*local\\n+" + + "Protocol\\s*\\:\\s*[a-z]+\\n+" + + "Host\\s*\\:\\s*.+\\n+" + + "URL\\s*\\:\\s*service\\:jmx\\:.+", + Pattern.MULTILINE + ); + + private final static Pattern REMOTE_AGENT_STATUS = Pattern.compile( + "Agent\\s*\\: enabled\\n+" + + "Connection Type\\s*\\: remote\\n+" + + "Protocol\\s*\\: [a-z]+\\n+" + + "Host\\s*\\: .+\\n+" + + "URL\\s*\\: service\\:jmx\\:.+\\n+" + + "Properties\\s*\\:\\n+(\\s*\\S+\\s*=\\s*\\S+\\n*)+", + Pattern.MULTILINE + ); + + private static ProcessBuilder testAppPb; + private Process testApp; + + private ManagementAgentJcmd jcmd; + + @BeforeClass + public static void setupClass() throws Exception { + testAppPb = ProcessTools.createJavaProcessBuilder( + "-cp", System.getProperty("test.class.path"), + "-XX:+UsePerfData", + TEST_APP_NAME + ); + } + + @BeforeTest + public void setup() { + jcmd = new ManagementAgentJcmd(TEST_APP_NAME, false); + } + + @BeforeMethod + public void startTestApp() throws Exception { + testApp = ProcessTools.startProcess( + TEST_APP_NAME, testAppPb, + (Predicate)l->l.trim().equals("main enter") + ); + } + + @AfterMethod + public void stopTestApp() throws Exception { + testApp.getOutputStream().write(1); + testApp.getOutputStream().flush(); + testApp.waitFor(); + testApp = null; + } + + @Test + public void testAgentDisabled() throws Exception { + String status = jcmd.status(); + assertStatusMatches(DISABLE_AGENT_STATUS, status); + } + + @Test + public void testAgentLocal() throws Exception { + jcmd.startLocal(); + String status = jcmd.status(); + + assertStatusMatches(LOCAL_AGENT_STATUS, status); + } + + @Test + public void testAgentRemote() throws Exception { + while (true) { + try { + int[] ports = PortAllocator.allocatePorts(1); + jcmd.start( + "jmxremote.port=" + ports[0], + "jmxremote.authenticate=false", + "jmxremote.ssl=false" + ); + String status = jcmd.status(); + + assertStatusMatches(REMOTE_AGENT_STATUS, status); + return; + } catch (BindException e) { + System.out.println("Failed to allocate ports. Retrying ..."); + } + } + } + + private void assertStatusMatches(Pattern expected, String value) { + assertStatusMatches(expected, value, ""); + } + + private void assertStatusMatches(Pattern expected, String value, String msg) { + int idx = value.indexOf('\n'); + if (idx > -1) { + value = value.substring(idx + 1).trim(); + assertTrue(expected.matcher(value).find(), msg); + } else { + fail("The management agent status must contain more then one line of text"); + } + } +} diff --git a/jdk/test/sun/management/jmxremote/startstop/ManagementAgentJcmd.java b/jdk/test/sun/management/jmxremote/startstop/ManagementAgentJcmd.java new file mode 100644 index 00000000000..efee771cf4a --- /dev/null +++ b/jdk/test/sun/management/jmxremote/startstop/ManagementAgentJcmd.java @@ -0,0 +1,198 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.io.IOException; +import java.net.BindException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; +import java.util.stream.Collectors; +import sun.management.Agent; +import sun.management.AgentConfigurationError; + +import jdk.testlibrary.JDKToolLauncher; +import jdk.testlibrary.ProcessTools; + +/** + * A helper class for issuing ManagementAgent.* diagnostic commands and capturing + * their output. + */ +final class ManagementAgentJcmd { + private static final String CMD_STOP = "ManagementAgent.stop"; + private static final String CMD_START = "ManagementAgent.start"; + private static final String CMD_START_LOCAL = "ManagementAgent.start_local"; + private static final String CMD_STATUS = "ManagementAgent.status"; + + private final String id; + private final boolean verbose; + + public ManagementAgentJcmd(String targetApp, boolean verbose) { + this.id = targetApp; + this.verbose = verbose; + } + + /** + * `jcmd` + * @return The JCMD output + * @throws IOException + * @throws InterruptedException + */ + public String list() throws IOException, InterruptedException { + return jcmd(); + } + + /** + * `jcmd ManagementAgent.stop` + * @return The JCMD output + * @throws IOException + * @throws InterruptedException + */ + public String stop() throws IOException, InterruptedException { + return jcmd(CMD_STOP); + } + + /** + * `jcmd ManagementAgent.start_local` + * @return The JCMD output + * @throws IOException + * @throws InterruptedException + */ + public String startLocal() throws IOException, InterruptedException { + return jcmd(CMD_START_LOCAL); + } + + /** + * `jcmd ManagementAgent.start ` + * @return The JCMD output + * @param params The arguments to ManagementAgent.start command + * @throws IOException + * @throws InterruptedException + */ + public String start(String ... params) throws IOException, InterruptedException { + return start(c->{}, params); + } + + /** + * `jcmd ManagementAgent.start ` + * @param c A string consumer used to inspect the jcmd output line-by-line + * @param params The arguments to ManagementAgent.start command + * @return The JCMD output + * @throws IOException + * @throws InterruptedException + */ + public String start(Consumer c, String ... params) throws IOException, InterruptedException { + List args = new ArrayList<>(); + args.add(CMD_START); + args.addAll(Arrays.asList(params)); + return jcmd(c, args.toArray(new String[args.size()])); + } + + public String status() throws IOException, InterruptedException { + return jcmd(CMD_STATUS); + } + + /** + * Run the "jcmd" command + * + * @param command Command + arguments + * @return The JCMD output + * @throws IOException + * @throws InterruptedException + */ + private String jcmd(String ... command) throws IOException, InterruptedException { + if (command.length == 0) { + return jcmd(null, c->{}); + } else { + return jcmd(c->{}, command); + } + } + + /** + * Run the "jcmd" command + * + * @param c {@linkplain Consumer} instance + * @param command Command + arguments + * @return The JCMD output + * @throws IOException + * @throws InterruptedException + */ + private String jcmd(Consumer c, String ... command) throws IOException, InterruptedException { + return jcmd(id, c, command); + } + + /** + * Run the "jcmd" command + * + * @param target The target application name (or PID) + * @param c {@linkplain Consumer} instance + * @param command Command + arguments + * @return The JCMD output + * @throws IOException + * @throws InterruptedException + */ + private String jcmd(String target, final Consumer c, String ... command) throws IOException, InterruptedException { + dbg_print("[jcmd] " + (command.length > 0 ? command[0] : "list")); + + JDKToolLauncher l = JDKToolLauncher.createUsingTestJDK("jcmd"); + l.addToolArg(target); + for (String cmd : command) { + l.addToolArg(cmd); + } + + StringBuilder output = new StringBuilder(); + + AtomicBoolean portUnavailable = new AtomicBoolean(false); + Process p = ProcessTools.startProcess( + "jcmd", + new ProcessBuilder(l.getCommand()), + line -> { + if (line.contains("BindException") || + line.contains(Agent.getText(AgentConfigurationError.CONNECTOR_SERVER_IO_ERROR))) { + portUnavailable.set(true); + } else { + output.append(line).append('\n'); + c.accept(line); + } + } + ); + + p.waitFor(); + dbg_print("[jcmd] --------"); + if (portUnavailable.get()) { + String cmd = Arrays.asList(l.getCommand()).stream() + .collect( + Collectors.joining(" ", "", ": Unable to bind address") + ); + throw new BindException(cmd); + } + + return output.toString(); + } + + private void dbg_print(String msg) { + if (verbose) { + System.out.println("DBG: " + msg); + } + } +} diff --git a/jdk/test/java/lang/management/ThreadMXBean/Semaphore.java b/jdk/test/sun/management/jmxremote/startstop/PortAllocator.java similarity index 50% rename from jdk/test/java/lang/management/ThreadMXBean/Semaphore.java rename to jdk/test/sun/management/jmxremote/startstop/PortAllocator.java index c5a6635f286..444dfbde410 100644 --- a/jdk/test/java/lang/management/ThreadMXBean/Semaphore.java +++ b/jdk/test/sun/management/jmxremote/startstop/PortAllocator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,54 +21,32 @@ * questions. */ -/* - * @bug 4530538 - * @summary A semaphore utility class. - * @author Mandy Chung +import java.util.Random; + +/** + * Dynamically allocates distinct ports from the ephemeral range 49152-65535 */ +class PortAllocator { + private final static int LOWER_BOUND = 49152; + private final static int UPPER_BOUND = 65535; -public class Semaphore { - private Object go = new Object(); - private int semaCount; - private int waiters = 0; + private final static Random RND = new Random(System.currentTimeMillis()); - public Semaphore() { - semaCount = 0; - } - - public Semaphore(int initialCount) { - semaCount = initialCount; - } - - public void semaP() { - synchronized (go) { - waiters++; - while (semaCount == 0) { - try { - go.wait(); - } catch (InterruptedException e) { - e.printStackTrace(); - throw new InternalError(); + static int[] allocatePorts(final int numPorts) { + int[] ports = new int[numPorts]; + for (int i = 0; i < numPorts; i++) { + int port = -1; + while (port == -1) { + port = RND.nextInt(UPPER_BOUND - LOWER_BOUND + 1) + LOWER_BOUND; + for (int j = 0; j < i; j++) { + if (ports[j] == port) { + port = -1; + break; + } } } - semaCount--; - waiters--; + ports[i] = port; } - } - public void semaV() { - synchronized (go) { - semaCount++; - go.notify(); - } - } - - public int getWaiterCount() { - synchronized (go) { - return waiters; - } - } - - public Object getLock() { - return go; + return ports; } } diff --git a/jdk/test/sun/management/jmxremote/startstop/REMOTE_TESTING.txt b/jdk/test/sun/management/jmxremote/startstop/REMOTE_TESTING.txt index 20c85f1f0be..770bf20f228 100644 --- a/jdk/test/sun/management/jmxremote/startstop/REMOTE_TESTING.txt +++ b/jdk/test/sun/management/jmxremote/startstop/REMOTE_TESTING.txt @@ -4,7 +4,7 @@ on host 1 4. run - ${TESTJAVA}/bin/java -server JMXStartStopDoSomething \ + ${TESTJAVA}/bin/java -server TestApp \ -Dcom.sun.management.jmxremote.port=50234 \ -Dcom.sun.management.jmxremote.rmi.port=50235 \ -Dcom.sun.management.jmxremote.authenticate=false \ diff --git a/jdk/test/sun/management/jmxremote/startstop/JMXStartStopDoSomething.java b/jdk/test/sun/management/jmxremote/startstop/TestApp.java similarity index 90% rename from jdk/test/sun/management/jmxremote/startstop/JMXStartStopDoSomething.java rename to jdk/test/sun/management/jmxremote/startstop/TestApp.java index 5a04a6d718b..997f9f5b900 100644 --- a/jdk/test/sun/management/jmxremote/startstop/JMXStartStopDoSomething.java +++ b/jdk/test/sun/management/jmxremote/startstop/TestApp.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,9 +22,8 @@ */ import java.io.IOException; -import jdk.testlibrary.ProcessTools; -public class JMXStartStopDoSomething { +public class TestApp { public static void doSomething() throws IOException{ int r = System.in.read(); System.out.println("read: " + r); diff --git a/jdk/test/sun/tools/jinfo/JInfoRunningProcessFlagTest.java b/jdk/test/sun/tools/jinfo/JInfoRunningProcessFlagTest.java index deb3c860d63..81398d84079 100644 --- a/jdk/test/sun/tools/jinfo/JInfoRunningProcessFlagTest.java +++ b/jdk/test/sun/tools/jinfo/JInfoRunningProcessFlagTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,8 @@ * questions. */ -import sun.management.ManagementFactoryHelper; - +import java.lang.management.ManagementFactory; import com.sun.management.HotSpotDiagnosticMXBean; - import jdk.testlibrary.OutputAnalyzer; import static jdk.testlibrary.Platform.isSolaris; import static jdk.testlibrary.Asserts.assertEquals; @@ -114,13 +112,15 @@ public class JInfoRunningProcessFlagTest { } private static void verifyIsEnabled(String flag) { - HotSpotDiagnosticMXBean hotspotDiagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); + HotSpotDiagnosticMXBean hotspotDiagnostic = + ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); String flagValue = hotspotDiagnostic.getVMOption(flag).getValue(); assertEquals(flagValue, "true", "Expected '" + flag + "' flag be enabled"); } private static void verifyIsDisabled(String flag) { - HotSpotDiagnosticMXBean hotspotDiagnostic = ManagementFactoryHelper.getDiagnosticMXBean(); + HotSpotDiagnosticMXBean hotspotDiagnostic = + ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); String flagValue = hotspotDiagnostic.getVMOption(flag).getValue(); assertEquals(flagValue, "false", "Expected '" + flag + "' flag be disabled"); } diff --git a/jdk/test/sun/tools/jps/JpsHelper.java b/jdk/test/sun/tools/jps/JpsHelper.java index e28e92dae73..a5882aee6db 100644 --- a/jdk/test/sun/tools/jps/JpsHelper.java +++ b/jdk/test/sun/tools/jps/JpsHelper.java @@ -151,6 +151,7 @@ public final class JpsHelper { */ public static OutputAnalyzer jps(List vmArgs, List toolArgs) throws Exception { JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jps"); + launcher.addVMArg("-XX:+UsePerfData"); if (vmArgs != null) { for (String vmArg : vmArgs) { launcher.addVMArg(vmArg); diff --git a/jdk/test/sun/tools/jstatd/JstatdTest.java b/jdk/test/sun/tools/jstatd/JstatdTest.java index 73a625cef7c..cdf880d1f1e 100644 --- a/jdk/test/sun/tools/jstatd/JstatdTest.java +++ b/jdk/test/sun/tools/jstatd/JstatdTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,7 +22,6 @@ */ import java.io.File; -import java.io.IOException; import java.net.UnknownHostException; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; @@ -130,38 +129,18 @@ public final class JstatdTest { private OutputAnalyzer runJps() throws Exception { JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jps"); launcher.addVMArg("-XX:+UsePerfData"); - // Run jps with -v flag to obtain -Dparent.pid. - launcher.addToolArg("-v"); launcher.addToolArg(getDestination()); String[] cmd = launcher.getCommand(); log("Start jps", cmd); ProcessBuilder processBuilder = new ProcessBuilder(cmd); - OutputAnalyzer output = waitForJstatdRMI(processBuilder); + OutputAnalyzer output = ProcessTools.executeProcess(processBuilder); System.out.println(output.getOutput()); return output; } - private OutputAnalyzer waitForJstatdRMI(ProcessBuilder pb) throws Exception { - OutputAnalyzer output = ProcessTools.executeProcess(pb); - - String remoteHost = (serverName != null) ? serverName : "JStatRemoteHost"; - while (output.getExitValue() != 0) { - String out = output.getOutput(); - - if (out.contains("RMI Registry not available") || - out.contains("RMI Server " + remoteHost + " not available")) { - Thread.sleep(100); - output = ProcessTools.executeProcess(pb); - } else { - output.shouldHaveExitValue(0); - } - } - return output; - } - /** * Verifies output form jps contains pids and programs' name information. * The function will discard any lines that come before the first line with pid. @@ -211,7 +190,7 @@ public final class JstatdTest { log("Start jstat", cmd); ProcessBuilder processBuilder = new ProcessBuilder(cmd); - OutputAnalyzer output = waitForJstatdRMI(processBuilder); + OutputAnalyzer output = ProcessTools.executeProcess(processBuilder); System.out.println(output.getOutput()); return output; @@ -277,8 +256,6 @@ public final class JstatdTest { assertTrue(policy.exists() && policy.isFile(), "Security policy " + policy.getAbsolutePath() + " does not exist or not a file"); launcher.addVMArg("-Djava.security.policy=" + policy.getAbsolutePath()); - // -Dparent.pid. will help to identify jstad process started by this test - launcher.addVMArg("-Dparent.pid." + ProcessTools.getProcessId()); if (port != null) { launcher.addToolArg("-p"); launcher.addToolArg(port); @@ -287,6 +264,9 @@ public final class JstatdTest { launcher.addToolArg("-n"); launcher.addToolArg(serverName); } + if (withExternalRegistry) { + launcher.addToolArg("-nr"); + } String[] cmd = launcher.getCommand(); log("Start jstatd", cmd); @@ -295,7 +275,7 @@ public final class JstatdTest { private ProcessThread tryToSetupJstatdProcess() throws Throwable { ProcessThread jstatdThread = new ProcessThread("Jstatd-Thread", - getJstatdCmd()); + JstatdTest::isJstadReady, getJstatdCmd()); try { jstatdThread.start(); // Make sure jstatd is up and running @@ -315,18 +295,26 @@ public final class JstatdTest { return jstatdThread; } + private static boolean isJstadReady(String line) { + return line.startsWith("jstatd started (bound to "); + } + public void doTest() throws Throwable { + if (useDefaultPort) { + verifyNoRmiRegistryOnDefaultPort(); + } + ProcessThread jstatdThread = null; try { while (jstatdThread == null) { - if (!useDefaultPort || withExternalRegistry) { + if (!useDefaultPort) { port = String.valueOf(Utils.getFreePort()); } if (withExternalRegistry) { Registry registry = startRegistry(); if (registry == null) { - // The port is already in use. Cancel and try with new one. + // The port is already in use. Cancel and try with a new one. continue; } } @@ -348,4 +336,14 @@ public final class JstatdTest { "jstatd process exited with unexpected exit code"); } + private void verifyNoRmiRegistryOnDefaultPort() throws Exception { + try { + Registry registry = LocateRegistry.getRegistry(); + registry.list(); + throw new Exception("There is already RMI registry on the default port: " + registry); + } catch (RemoteException e) { + // No RMI registry on default port is detected + } + } + } diff --git a/jdk/test/sun/tools/jstatd/TestJstatdExternalRegistry.java b/jdk/test/sun/tools/jstatd/TestJstatdExternalRegistry.java index fdf2e484c46..eef692729e2 100644 --- a/jdk/test/sun/tools/jstatd/TestJstatdExternalRegistry.java +++ b/jdk/test/sun/tools/jstatd/TestJstatdExternalRegistry.java @@ -32,6 +32,7 @@ public class TestJstatdExternalRegistry { public static void main(String[] args) throws Throwable { JstatdTest test = new JstatdTest(); + test.setUseDefaultPort(false); test.setWithExternalRegistry(true); test.doTest(); }