--- a/jdk/make/copy/Copy-java.management.gmk Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-#
-# Copyright (c) 2014, 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 CopyCommon.gmk
-
-################################################################################
-
-MGMT_CONF_DIR := $(CONF_DST_DIR)/management
-MGMT_CONF_SRC := $(JDK_TOPDIR)/src/java.management/share/conf
-MGMT_SRC_FILES := $(wildcard $(MGMT_CONF_SRC)/*)
-MGMT_TARGET_FILES := $(subst $(MGMT_CONF_SRC),$(MGMT_CONF_DIR),$(MGMT_SRC_FILES))
-
-$(MGMT_CONF_DIR)/management.properties: $(MGMT_CONF_SRC)/management.properties
- $(call install-file)
- $(CHMOD) 644 $@
-
-# this file has different permissions...don't know why...
-$(MGMT_CONF_DIR)/jmxremote.access: $(MGMT_CONF_SRC)/jmxremote.access
- $(call install-file)
- $(CHMOD) 644 $@
-
-$(MGMT_CONF_DIR)/%: $(MGMT_CONF_SRC)/%
- $(call install-file)
- $(CHMOD) 444 $@
-
-TARGETS := $(MGMT_TARGET_FILES)
-
-################################################################################
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/copy/Copy-jdk.management.agent.gmk Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,50 @@
+#
+# Copyright (c) 2014, 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 CopyCommon.gmk
+
+################################################################################
+
+MGMT_CONF_DIR := $(CONF_DST_DIR)/management
+MGMT_CONF_SRC := $(JDK_TOPDIR)/src/jdk.management.agent/share/conf
+MGMT_SRC_FILES := $(wildcard $(MGMT_CONF_SRC)/*)
+MGMT_TARGET_FILES := $(subst $(MGMT_CONF_SRC),$(MGMT_CONF_DIR),$(MGMT_SRC_FILES))
+
+$(MGMT_CONF_DIR)/management.properties: $(MGMT_CONF_SRC)/management.properties
+ $(call install-file)
+ $(CHMOD) 644 $@
+
+# this file has different permissions...don't know why...
+$(MGMT_CONF_DIR)/jmxremote.access: $(MGMT_CONF_SRC)/jmxremote.access
+ $(call install-file)
+ $(CHMOD) 644 $@
+
+$(MGMT_CONF_DIR)/%: $(MGMT_CONF_SRC)/%
+ $(call install-file)
+ $(CHMOD) 444 $@
+
+TARGETS := $(MGMT_TARGET_FILES)
+
+################################################################################
--- a/jdk/make/gensrc/Gensrc-java.management.gmk Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +0,0 @@
-#
-# 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
-# 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 GensrcCommon.gmk
-
-# Hook to include the corresponding custom file, if present.
-$(eval $(call IncludeCustomExtension, jdk, gensrc/Gensrc-java.management.gmk))
-
-################################################################################
-
-include GensrcProperties.gmk
-
-$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
- SRC_DIRS := $(JDK_TOPDIR)/src/java.management/share/classes/sun/management/resources, \
- CLASS := ListResourceBundle, \
-))
-
-TARGETS += $(COMPILE_PROPERTIES)
-
-################################################################################
-
-all: $(TARGETS)
-
-.PHONY: all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/gensrc/Gensrc-jdk.management.agent.gmk Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,43 @@
+#
+# 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
+# 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 GensrcCommon.gmk
+
+################################################################################
+
+include GensrcProperties.gmk
+
+$(eval $(call SetupCompileProperties, COMPILE_PROPERTIES, \
+ SRC_DIRS := $(JDK_TOPDIR)/src/jdk.management.agent/share/classes/jdk/internal/agent/resources, \
+ CLASS := ListResourceBundle, \
+))
+
+TARGETS += $(COMPILE_PROPERTIES)
+
+################################################################################
+
+all: $(TARGETS)
+
+.PHONY: all
--- a/jdk/make/lib/Lib-java.management.gmk Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/make/lib/Lib-java.management.gmk Thu Feb 02 21:55:34 2017 +0000
@@ -30,8 +30,7 @@
################################################################################
-LIBMANAGEMENT_SRC += $(JDK_TOPDIR)/src/java.management/share/native/libmanagement \
- $(JDK_TOPDIR)/src/java.management/$(OPENJDK_TARGET_OS_TYPE)/native/libmanagement
+LIBMANAGEMENT_SRC += $(JDK_TOPDIR)/src/java.management/share/native/libmanagement
LIBMANAGEMENT_CFLAGS := -I$(JDK_TOPDIR)/src/java.management/share/native/include \
$(addprefix -I,$(LIBMANAGEMENT_SRC)) \
-I$(SUPPORT_OUTPUTDIR)/headers/java.management \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/lib/Lib-jdk.management.agent.gmk Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,59 @@
+#
+# Copyright (c) 2017, 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
+
+################################################################################
+
+LIBMANAGEMENT_RMI_SRC += $(JDK_TOPDIR)/src/jdk.management.agent/$(OPENJDK_TARGET_OS_TYPE)/native/libmanagement_rmi
+LIBMANAGEMENT_RMI_CFLAGS := $(addprefix -I,$(LIBMANAGEMENT_RMI_SRC)) \
+ -I$(SUPPORT_OUTPUTDIR)/headers/jdk.management.agent \
+ $(LIBJAVA_HEADER_FLAGS) \
+ #
+
+$(eval $(call SetupNativeCompilation,BUILD_LIBMANAGEMENT_RMI, \
+ LIBRARY := management_rmi, \
+ OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+ SRC := $(LIBMANAGEMENT_RMI_SRC), \
+ OPTIMIZATION := LOW, \
+ CFLAGS := $(CFLAGS_JDKLIB) $(LIBMANAGEMENT_RMI_CFLAGS), \
+ MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libmanagement_rmi/mapfile-vers, \
+ LDFLAGS := $(LDFLAGS_JDKLIB) \
+ $(call SET_SHARED_LIBRARY_ORIGIN), \
+ LIBS := $(JDKLIB_LIBS), \
+ LIBS_windows := $(WIN_JAVA_LIB) advapi32.lib, \
+ VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
+ RC_FLAGS := $(RC_FLAGS) \
+ -D "JDK_FNAME=management_rmi.dll" \
+ -D "JDK_INTERNAL_NAME=management_rmi" \
+ -D "JDK_FTYPE=0x2L", \
+ OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libmanagement_rmi, \
+))
+
+$(BUILD_LIBMANAGEMENT_RMI): $(call FindLib, java.base, java)
+
+TARGETS += $(BUILD_LIBMANAGEMENT_RMI)
+
+################################################################################
--- a/jdk/make/lib/NetworkingLibraries.gmk Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/make/lib/NetworkingLibraries.gmk Thu Feb 02 21:55:34 2017 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2017, 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
@@ -44,8 +44,9 @@
LIBS_linux := $(LIBDL) -lpthread, \
LIBS_solaris := -lnsl -lsocket $(LIBDL) -lc, \
LIBS_aix := $(LIBDL),\
- LIBS_windows := ws2_32.lib jvm.lib secur32.lib iphlpapi.lib \
+ LIBS_windows := ws2_32.lib jvm.lib secur32.lib iphlpapi.lib winhttp.lib \
delayimp.lib $(WIN_JAVA_LIB) advapi32.lib, \
+ LIBS_macosx := -framework CoreFoundation -framework CoreServices, \
VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
RC_FLAGS := $(RC_FLAGS) \
-D "JDK_FNAME=net.dll" \
--- a/jdk/make/mapfiles/libmanagement/mapfile-vers Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/make/mapfiles/libmanagement/mapfile-vers Thu Feb 02 21:55:34 2017 +0000
@@ -28,7 +28,6 @@
SUNWprivate_1.1 {
global:
Java_sun_management_ClassLoadingImpl_setVerboseClass;
- Java_sun_management_FileSystemImpl_isAccessUserOnly0;
Java_sun_management_GarbageCollectorImpl_getCollectionCount;
Java_sun_management_GarbageCollectorImpl_getCollectionTime;
Java_sun_management_HotspotThread_getInternalThreadCount;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/mapfiles/libmanagement_rmi/mapfile-vers Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,34 @@
+#
+# Copyright (c) 2017, 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_jdk_internal_agent_FileSystemImpl_isAccessUserOnly0;
+ JNI_OnLoad;
+ local:
+ *;
+};
--- a/jdk/make/mapfiles/libnet/mapfile-vers Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/make/mapfiles/libnet/mapfile-vers Thu Feb 02 21:55:34 2017 +0000
@@ -1,5 +1,5 @@
#
-# Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1997, 2017, 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
@@ -97,7 +97,7 @@
Java_sun_net_sdp_SdpSupport_convert0;
Java_sun_net_sdp_SdpSupport_create0;
Java_sun_net_spi_DefaultProxySelector_init;
- Java_sun_net_spi_DefaultProxySelector_getSystemProxy;
+ Java_sun_net_spi_DefaultProxySelector_getSystemProxies;
NET_SockaddrToInetAddress;
NET_SockaddrEqualsInetAddress;
NET_InetAddressToSockaddr;
--- a/jdk/make/rmic/Rmic-java.management.gmk Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-#
-# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-default: all
-
-include RmicCommon.gmk
-
-##########################################################################################
-#
-# Generate RMI stubs
-#
-
-JMX_RMI_CLASSES := javax.management.remote.rmi.RMIConnectionImpl \
- javax.management.remote.rmi.RMIServerImpl
-
-# Generate into gensrc dir where sources get picked up for javadoc, then move the classes
-# into the stub classes dir.
-$(eval $(call SetupRMICompilation,RMI_GEN, \
- CLASSES := $(JMX_RMI_CLASSES), \
- CLASSES_DIR := $(CLASSES_DIR)/java.management, \
- STUB_CLASSES_DIR := $(RMIC_GENSRC_DIR)/java.management, \
- RUN_V12 := true, \
- KEEP_GENERATED := true, \
-))
-
-# Find all classes generated and move them from the gensrc dir to the stub classes dir
-$(RMIC_GENSRC_DIR)/_classes.moved: $(RMI_GEN)
- $(eval classfiles := $(shell $(FIND) $(RMIC_GENSRC_DIR) -name "*.class"))
- $(foreach src, $(classfiles), \
- $(eval target := $(patsubst $(RMIC_GENSRC_DIR)/%, \
- $(STUB_CLASSES_DIR)/%, $(src))) \
- $(MKDIR) -p $(dir $(target)) ; \
- $(MV) $(src) $(target) $(NEWLINE))
- $(TOUCH) $@
-
-##########################################################################################
-
-all: $(RMIC_GENSRC_DIR)/_classes.moved $(RMI_GEN)
-
-.PHONY: all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/rmic/Rmic-java.management.rmi.gmk Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+default: all
+
+include RmicCommon.gmk
+
+##########################################################################################
+#
+# Generate RMI stubs
+#
+
+JMX_RMI_CLASSES := javax.management.remote.rmi.RMIConnectionImpl \
+ javax.management.remote.rmi.RMIServerImpl
+
+# Generate into gensrc dir where sources get picked up for javadoc, then move the classes
+# into the stub classes dir.
+$(eval $(call SetupRMICompilation,RMI_GEN, \
+ CLASSES := $(JMX_RMI_CLASSES), \
+ CLASSES_DIR := $(CLASSES_DIR)/java.management.rmi, \
+ STUB_CLASSES_DIR := $(RMIC_GENSRC_DIR)/java.management.rmi, \
+ RUN_V12 := true, \
+ KEEP_GENERATED := true, \
+))
+
+# Find all classes generated and move them from the gensrc dir to the stub classes dir
+$(RMIC_GENSRC_DIR)/_classes.moved: $(RMI_GEN)
+ $(eval classfiles := $(shell $(FIND) $(RMIC_GENSRC_DIR) -name "*.class"))
+ $(foreach src, $(classfiles), \
+ $(eval target := $(patsubst $(RMIC_GENSRC_DIR)/%, \
+ $(STUB_CLASSES_DIR)/%, $(src))) \
+ $(MKDIR) -p $(dir $(target)) ; \
+ $(MV) $(src) $(target) $(NEWLINE))
+ $(TOUCH) $@
+
+##########################################################################################
+
+all: $(RMIC_GENSRC_DIR)/_classes.moved $(RMI_GEN)
+
+.PHONY: all
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/macosx/native/libnet/DefaultProxySelector.c Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2017 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017 SAP SE. 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 <string.h>
+#include <CoreFoundation/CoreFoundation.h>
+#include <CoreServices/CoreServices.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jvm_md.h"
+
+#include "proxy_util.h"
+
+#include "sun_net_spi_DefaultProxySelector.h"
+
+
+/**
+ * For more information on how to use the APIs in "CFProxySupport.h" see:
+ * https://developer.apple.com/legacy/library/samplecode/CFProxySupportTool/Introduction/Intro.html
+ */
+
+#define kResolveProxyRunLoopMode CFSTR("sun.net.spi.DefaultProxySelector")
+
+#define BUFFER_SIZE 1024
+
+/* Callback for CFNetworkExecuteProxyAutoConfigurationURL. */
+static void proxyUrlCallback(void * client, CFArrayRef proxies, CFErrorRef error) {
+ /* client is a pointer to a CFTypeRef and holds either proxies or an error. */
+ CFTypeRef* resultPtr = (CFTypeRef *)client;
+
+ if (error != NULL) {
+ *resultPtr = CFRetain(error);
+ } else {
+ *resultPtr = CFRetain(proxies);
+ }
+ CFRunLoopStop(CFRunLoopGetCurrent());
+}
+
+/*
+ * Returns a new array of proxies containing all the given non-PAC proxies as
+ * well as the results of executing all the given PAC-based proxies, for the
+ * specified URL. 'proxies' is a list that may contain both PAC and non-PAC
+ * proxies.
+ */
+static CFArrayRef createExpandedProxiesArray(CFArrayRef proxies, CFURLRef url) {
+
+ CFIndex count;
+ CFIndex index;
+ CFMutableArrayRef expandedProxiesArray;
+
+ expandedProxiesArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+ if (expandedProxiesArray == NULL)
+ return NULL;
+
+ /* Iterate over the array of proxies */
+ count = CFArrayGetCount(proxies);
+ for (index = 0; index < count ; index++) {
+ CFDictionaryRef currentProxy;
+ CFStringRef proxyType;
+
+ currentProxy = (CFDictionaryRef) CFArrayGetValueAtIndex(proxies, index);
+ if(currentProxy == NULL) {
+ CFRelease(expandedProxiesArray);
+ return NULL;
+ }
+ proxyType = (CFStringRef) CFDictionaryGetValue(currentProxy, kCFProxyTypeKey);
+ if (proxyType == NULL) {
+ CFRelease(expandedProxiesArray);
+ return NULL;
+ }
+
+ if (!CFEqual(proxyType, kCFProxyTypeAutoConfigurationURL)) {
+ /* Non-PAC entry, just copy it to the new array */
+ CFArrayAppendValue(expandedProxiesArray, currentProxy);
+ } else {
+ /* PAC-based URL, execute its script append its results */
+ CFRunLoopSourceRef runLoop;
+ CFURLRef scriptURL;
+ CFTypeRef result = NULL;
+ CFStreamClientContext context = { 0, &result, NULL, NULL, NULL };
+ CFTimeInterval timeout = 5;
+
+ scriptURL = CFDictionaryGetValue(currentProxy, kCFProxyAutoConfigurationURLKey);
+
+ runLoop = CFNetworkExecuteProxyAutoConfigurationURL(scriptURL, url, proxyUrlCallback,
+ &context);
+ if (runLoop != NULL) {
+ /*
+ * Despite the fact that CFNetworkExecuteProxyAutoConfigurationURL has
+ * neither a "Create" nor a "Copy" in the name, we are required to
+ * release the return CFRunLoopSourceRef <rdar://problem/5533931>.
+ */
+ CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoop, kResolveProxyRunLoopMode);
+ CFRunLoopRunInMode(kResolveProxyRunLoopMode, timeout, false);
+ CFRunLoopRemoveSource(CFRunLoopGetCurrent(), runLoop, kResolveProxyRunLoopMode);
+
+ /*
+ * Once the runloop returns, there will be either an error result or
+ * a proxies array result. Do the appropriate thing with that result.
+ */
+ if (result != NULL) {
+ if (CFGetTypeID(result) == CFArrayGetTypeID()) {
+ /*
+ * Append the new array from the PAC list - it contains
+ * only non-PAC entries.
+ */
+ CFArrayAppendArray(expandedProxiesArray, result,
+ CFRangeMake(0, CFArrayGetCount(result)));
+ }
+ CFRelease(result);
+ }
+ CFRelease(runLoop);
+ }
+ }
+ }
+ return expandedProxiesArray;
+}
+
+
+/*
+ * Class: sun_net_spi_DefaultProxySelector
+ * Method: init
+ * Signature: ()Z
+ */
+JNIEXPORT jboolean JNICALL
+Java_sun_net_spi_DefaultProxySelector_init(JNIEnv *env, jclass clazz) {
+ if (!initJavaClass(env)) {
+ return JNI_FALSE;
+ }
+ return JNI_TRUE;
+}
+
+
+/*
+ * Class: sun_net_spi_DefaultProxySelector
+ * Method: getSystemProxies
+ * Signature: ([Ljava/lang/String;Ljava/lang/String;)[Ljava/net/Proxy;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env,
+ jobject this,
+ jstring proto,
+ jstring host)
+{
+ CFDictionaryRef proxyDicRef = NULL;
+ CFURLRef urlRef = NULL;
+ bool proxyFound = false;
+ jobjectArray proxyArray = NULL;
+ const char *cproto;
+ const char *chost;
+
+ /* Get system proxy settings */
+ proxyDicRef = CFNetworkCopySystemProxySettings();
+ if (proxyDicRef == NULL) {
+ return NULL;
+ }
+
+ /* Create CFURLRef from proto and host */
+ cproto = (*env)->GetStringUTFChars(env, proto, NULL);
+ if (cproto != NULL) {
+ chost = (*env)->GetStringUTFChars(env, host, NULL);
+ if (chost != NULL) {
+ char* uri = NULL;
+ size_t protoLen = 0;
+ size_t hostLen = 0;
+
+ protoLen = strlen(cproto);
+ hostLen = strlen(chost);
+
+ /* Construct the uri, cproto + "://" + chost */
+ uri = malloc(protoLen + hostLen + 4);
+ if (uri != NULL) {
+ memcpy(uri, cproto, protoLen);
+ memcpy(uri + protoLen, "://", 3);
+ memcpy(uri + protoLen + 3, chost, hostLen + 1);
+
+ urlRef = CFURLCreateWithBytes(NULL, (const UInt8 *) uri, strlen(uri),
+ kCFStringEncodingUTF8, NULL);
+ free(uri);
+ }
+ (*env)->ReleaseStringUTFChars(env, host, chost);
+ }
+ (*env)->ReleaseStringUTFChars(env, proto, cproto);
+ }
+ if (urlRef != NULL) {
+ CFArrayRef urlProxyArrayRef = CFNetworkCopyProxiesForURL(urlRef, proxyDicRef);
+ if (urlProxyArrayRef != NULL) {
+ CFIndex count;
+ CFIndex index;
+
+ CFArrayRef expandedProxyArray = createExpandedProxiesArray(urlProxyArrayRef, urlRef);
+ CFRelease(urlProxyArrayRef);
+
+ if (expandedProxyArray == NULL) {
+ CFRelease(urlRef);
+ CFRelease(proxyDicRef);
+ return NULL;
+ }
+
+ count = CFArrayGetCount(expandedProxyArray);
+
+ proxyArray = (*env)->NewObjectArray(env, count, proxy_class, NULL);
+ if (proxyArray != NULL || (*env)->ExceptionCheck(env)) {
+ /* Iterate over the expanded array of proxies */
+ for (index = 0; index < count ; index++) {
+ CFDictionaryRef currentProxy;
+ CFStringRef proxyType;
+ jobject proxy = NULL;
+
+ currentProxy = (CFDictionaryRef) CFArrayGetValueAtIndex(expandedProxyArray,
+ index);
+ proxyType = (CFStringRef) CFDictionaryGetValue(currentProxy, kCFProxyTypeKey);
+ if (CFEqual(proxyType, kCFProxyTypeNone)) {
+ /* This entry states no proxy, therefore just add a NO_PROXY object. */
+ proxy = (*env)->GetStaticObjectField(env, proxy_class, pr_no_proxyID);
+ } else {
+ /*
+ * Create a proxy object for this entry.
+ * Differentiate between SOCKS and HTTP type.
+ */
+ jfieldID typeID = ptype_httpID;
+ if (CFEqual(proxyType, kCFProxyTypeSOCKS)) {
+ typeID = ptype_socksID;
+ }
+ CFNumberRef portNumberRef = (CFNumberRef)CFDictionaryGetValue(currentProxy,
+ (const void*)kCFProxyPortNumberKey);
+ if (portNumberRef != NULL) {
+ int port = 0;
+ if (CFNumberGetValue(portNumberRef, kCFNumberSInt32Type, &port)) {
+ CFStringRef hostNameRef = (CFStringRef)CFDictionaryGetValue(
+ currentProxy, (const void*)kCFProxyHostNameKey);
+ if (hostNameRef != NULL) {
+ char hostNameBuffer[BUFFER_SIZE];
+ if (CFStringGetCString(hostNameRef, hostNameBuffer,
+ BUFFER_SIZE, kCFStringEncodingUTF8)) {
+ proxy = createProxy(env, typeID, &hostNameBuffer[0], port);
+ }
+ }
+ }
+ }
+ }
+ if (proxy == NULL || (*env)->ExceptionCheck(env)) {
+ proxyArray = NULL;
+ break;
+ }
+ (*env)->SetObjectArrayElement(env, proxyArray, index, proxy);
+ if ((*env)->ExceptionCheck(env)) {
+ proxyArray = NULL;
+ break;
+ }
+ }
+ }
+ CFRelease(expandedProxyArray);
+ }
+ CFRelease(urlRef);
+ }
+ CFRelease(proxyDicRef);
+
+ return proxyArray;
+}
--- a/jdk/src/java.base/share/classes/java/net/doc-files/net-properties.html Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/net/doc-files/net-properties.html Thu Feb 02 21:55:34 2017 +0000
@@ -149,7 +149,7 @@
the <B>user.name</B> property will be used with no password.</P>
</UL>
<LI><P><B>java.net.useSystemProxies</B> (default: false)<BR>
- On recent Windows systems and on Gnome 2.x systems it is possible to
+ On Windows systems, macOS systems and on Gnome systems it is possible to
tell the java.net stack, setting this property to <B>true</B>, to use
the system proxy settings (both these systems let you set proxies
globally through their user interface). Note that this property is
--- a/jdk/src/java.base/share/classes/java/util/regex/CharPredicates.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/regex/CharPredicates.java Thu Feb 02 21:55:34 2017 +0000
@@ -32,164 +32,195 @@
class CharPredicates {
- static final CharPredicate ALPHABETIC = Character::isAlphabetic;
+ static final CharPredicate ALPHABETIC() {
+ return Character::isAlphabetic;
+ }
// \p{gc=Decimal_Number}
- static final CharPredicate DIGIT = Character::isDigit;
+ static final CharPredicate DIGIT() {
+ return Character::isDigit;
+ }
- static final CharPredicate LETTER = Character::isLetter;
+ static final CharPredicate LETTER() {
+ return Character::isLetter;
+ }
- static final CharPredicate IDEOGRAPHIC = Character::isIdeographic;
+ static final CharPredicate IDEOGRAPHIC() {
+ return Character::isIdeographic;
+ }
- static final CharPredicate LOWERCASE = Character::isLowerCase;
+ static final CharPredicate LOWERCASE() {
+ return Character::isLowerCase;
+ }
- static final CharPredicate UPPERCASE = Character::isUpperCase;
+ static final CharPredicate UPPERCASE() {
+ return Character::isUpperCase;
+ }
- static final CharPredicate TITLECASE = Character::isTitleCase;
+ static final CharPredicate TITLECASE() {
+ return Character::isTitleCase;
+ }
// \p{Whitespace}
- static final CharPredicate WHITE_SPACE = ch ->
- ((((1 << Character.SPACE_SEPARATOR) |
- (1 << Character.LINE_SEPARATOR) |
- (1 << Character.PARAGRAPH_SEPARATOR)) >> Character.getType(ch)) & 1)
- != 0 || (ch >= 0x9 && ch <= 0xd) || (ch == 0x85);
+ static final CharPredicate WHITE_SPACE() {
+ return ch ->
+ ((((1 << Character.SPACE_SEPARATOR) |
+ (1 << Character.LINE_SEPARATOR) |
+ (1 << Character.PARAGRAPH_SEPARATOR)) >> Character.getType(ch)) & 1)
+ != 0 || (ch >= 0x9 && ch <= 0xd) || (ch == 0x85);
+ }
// \p{gc=Control}
- static final CharPredicate CONTROL = ch ->
- Character.getType(ch) == Character.CONTROL;
+ static final CharPredicate CONTROL() {
+ return ch -> Character.getType(ch) == Character.CONTROL;
+ }
// \p{gc=Punctuation}
- static final CharPredicate PUNCTUATION = ch ->
- ((((1 << Character.CONNECTOR_PUNCTUATION) |
- (1 << Character.DASH_PUNCTUATION) |
- (1 << Character.START_PUNCTUATION) |
- (1 << Character.END_PUNCTUATION) |
- (1 << Character.OTHER_PUNCTUATION) |
- (1 << Character.INITIAL_QUOTE_PUNCTUATION) |
- (1 << Character.FINAL_QUOTE_PUNCTUATION)) >> Character.getType(ch)) & 1)
- != 0;
+ static final CharPredicate PUNCTUATION() {
+ return ch ->
+ ((((1 << Character.CONNECTOR_PUNCTUATION) |
+ (1 << Character.DASH_PUNCTUATION) |
+ (1 << Character.START_PUNCTUATION) |
+ (1 << Character.END_PUNCTUATION) |
+ (1 << Character.OTHER_PUNCTUATION) |
+ (1 << Character.INITIAL_QUOTE_PUNCTUATION) |
+ (1 << Character.FINAL_QUOTE_PUNCTUATION)) >> Character.getType(ch)) & 1)
+ != 0;
+ }
// \p{gc=Decimal_Number}
// \p{Hex_Digit} -> PropList.txt: Hex_Digit
- static final CharPredicate HEX_DIGIT = DIGIT.union(
- ch -> (ch >= 0x0030 && ch <= 0x0039) ||
- (ch >= 0x0041 && ch <= 0x0046) ||
- (ch >= 0x0061 && ch <= 0x0066) ||
- (ch >= 0xFF10 && ch <= 0xFF19) ||
- (ch >= 0xFF21 && ch <= 0xFF26) ||
- (ch >= 0xFF41 && ch <= 0xFF46));
+ static final CharPredicate HEX_DIGIT() {
+ return DIGIT().union(ch -> (ch >= 0x0030 && ch <= 0x0039) ||
+ (ch >= 0x0041 && ch <= 0x0046) ||
+ (ch >= 0x0061 && ch <= 0x0066) ||
+ (ch >= 0xFF10 && ch <= 0xFF19) ||
+ (ch >= 0xFF21 && ch <= 0xFF26) ||
+ (ch >= 0xFF41 && ch <= 0xFF46));
+ }
- static final CharPredicate ASSIGNED = ch ->
- Character.getType(ch) != Character.UNASSIGNED;
+ static final CharPredicate ASSIGNED() {
+ return ch -> Character.getType(ch) != Character.UNASSIGNED;
+ }
// PropList.txt:Noncharacter_Code_Point
- static final CharPredicate NONCHARACTER_CODE_POINT = ch ->
- (ch & 0xfffe) == 0xfffe || (ch >= 0xfdd0 && ch <= 0xfdef);
+ static final CharPredicate NONCHARACTER_CODE_POINT() {
+ return ch -> (ch & 0xfffe) == 0xfffe || (ch >= 0xfdd0 && ch <= 0xfdef);
+ }
// \p{alpha}
// \p{digit}
- static final CharPredicate ALNUM = ALPHABETIC.union(DIGIT);
+ static final CharPredicate ALNUM() {
+ return ALPHABETIC().union(DIGIT());
+ }
// \p{Whitespace} --
// [\N{LF} \N{VT} \N{FF} \N{CR} \N{NEL} -> 0xa, 0xb, 0xc, 0xd, 0x85
// \p{gc=Line_Separator}
// \p{gc=Paragraph_Separator}]
- static final CharPredicate BLANK = ch ->
- Character.getType(ch) == Character.SPACE_SEPARATOR ||
- ch == 0x9; // \N{HT}
+ static final CharPredicate BLANK() {
+ return ch ->
+ Character.getType(ch) == Character.SPACE_SEPARATOR ||
+ ch == 0x9; // \N{HT}
+ }
// [^
// \p{space}
// \p{gc=Control}
// \p{gc=Surrogate}
// \p{gc=Unassigned}]
- static final CharPredicate GRAPH = ch ->
- ((((1 << Character.SPACE_SEPARATOR) |
- (1 << Character.LINE_SEPARATOR) |
- (1 << Character.PARAGRAPH_SEPARATOR) |
- (1 << Character.CONTROL) |
- (1 << Character.SURROGATE) |
- (1 << Character.UNASSIGNED)) >> Character.getType(ch)) & 1)
- == 0;
+ static final CharPredicate GRAPH() {
+ return ch ->
+ ((((1 << Character.SPACE_SEPARATOR) |
+ (1 << Character.LINE_SEPARATOR) |
+ (1 << Character.PARAGRAPH_SEPARATOR) |
+ (1 << Character.CONTROL) |
+ (1 << Character.SURROGATE) |
+ (1 << Character.UNASSIGNED)) >> Character.getType(ch)) & 1)
+ == 0;
+ }
// \p{graph}
// \p{blank}
// -- \p{cntrl}
- static final CharPredicate PRINT = GRAPH.union(BLANK).and(CONTROL.negate());
+ static final CharPredicate PRINT() {
+ return GRAPH().union(BLANK()).and(CONTROL().negate());
+ }
// 200C..200D PropList.txt:Join_Control
- static final CharPredicate JOIN_CONTROL = ch -> ch == 0x200C || ch == 0x200D;
+ static final CharPredicate JOIN_CONTROL() {
+ return ch -> ch == 0x200C || ch == 0x200D;
+ }
// \p{alpha}
// \p{gc=Mark}
// \p{digit}
// \p{gc=Connector_Punctuation}
// \p{Join_Control} 200C..200D
- static final CharPredicate WORD =
- ALPHABETIC.union(ch -> ((((1 << Character.NON_SPACING_MARK) |
+ static final CharPredicate WORD() {
+ return ALPHABETIC().union(ch -> ((((1 << Character.NON_SPACING_MARK) |
(1 << Character.ENCLOSING_MARK) |
(1 << Character.COMBINING_SPACING_MARK) |
(1 << Character.DECIMAL_DIGIT_NUMBER) |
(1 << Character.CONNECTOR_PUNCTUATION))
>> Character.getType(ch)) & 1) != 0,
- JOIN_CONTROL);
+ JOIN_CONTROL());
+ }
/////////////////////////////////////////////////////////////////////////////
- private static final HashMap<String, CharPredicate> posix = new HashMap<>(12);
- private static final HashMap<String, CharPredicate> uprops = new HashMap<>(18);
-
- private static void defPosix(String name, CharPredicate p) {
- posix.put(name, p);
- }
- private static void defUProp(String name, CharPredicate p) {
- uprops.put(name, p);
+ private static CharPredicate getPosixPredicate(String name) {
+ switch (name) {
+ case "ALPHA": return ALPHABETIC();
+ case "LOWER": return LOWERCASE();
+ case "UPPER": return UPPERCASE();
+ case "SPACE": return WHITE_SPACE();
+ case "PUNCT": return PUNCTUATION();
+ case "XDIGIT": return HEX_DIGIT();
+ case "ALNUM": return ALNUM();
+ case "CNTRL": return CONTROL();
+ case "DIGIT": return DIGIT();
+ case "BLANK": return BLANK();
+ case "GRAPH": return GRAPH();
+ case "PRINT": return PRINT();
+ default: return null;
+ }
}
- static {
- defPosix("ALPHA", ALPHABETIC);
- defPosix("LOWER", LOWERCASE);
- defPosix("UPPER", UPPERCASE);
- defPosix("SPACE", WHITE_SPACE);
- defPosix("PUNCT", PUNCTUATION);
- defPosix("XDIGIT",HEX_DIGIT);
- defPosix("ALNUM", ALNUM);
- defPosix("CNTRL", CONTROL);
- defPosix("DIGIT", DIGIT);
- defPosix("BLANK", BLANK);
- defPosix("GRAPH", GRAPH);
- defPosix("PRINT", PRINT);
-
- defUProp("ALPHABETIC", ALPHABETIC);
- defUProp("ASSIGNED", ASSIGNED);
- defUProp("CONTROL", CONTROL);
- defUProp("HEXDIGIT", HEX_DIGIT);
- defUProp("IDEOGRAPHIC", IDEOGRAPHIC);
- defUProp("JOINCONTROL", JOIN_CONTROL);
- defUProp("LETTER", LETTER);
- defUProp("LOWERCASE", LOWERCASE);
- defUProp("NONCHARACTERCODEPOINT", NONCHARACTER_CODE_POINT);
- defUProp("TITLECASE", TITLECASE);
- defUProp("PUNCTUATION", PUNCTUATION);
- defUProp("UPPERCASE", UPPERCASE);
- defUProp("WHITESPACE", WHITE_SPACE);
- defUProp("WORD", WORD);
- defUProp("WHITE_SPACE", WHITE_SPACE);
- defUProp("HEX_DIGIT", HEX_DIGIT);
- defUProp("NONCHARACTER_CODE_POINT", NONCHARACTER_CODE_POINT);
- defUProp("JOIN_CONTROL", JOIN_CONTROL);
+ private static CharPredicate getUnicodePredicate(String name) {
+ switch (name) {
+ case "ALPHABETIC": return ALPHABETIC();
+ case "ASSIGNED": return ASSIGNED();
+ case "CONTROL": return CONTROL();
+ case "HEXDIGIT": return HEX_DIGIT();
+ case "IDEOGRAPHIC": return IDEOGRAPHIC();
+ case "JOINCONTROL": return JOIN_CONTROL();
+ case "LETTER": return LETTER();
+ case "LOWERCASE": return LOWERCASE();
+ case "NONCHARACTERCODEPOINT": return NONCHARACTER_CODE_POINT();
+ case "TITLECASE": return TITLECASE();
+ case "PUNCTUATION": return PUNCTUATION();
+ case "UPPERCASE": return UPPERCASE();
+ case "WHITESPACE": return WHITE_SPACE();
+ case "WORD": return WORD();
+ case "WHITE_SPACE": return WHITE_SPACE();
+ case "HEX_DIGIT": return HEX_DIGIT();
+ case "NONCHARACTER_CODE_POINT": return NONCHARACTER_CODE_POINT();
+ case "JOIN_CONTROL": return JOIN_CONTROL();
+ default: return null;
+ }
}
public static CharPredicate forUnicodeProperty(String propName) {
propName = propName.toUpperCase(Locale.ROOT);
- CharPredicate p = uprops.get(propName);
+ CharPredicate p = getUnicodePredicate(propName);
if (p != null)
return p;
- return posix.get(propName);
+ return getPosixPredicate(propName);
}
public static CharPredicate forPOSIXName(String propName) {
- return posix.get(propName.toUpperCase(Locale.ENGLISH));
+ return getPosixPredicate(propName.toUpperCase(Locale.ENGLISH));
}
/////////////////////////////////////////////////////////////////////////////
@@ -223,145 +254,130 @@
// unicode categories, aliases, properties, java methods ...
- private static final HashMap<String, CharPredicate> props = new HashMap<>(128);
-
- /**
- * Returns a predicate matching all characters in a named property.
- */
static CharPredicate forProperty(String name) {
- return props.get(name);
- }
-
- private static void defProp(String name, CharPredicate p) {
- props.put(name, p);
- }
-
- private static void defCategory(String name, final int typeMask) {
- CharPredicate p = ch -> (typeMask & (1 << Character.getType(ch))) != 0;
- props.put(name, p);
- }
-
- private static void defRange(String name, final int lower, final int upper) {
- BmpCharPredicate p = ch -> lower <= ch && ch <= upper;
- props.put(name, p);
- }
-
- private static void defCtype(String name, final int ctype) {
- BmpCharPredicate p = ch -> ch < 128 && ASCII.isType(ch, ctype);
- // PrintPattern.pmap.put(p, name);
- props.put(name, p);
- }
-
- static {
// Unicode character property aliases, defined in
// http://www.unicode.org/Public/UNIDATA/PropertyValueAliases.txt
- defCategory("Cn", 1<<Character.UNASSIGNED);
- defCategory("Lu", 1<<Character.UPPERCASE_LETTER);
- defCategory("Ll", 1<<Character.LOWERCASE_LETTER);
- defCategory("Lt", 1<<Character.TITLECASE_LETTER);
- defCategory("Lm", 1<<Character.MODIFIER_LETTER);
- defCategory("Lo", 1<<Character.OTHER_LETTER);
- defCategory("Mn", 1<<Character.NON_SPACING_MARK);
- defCategory("Me", 1<<Character.ENCLOSING_MARK);
- defCategory("Mc", 1<<Character.COMBINING_SPACING_MARK);
- defCategory("Nd", 1<<Character.DECIMAL_DIGIT_NUMBER);
- defCategory("Nl", 1<<Character.LETTER_NUMBER);
- defCategory("No", 1<<Character.OTHER_NUMBER);
- defCategory("Zs", 1<<Character.SPACE_SEPARATOR);
- defCategory("Zl", 1<<Character.LINE_SEPARATOR);
- defCategory("Zp", 1<<Character.PARAGRAPH_SEPARATOR);
- defCategory("Cc", 1<<Character.CONTROL);
- defCategory("Cf", 1<<Character.FORMAT);
- defCategory("Co", 1<<Character.PRIVATE_USE);
- defCategory("Cs", 1<<Character.SURROGATE);
- defCategory("Pd", 1<<Character.DASH_PUNCTUATION);
- defCategory("Ps", 1<<Character.START_PUNCTUATION);
- defCategory("Pe", 1<<Character.END_PUNCTUATION);
- defCategory("Pc", 1<<Character.CONNECTOR_PUNCTUATION);
- defCategory("Po", 1<<Character.OTHER_PUNCTUATION);
- defCategory("Sm", 1<<Character.MATH_SYMBOL);
- defCategory("Sc", 1<<Character.CURRENCY_SYMBOL);
- defCategory("Sk", 1<<Character.MODIFIER_SYMBOL);
- defCategory("So", 1<<Character.OTHER_SYMBOL);
- defCategory("Pi", 1<<Character.INITIAL_QUOTE_PUNCTUATION);
- defCategory("Pf", 1<<Character.FINAL_QUOTE_PUNCTUATION);
- defCategory("L", ((1<<Character.UPPERCASE_LETTER) |
- (1<<Character.LOWERCASE_LETTER) |
- (1<<Character.TITLECASE_LETTER) |
- (1<<Character.MODIFIER_LETTER) |
- (1<<Character.OTHER_LETTER)));
- defCategory("M", ((1<<Character.NON_SPACING_MARK) |
- (1<<Character.ENCLOSING_MARK) |
- (1<<Character.COMBINING_SPACING_MARK)));
- defCategory("N", ((1<<Character.DECIMAL_DIGIT_NUMBER) |
- (1<<Character.LETTER_NUMBER) |
- (1<<Character.OTHER_NUMBER)));
- defCategory("Z", ((1<<Character.SPACE_SEPARATOR) |
- (1<<Character.LINE_SEPARATOR) |
- (1<<Character.PARAGRAPH_SEPARATOR)));
- defCategory("C", ((1<<Character.CONTROL) |
- (1<<Character.FORMAT) |
- (1<<Character.PRIVATE_USE) |
- (1<<Character.SURROGATE) |
- (1<<Character.UNASSIGNED))); // Other
- defCategory("P", ((1<<Character.DASH_PUNCTUATION) |
- (1<<Character.START_PUNCTUATION) |
- (1<<Character.END_PUNCTUATION) |
- (1<<Character.CONNECTOR_PUNCTUATION) |
- (1<<Character.OTHER_PUNCTUATION) |
- (1<<Character.INITIAL_QUOTE_PUNCTUATION) |
- (1<<Character.FINAL_QUOTE_PUNCTUATION)));
- defCategory("S", ((1<<Character.MATH_SYMBOL) |
- (1<<Character.CURRENCY_SYMBOL) |
- (1<<Character.MODIFIER_SYMBOL) |
- (1<<Character.OTHER_SYMBOL)));
- defCategory("LC", ((1<<Character.UPPERCASE_LETTER) |
- (1<<Character.LOWERCASE_LETTER) |
- (1<<Character.TITLECASE_LETTER)));
- defCategory("LD", ((1<<Character.UPPERCASE_LETTER) |
- (1<<Character.LOWERCASE_LETTER) |
- (1<<Character.TITLECASE_LETTER) |
- (1<<Character.MODIFIER_LETTER) |
- (1<<Character.OTHER_LETTER) |
- (1<<Character.DECIMAL_DIGIT_NUMBER)));
- defRange("L1", 0x00, 0xFF); // Latin-1
- props.put("all", ch -> true);
+ switch (name) {
+ case "Cn": return category(1<<Character.UNASSIGNED);
+ case "Lu": return category(1<<Character.UPPERCASE_LETTER);
+ case "Ll": return category(1<<Character.LOWERCASE_LETTER);
+ case "Lt": return category(1<<Character.TITLECASE_LETTER);
+ case "Lm": return category(1<<Character.MODIFIER_LETTER);
+ case "Lo": return category(1<<Character.OTHER_LETTER);
+ case "Mn": return category(1<<Character.NON_SPACING_MARK);
+ case "Me": return category(1<<Character.ENCLOSING_MARK);
+ case "Mc": return category(1<<Character.COMBINING_SPACING_MARK);
+ case "Nd": return category(1<<Character.DECIMAL_DIGIT_NUMBER);
+ case "Nl": return category(1<<Character.LETTER_NUMBER);
+ case "No": return category(1<<Character.OTHER_NUMBER);
+ case "Zs": return category(1<<Character.SPACE_SEPARATOR);
+ case "Zl": return category(1<<Character.LINE_SEPARATOR);
+ case "Zp": return category(1<<Character.PARAGRAPH_SEPARATOR);
+ case "Cc": return category(1<<Character.CONTROL);
+ case "Cf": return category(1<<Character.FORMAT);
+ case "Co": return category(1<<Character.PRIVATE_USE);
+ case "Cs": return category(1<<Character.SURROGATE);
+ case "Pd": return category(1<<Character.DASH_PUNCTUATION);
+ case "Ps": return category(1<<Character.START_PUNCTUATION);
+ case "Pe": return category(1<<Character.END_PUNCTUATION);
+ case "Pc": return category(1<<Character.CONNECTOR_PUNCTUATION);
+ case "Po": return category(1<<Character.OTHER_PUNCTUATION);
+ case "Sm": return category(1<<Character.MATH_SYMBOL);
+ case "Sc": return category(1<<Character.CURRENCY_SYMBOL);
+ case "Sk": return category(1<<Character.MODIFIER_SYMBOL);
+ case "So": return category(1<<Character.OTHER_SYMBOL);
+ case "Pi": return category(1<<Character.INITIAL_QUOTE_PUNCTUATION);
+ case "Pf": return category(1<<Character.FINAL_QUOTE_PUNCTUATION);
+ case "L": return category(((1<<Character.UPPERCASE_LETTER) |
+ (1<<Character.LOWERCASE_LETTER) |
+ (1<<Character.TITLECASE_LETTER) |
+ (1<<Character.MODIFIER_LETTER) |
+ (1<<Character.OTHER_LETTER)));
+ case "M": return category(((1<<Character.NON_SPACING_MARK) |
+ (1<<Character.ENCLOSING_MARK) |
+ (1<<Character.COMBINING_SPACING_MARK)));
+ case "N": return category(((1<<Character.DECIMAL_DIGIT_NUMBER) |
+ (1<<Character.LETTER_NUMBER) |
+ (1<<Character.OTHER_NUMBER)));
+ case "Z": return category(((1<<Character.SPACE_SEPARATOR) |
+ (1<<Character.LINE_SEPARATOR) |
+ (1<<Character.PARAGRAPH_SEPARATOR)));
+ case "C": return category(((1<<Character.CONTROL) |
+ (1<<Character.FORMAT) |
+ (1<<Character.PRIVATE_USE) |
+ (1<<Character.SURROGATE) |
+ (1<<Character.UNASSIGNED))); // Other
+ case "P": return category(((1<<Character.DASH_PUNCTUATION) |
+ (1<<Character.START_PUNCTUATION) |
+ (1<<Character.END_PUNCTUATION) |
+ (1<<Character.CONNECTOR_PUNCTUATION) |
+ (1<<Character.OTHER_PUNCTUATION) |
+ (1<<Character.INITIAL_QUOTE_PUNCTUATION) |
+ (1<<Character.FINAL_QUOTE_PUNCTUATION)));
+ case "S": return category(((1<<Character.MATH_SYMBOL) |
+ (1<<Character.CURRENCY_SYMBOL) |
+ (1<<Character.MODIFIER_SYMBOL) |
+ (1<<Character.OTHER_SYMBOL)));
+ case "LC": return category(((1<<Character.UPPERCASE_LETTER) |
+ (1<<Character.LOWERCASE_LETTER) |
+ (1<<Character.TITLECASE_LETTER)));
+ case "LD": return category(((1<<Character.UPPERCASE_LETTER) |
+ (1<<Character.LOWERCASE_LETTER) |
+ (1<<Character.TITLECASE_LETTER) |
+ (1<<Character.MODIFIER_LETTER) |
+ (1<<Character.OTHER_LETTER) |
+ (1<<Character.DECIMAL_DIGIT_NUMBER)));
+ case "L1": return range(0x00, 0xFF); // Latin-1
+ case "all": return Pattern.ALL();
+ // Posix regular expression character classes, defined in
+ // http://www.unix.org/onlinepubs/009695399/basedefs/xbd_chap09.html
+ case "ASCII": return range(0x00, 0x7F); // ASCII
+ case "Alnum": return ctype(ASCII.ALNUM); // Alphanumeric characters
+ case "Alpha": return ctype(ASCII.ALPHA); // Alphabetic characters
+ case "Blank": return ctype(ASCII.BLANK); // Space and tab characters
+ case "Cntrl": return ctype(ASCII.CNTRL); // Control characters
+ case "Digit": return range('0', '9'); // Numeric characters
+ case "Graph": return ctype(ASCII.GRAPH); // printable and visible
+ case "Lower": return range('a', 'z'); // Lower-case alphabetic
+ case "Print": return range(0x20, 0x7E); // Printable characters
+ case "Punct": return ctype(ASCII.PUNCT); // Punctuation characters
+ case "Space": return ctype(ASCII.SPACE); // Space characters
+ case "Upper": return range('A', 'Z'); // Upper-case alphabetic
+ case "XDigit": return ctype(ASCII.XDIGIT); // hexadecimal digits
- // Posix regular expression character classes, defined in
- // http://www.unix.org/onlinepubs/009695399/basedefs/xbd_chap09.html
- defRange("ASCII", 0x00, 0x7F); // ASCII
- defCtype("Alnum", ASCII.ALNUM); // Alphanumeric characters
- defCtype("Alpha", ASCII.ALPHA); // Alphabetic characters
- defCtype("Blank", ASCII.BLANK); // Space and tab characters
- defCtype("Cntrl", ASCII.CNTRL); // Control characters
- defRange("Digit", '0', '9'); // Numeric characters
- defCtype("Graph", ASCII.GRAPH); // printable and visible
- defRange("Lower", 'a', 'z'); // Lower-case alphabetic
- defRange("Print", 0x20, 0x7E); // Printable characters
- defCtype("Punct", ASCII.PUNCT); // Punctuation characters
- defCtype("Space", ASCII.SPACE); // Space characters
- defRange("Upper", 'A', 'Z'); // Upper-case alphabetic
- defCtype("XDigit",ASCII.XDIGIT); // hexadecimal digits
+ // Java character properties, defined by methods in Character.java
+ case "javaLowerCase": return java.lang.Character::isLowerCase;
+ case "javaUpperCase": return Character::isUpperCase;
+ case "javaAlphabetic": return java.lang.Character::isAlphabetic;
+ case "javaIdeographic": return java.lang.Character::isIdeographic;
+ case "javaTitleCase": return java.lang.Character::isTitleCase;
+ case "javaDigit": return java.lang.Character::isDigit;
+ case "javaDefined": return java.lang.Character::isDefined;
+ case "javaLetter": return java.lang.Character::isLetter;
+ case "javaLetterOrDigit": return java.lang.Character::isLetterOrDigit;
+ case "javaJavaIdentifierStart": return java.lang.Character::isJavaIdentifierStart;
+ case "javaJavaIdentifierPart": return java.lang.Character::isJavaIdentifierPart;
+ case "javaUnicodeIdentifierStart": return java.lang.Character::isUnicodeIdentifierStart;
+ case "javaUnicodeIdentifierPart": return java.lang.Character::isUnicodeIdentifierPart;
+ case "javaIdentifierIgnorable": return java.lang.Character::isIdentifierIgnorable;
+ case "javaSpaceChar": return java.lang.Character::isSpaceChar;
+ case "javaWhitespace": return java.lang.Character::isWhitespace;
+ case "javaISOControl": return java.lang.Character::isISOControl;
+ case "javaMirrored": return java.lang.Character::isMirrored;
+ default: return null;
+ }
+ }
- // Java character properties, defined by methods in Character.java
- defProp("javaLowerCase", java.lang.Character::isLowerCase);
- defProp("javaUpperCase", Character::isUpperCase);
- defProp("javaAlphabetic", java.lang.Character::isAlphabetic);
- defProp("javaIdeographic", java.lang.Character::isIdeographic);
- defProp("javaTitleCase", java.lang.Character::isTitleCase);
- defProp("javaDigit", java.lang.Character::isDigit);
- defProp("javaDefined", java.lang.Character::isDefined);
- defProp("javaLetter", java.lang.Character::isLetter);
- defProp("javaLetterOrDigit", java.lang.Character::isLetterOrDigit);
- defProp("javaJavaIdentifierStart", java.lang.Character::isJavaIdentifierStart);
- defProp("javaJavaIdentifierPart", java.lang.Character::isJavaIdentifierPart);
- defProp("javaUnicodeIdentifierStart", java.lang.Character::isUnicodeIdentifierStart);
- defProp("javaUnicodeIdentifierPart", java.lang.Character::isUnicodeIdentifierPart);
- defProp("javaIdentifierIgnorable", java.lang.Character::isIdentifierIgnorable);
- defProp("javaSpaceChar", java.lang.Character::isSpaceChar);
- defProp("javaWhitespace", java.lang.Character::isWhitespace);
- defProp("javaISOControl", java.lang.Character::isISOControl);
- defProp("javaMirrored", java.lang.Character::isMirrored);
+ private static CharPredicate category(final int typeMask) {
+ return ch -> (typeMask & (1 << Character.getType(ch))) != 0;
+ }
+
+ private static CharPredicate range(final int lower, final int upper) {
+ return (BmpCharPredicate)ch -> lower <= ch && ch <= upper;
+ }
+
+ private static CharPredicate ctype(final int ctype) {
+ return (BmpCharPredicate)ch -> ch < 128 && ASCII.isType(ch, ctype);
}
/////////////////////////////////////////////////////////////////////////////
@@ -369,8 +385,14 @@
/**
* Posix ASCII variants, not in the lookup map
*/
- static final BmpCharPredicate ASCII_DIGIT = ch -> ch < 128 && ASCII.isDigit(ch);
- static final BmpCharPredicate ASCII_WORD = ch -> ch < 128 && ASCII.isWord(ch);
- static final BmpCharPredicate ASCII_SPACE = ch -> ch < 128 && ASCII.isSpace(ch);
+ static final BmpCharPredicate ASCII_DIGIT() {
+ return ch -> ch < 128 && ASCII.isDigit(ch);
+ }
+ static final BmpCharPredicate ASCII_WORD() {
+ return ch -> ch < 128 && ASCII.isWord(ch);
+ }
+ static final BmpCharPredicate ASCII_SPACE() {
+ return ch -> ch < 128 && ASCII.isSpace(ch);
+ }
}
--- a/jdk/src/java.base/share/classes/java/util/regex/Pattern.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/regex/Pattern.java Thu Feb 02 21:55:34 2017 +0000
@@ -1495,7 +1495,7 @@
altns.add(seq);
produceEquivalentAlternation(nfd, altns);
dst.append("(?:");
- altns.forEach( s -> dst.append(s + "|"));
+ altns.forEach( s -> dst.append(s).append('|'));
dst.delete(dst.length() - 1, dst.length());
dst.append(")");
continue;
@@ -2142,12 +2142,12 @@
case '.':
next();
if (has(DOTALL)) {
- node = new CharProperty(ALL);
+ node = new CharProperty(ALL());
} else {
if (has(UNIX_LINES)) {
- node = new CharProperty(UNIXDOT);
+ node = new CharProperty(UNIXDOT());
} else {
- node = new CharProperty(DOT);
+ node = new CharProperty(DOT());
}
}
break;
@@ -2376,7 +2376,7 @@
case 'D':
if (create) {
predicate = has(UNICODE_CHARACTER_CLASS) ?
- CharPredicates.DIGIT : CharPredicates.ASCII_DIGIT;
+ CharPredicates.DIGIT() : CharPredicates.ASCII_DIGIT();
predicate = predicate.negate();
if (!inclass)
root = newCharProperty(predicate);
@@ -2391,7 +2391,7 @@
return -1;
case 'H':
if (create) {
- predicate = HorizWS.negate();
+ predicate = HorizWS().negate();
if (!inclass)
root = newCharProperty(predicate);
}
@@ -2415,7 +2415,7 @@
case 'S':
if (create) {
predicate = has(UNICODE_CHARACTER_CLASS) ?
- CharPredicates.WHITE_SPACE : CharPredicates.ASCII_SPACE;
+ CharPredicates.WHITE_SPACE() : CharPredicates.ASCII_SPACE();
predicate = predicate.negate();
if (!inclass)
root = newCharProperty(predicate);
@@ -2426,7 +2426,7 @@
break;
case 'V':
if (create) {
- predicate = VertWS.negate();
+ predicate = VertWS().negate();
if (!inclass)
root = newCharProperty(predicate);
}
@@ -2434,7 +2434,7 @@
case 'W':
if (create) {
predicate = has(UNICODE_CHARACTER_CLASS) ?
- CharPredicates.WORD : CharPredicates.ASCII_WORD;
+ CharPredicates.WORD() : CharPredicates.ASCII_WORD();
predicate = predicate.negate();
if (!inclass)
root = newCharProperty(predicate);
@@ -2480,7 +2480,7 @@
case 'd':
if (create) {
predicate = has(UNICODE_CHARACTER_CLASS) ?
- CharPredicates.DIGIT : CharPredicates.ASCII_DIGIT;
+ CharPredicates.DIGIT() : CharPredicates.ASCII_DIGIT();
if (!inclass)
root = newCharProperty(predicate);
}
@@ -2493,7 +2493,7 @@
break;
case 'h':
if (create) {
- predicate = HorizWS;
+ predicate = HorizWS();
if (!inclass)
root = newCharProperty(predicate);
}
@@ -2531,7 +2531,7 @@
case 's':
if (create) {
predicate = has(UNICODE_CHARACTER_CLASS) ?
- CharPredicates.WHITE_SPACE : CharPredicates.ASCII_SPACE;
+ CharPredicates.WHITE_SPACE() : CharPredicates.ASCII_SPACE();
if (!inclass)
root = newCharProperty(predicate);
}
@@ -2552,7 +2552,7 @@
if (isrange)
return '\013';
if (create) {
- predicate = VertWS;
+ predicate = VertWS();
if (!inclass)
root = newCharProperty(predicate);
}
@@ -2560,7 +2560,7 @@
case 'w':
if (create) {
predicate = has(UNICODE_CHARACTER_CLASS) ?
- CharPredicates.WORD : CharPredicates.ASCII_WORD;
+ CharPredicates.WORD() : CharPredicates.ASCII_WORD();
if (!inclass)
root = newCharProperty(predicate);
}
@@ -2704,7 +2704,6 @@
(6)AngstromSign u+212b
toLowerCase(u+212b) ==> u+00e5
*/
- int d;
if (ch < 256 &&
!(has(CASE_INSENSITIVE) && has(UNICODE_CASE) &&
(ch == 0xff || ch == 0xb5 ||
@@ -5384,7 +5383,7 @@
}
boolean isWord(int ch) {
- return useUWORD ? CharPredicates.WORD.is(ch)
+ return useUWORD ? CharPredicates.WORD().is(ch)
: (ch == '_' || Character.isLetterOrDigit(ch));
}
@@ -5680,33 +5679,45 @@
/**
* matches a Perl vertical whitespace
*/
- static BmpCharPredicate VertWS = cp ->
- (cp >= 0x0A && cp <= 0x0D) || cp == 0x85 || cp == 0x2028 || cp == 0x2029;
+ static BmpCharPredicate VertWS() {
+ return cp -> (cp >= 0x0A && cp <= 0x0D) ||
+ cp == 0x85 || cp == 0x2028 || cp == 0x2029;
+ }
/**
* matches a Perl horizontal whitespace
*/
- static BmpCharPredicate HorizWS = cp ->
- cp == 0x09 || cp == 0x20 || cp == 0xa0 || cp == 0x1680 ||
- cp == 0x180e || cp >= 0x2000 && cp <= 0x200a || cp == 0x202f ||
- cp == 0x205f || cp == 0x3000;
+ static BmpCharPredicate HorizWS() {
+ return cp ->
+ cp == 0x09 || cp == 0x20 || cp == 0xa0 || cp == 0x1680 ||
+ cp == 0x180e || cp >= 0x2000 && cp <= 0x200a || cp == 0x202f ||
+ cp == 0x205f || cp == 0x3000;
+ }
/**
* for the Unicode category ALL and the dot metacharacter when
* in dotall mode.
*/
- static CharPredicate ALL = ch -> true;
+ static CharPredicate ALL() {
+ return ch -> true;
+ }
/**
* for the dot metacharacter when dotall is not enabled.
*/
- static CharPredicate DOT = ch -> (ch != '\n' && ch != '\r'
- && (ch|1) != '\u2029'
- && ch != '\u0085');
+ static CharPredicate DOT() {
+ return ch ->
+ (ch != '\n' && ch != '\r'
+ && (ch|1) != '\u2029'
+ && ch != '\u0085');
+ }
+
/**
* the dot metacharacter when dotall is not enabled but UNIX_LINES is enabled.
*/
- static CharPredicate UNIXDOT = ch -> ch != '\n';
+ static CharPredicate UNIXDOT() {
+ return ch -> ch != '\n';
+ }
/**
* Indicate that matches a Supplementary Unicode character
--- a/jdk/src/java.base/share/classes/java/util/regex/PrintPattern.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/regex/PrintPattern.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,6 @@
import java.util.HashMap;
import java.util.regex.Pattern.CharPredicate;
-import java.util.regex.CharPredicates;
import static java.util.regex.ASCII.*;
/**
@@ -106,15 +105,15 @@
static HashMap<CharPredicate, String> pmap;
static {
pmap = new HashMap<>();
- pmap.put(Pattern.ALL, "All");
- pmap.put(Pattern.DOT, "Dot");
- pmap.put(Pattern.UNIXDOT, "UnixDot");
- pmap.put(Pattern.VertWS, "VertWS");
- pmap.put(Pattern.HorizWS, "HorizWS");
+ pmap.put(Pattern.ALL(), "All");
+ pmap.put(Pattern.DOT(), "Dot");
+ pmap.put(Pattern.UNIXDOT(), "UnixDot");
+ pmap.put(Pattern.VertWS(), "VertWS");
+ pmap.put(Pattern.HorizWS(), "HorizWS");
- pmap.put(CharPredicates.ASCII_DIGIT, "ASCII.DIGIT");
- pmap.put(CharPredicates.ASCII_WORD, "ASCII.WORD");
- pmap.put(CharPredicates.ASCII_SPACE, "ASCII.SPACE");
+ pmap.put(CharPredicates.ASCII_DIGIT(), "ASCII.DIGIT");
+ pmap.put(CharPredicates.ASCII_WORD(), "ASCII.WORD");
+ pmap.put(CharPredicates.ASCII_SPACE(), "ASCII.SPACE");
}
static void walk(Pattern.Node node, int depth) {
--- a/jdk/src/java.base/share/classes/module-info.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.base/share/classes/module-info.java Thu Feb 02 21:55:34 2017 +0000
@@ -150,7 +150,7 @@
java.desktop;
exports jdk.internal.module to
java.instrument,
- java.management,
+ java.management.rmi,
jdk.jartool,
jdk.jlink;
exports jdk.internal.misc to
@@ -177,6 +177,7 @@
exports jdk.internal.perf to
java.desktop,
java.management,
+ jdk.management.agent,
jdk.jvmstat;
exports jdk.internal.ref to
java.desktop,
@@ -197,6 +198,7 @@
jdk.jlink;
exports jdk.internal.vm to
java.management,
+ jdk.management.agent,
jdk.jvmstat;
exports sun.net to
jdk.incubator.httpclient;
@@ -233,6 +235,7 @@
java.desktop,
java.datatransfer,
java.management,
+ java.management.rmi,
java.rmi,
java.sql.rowset,
java.xml,
--- a/jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java Thu Feb 02 21:55:34 2017 +0000
@@ -581,12 +581,18 @@
}
// load the class from the module
- Class<?> c = Class.forName(m, mainClass);
- if (c == null && System.getProperty("os.name", "").contains("OS X")
- && Normalizer.isNormalized(mainClass, Normalizer.Form.NFD)) {
+ Class<?> c = null;
+ try {
+ c = Class.forName(m, mainClass);
+ if (c == null && System.getProperty("os.name", "").contains("OS X")
+ && Normalizer.isNormalized(mainClass, Normalizer.Form.NFD)) {
- String cn = Normalizer.normalize(mainClass, Normalizer.Form.NFC);
- c = Class.forName(m, cn);
+ String cn = Normalizer.normalize(mainClass, Normalizer.Form.NFC);
+ c = Class.forName(m, cn);
+ }
+ } catch (LinkageError le) {
+ abort(null, "java.launcher.module.error3",
+ mainClass, m.getName(), le.getLocalizedMessage());
}
if (c == null) {
abort(null, "java.launcher.module.error2", mainClass, mainModule);
@@ -619,23 +625,27 @@
Class<?> mainClass = null;
ClassLoader scl = ClassLoader.getSystemClassLoader();
try {
- mainClass = Class.forName(cn, false, scl);
- } catch (NoClassDefFoundError | ClassNotFoundException cnfe) {
- if (System.getProperty("os.name", "").contains("OS X")
- && Normalizer.isNormalized(cn, Normalizer.Form.NFD)) {
- try {
- // On Mac OS X since all names with diacritical marks are
- // given as decomposed it is possible that main class name
- // comes incorrectly from the command line and we have
- // to re-compose it
- String ncn = Normalizer.normalize(cn, Normalizer.Form.NFC);
- mainClass = Class.forName(ncn, false, scl);
- } catch (NoClassDefFoundError | ClassNotFoundException cnfe1) {
+ try {
+ mainClass = Class.forName(cn, false, scl);
+ } catch (NoClassDefFoundError | ClassNotFoundException cnfe) {
+ if (System.getProperty("os.name", "").contains("OS X")
+ && Normalizer.isNormalized(cn, Normalizer.Form.NFD)) {
+ try {
+ // On Mac OS X since all names with diacritical marks are
+ // given as decomposed it is possible that main class name
+ // comes incorrectly from the command line and we have
+ // to re-compose it
+ String ncn = Normalizer.normalize(cn, Normalizer.Form.NFC);
+ mainClass = Class.forName(ncn, false, scl);
+ } catch (NoClassDefFoundError | ClassNotFoundException cnfe1) {
+ abort(cnfe1, "java.launcher.cls.error1", cn);
+ }
+ } else {
abort(cnfe, "java.launcher.cls.error1", cn);
}
- } else {
- abort(cnfe, "java.launcher.cls.error1", cn);
}
+ } catch (LinkageError le) {
+ abort(le, "java.launcher.cls.error6", cn, le.getLocalizedMessage());
}
return mainClass;
}
--- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties Thu Feb 02 21:55:34 2017 +0000
@@ -189,6 +189,9 @@
or a JavaFX application class must extend {1}
java.launcher.cls.error5=\
Error: JavaFX runtime components are missing, and are required to run this application
+java.launcher.cls.error6=\
+ Error: LinkageError occurred while loading main class {0}\n\
+ \t{1}
java.launcher.jar.error1=\
Error: An unexpected error occurred while trying to open file {0}
java.launcher.jar.error2=manifest not found in {0}
@@ -201,3 +204,7 @@
module {0} does not have a MainClass attribute, use -m <module>/<main-class>
java.launcher.module.error2=\
Error: Could not find or load main class {0} in module {1}
+java.launcher.module.error3=\
+ Error: Unable to load main class {0} from module {1}\n\
+ \t{2}
+
--- a/jdk/src/java.base/share/classes/sun/net/spi/DefaultProxySelector.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/net/spi/DefaultProxySelector.java Thu Feb 02 21:55:34 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, 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,16 +30,19 @@
import java.net.ProxySelector;
import java.net.SocketAddress;
import java.net.URI;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.StringJoiner;
import java.util.regex.Pattern;
+import java.util.stream.Stream;
import sun.net.NetProperties;
import sun.net.SocksProxy;
import static java.util.regex.Pattern.quote;
+import static java.util.stream.Collectors.collectingAndThen;
+import static java.util.stream.Collectors.toList;
/**
* Supports proxy settings using system properties This proxy selector
@@ -87,6 +90,8 @@
private static boolean hasSystemProxies = false;
+ private static final List<Proxy> NO_PROXY_LIST = List.of(Proxy.NO_PROXY);
+
static {
final String key = "java.net.useSystemProxies";
Boolean b = AccessController.doPrivileged(
@@ -149,8 +154,9 @@
* select() method. Where all the hard work is done.
* Build a list of proxies depending on URI.
* Since we're only providing compatibility with the system properties
- * from previous releases (see list above), that list will always
- * contain 1 single proxy, default being NO_PROXY.
+ * from previous releases (see list above), that list will typically
+ * contain one single proxy, default being NO_PROXY.
+ * If we can get a system proxy it might contain more entries.
*/
public java.util.List<Proxy> select(URI uri) {
if (uri == null) {
@@ -185,7 +191,6 @@
if (protocol == null || host == null) {
throw new IllegalArgumentException("protocol = "+protocol+" host = "+host);
}
- List<Proxy> proxyl = new ArrayList<Proxy>(1);
NonProxyInfo pinfo = null;
@@ -214,9 +219,9 @@
* System properties it does help having only 1 call to doPrivileged.
* Be mindful what you do in here though!
*/
- Proxy p = AccessController.doPrivileged(
- new PrivilegedAction<Proxy>() {
- public Proxy run() {
+ Proxy[] proxyArray = AccessController.doPrivileged(
+ new PrivilegedAction<Proxy[]>() {
+ public Proxy[] run() {
int i, j;
String phost = null;
int pport = 0;
@@ -239,8 +244,8 @@
/**
* No system property defined for that
* protocol. Let's check System Proxy
- * settings (Gnome & Windows) if we were
- * instructed to.
+ * settings (Gnome, MacOsX & Windows) if
+ * we were instructed to.
*/
if (hasSystemProxies) {
String sproto;
@@ -248,12 +253,9 @@
sproto = "socks";
else
sproto = proto;
- Proxy sproxy = getSystemProxy(sproto, urlhost);
- if (sproxy != null) {
- return sproxy;
- }
+ return getSystemProxies(sproto, urlhost);
}
- return Proxy.NO_PROXY;
+ return null;
}
// If a Proxy Host is defined for that protocol
// Let's get the NonProxyHosts property
@@ -281,7 +283,7 @@
}
}
if (shouldNotUseProxyFor(nprop.pattern, urlhost)) {
- return Proxy.NO_PROXY;
+ return null;
}
}
}
@@ -311,22 +313,24 @@
saddr = InetSocketAddress.createUnresolved(phost, pport);
// Socks is *always* the last on the list.
if (j == (props[i].length - 1)) {
- return SocksProxy.create(saddr, socksProxyVersion());
- } else {
- return new Proxy(Proxy.Type.HTTP, saddr);
+ return new Proxy[] {SocksProxy.create(saddr, socksProxyVersion())};
}
+ return new Proxy[] {new Proxy(Proxy.Type.HTTP, saddr)};
}
}
- return Proxy.NO_PROXY;
+ return null;
}});
- proxyl.add(p);
- /*
- * If no specific property was set for that URI, we should be
- * returning an iterator to an empty List.
- */
- return proxyl;
+ if (proxyArray != null) {
+ // Remove duplicate entries, while preserving order.
+ return Stream.of(proxyArray).distinct().collect(
+ collectingAndThen(toList(), Collections::unmodifiableList));
+ }
+
+ // If no specific proxy was found, return a standard list containing
+ // only one NO_PROXY entry.
+ return NO_PROXY_LIST;
}
public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
@@ -354,7 +358,7 @@
}
private static native boolean init();
- private synchronized native Proxy getSystemProxy(String protocol, String host);
+ private synchronized native Proxy[] getSystemProxies(String protocol, String host);
/**
* @return {@code true} if given this pattern for non-proxy hosts and this
--- a/jdk/src/java.base/share/native/libjli/java.c Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.base/share/native/libjli/java.c Thu Feb 02 21:55:34 2017 +0000
@@ -1587,7 +1587,7 @@
p = JLI_MemAlloc(optLen + valueLen + 1);
memcpy(p, arg, optLen);
memcpy(p + optLen, value, valueLen);
- p[optLen + valueLen + 1] = '\0';
+ p[optLen + valueLen] = '\0';
return p;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libnet/proxy_util.c Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2017, 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 "jni.h"
+#include "jni_util.h"
+
+#include "proxy_util.h"
+
+jclass proxy_class;
+jclass isaddr_class;
+jclass ptype_class;
+jmethodID isaddr_createUnresolvedID;
+jmethodID proxy_ctrID;
+jfieldID pr_no_proxyID;
+jfieldID ptype_httpID;
+jfieldID ptype_socksID;
+
+int initJavaClass(JNIEnv *env) {
+ jclass proxy_cls = NULL;
+ jclass ptype_cls = NULL;
+ jclass isaddr_cls = NULL;
+
+ // Proxy initialization
+ proxy_cls = (*env)->FindClass(env,"java/net/Proxy");
+ CHECK_NULL_RETURN(proxy_cls, 0);
+ proxy_class = (*env)->NewGlobalRef(env, proxy_cls);
+ CHECK_NULL_RETURN(proxy_class, 0);
+ proxy_ctrID = (*env)->GetMethodID(env, proxy_class, "<init>",
+ "(Ljava/net/Proxy$Type;Ljava/net/SocketAddress;)V");
+ CHECK_NULL_RETURN(proxy_ctrID, 0);
+
+ // Proxy$Type initialization
+ ptype_cls = (*env)->FindClass(env,"java/net/Proxy$Type");
+ CHECK_NULL_RETURN(ptype_cls, 0);
+ ptype_class = (*env)->NewGlobalRef(env, ptype_cls);
+ CHECK_NULL_RETURN(ptype_class, 0);
+ ptype_httpID = (*env)->GetStaticFieldID(env, ptype_class, "HTTP",
+ "Ljava/net/Proxy$Type;");
+ CHECK_NULL_RETURN(ptype_httpID, 0);
+ ptype_socksID = (*env)->GetStaticFieldID(env, ptype_class, "SOCKS",
+ "Ljava/net/Proxy$Type;");
+ CHECK_NULL_RETURN(ptype_socksID, 0);
+
+ // NO_PROXY
+ pr_no_proxyID = (*env)->GetStaticFieldID(env, proxy_class, "NO_PROXY",
+ "Ljava/net/Proxy;");
+ CHECK_NULL_RETURN(pr_no_proxyID, 0);
+
+ // InetSocketAddress initialization
+ isaddr_cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
+ CHECK_NULL_RETURN(isaddr_cls, 0);
+ isaddr_class = (*env)->NewGlobalRef(env, isaddr_cls);
+ CHECK_NULL_RETURN(isaddr_class, 0);
+ isaddr_createUnresolvedID = (*env)->GetStaticMethodID(env, isaddr_class,
+ "createUnresolved",
+ "(Ljava/lang/String;I)Ljava/net/InetSocketAddress;");
+
+ return isaddr_createUnresolvedID != NULL ? 1 : 0;
+}
+
+jobject createProxy(JNIEnv *env, jfieldID ptype_ID, const char* phost, unsigned short pport) {
+ jobject jProxy = NULL;
+ jobject type_proxy = NULL;
+ type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_ID);
+ if (type_proxy) {
+ jstring jhost = NULL;
+ jhost = (*env)->NewStringUTF(env, phost);
+ if (jhost) {
+ jobject isa = NULL;
+ isa = (*env)->CallStaticObjectMethod(env, isaddr_class,
+ isaddr_createUnresolvedID, jhost, pport);
+ if (isa) {
+ jProxy = (*env)->NewObject(env, proxy_class, proxy_ctrID,
+ type_proxy, isa);
+ }
+ }
+ }
+ return jProxy;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libnet/proxy_util.h Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+extern jclass proxy_class;
+extern jclass isaddr_class;
+extern jclass ptype_class;
+extern jmethodID isaddr_createUnresolvedID;
+extern jmethodID proxy_ctrID;
+extern jfieldID pr_no_proxyID;
+extern jfieldID ptype_httpID;
+extern jfieldID ptype_socksID;
+
+int initJavaClass(JNIEnv *env);
+
+jobject createProxy(JNIEnv *env, jfieldID ptype_ID, const char* phost, unsigned short pport);
--- a/jdk/src/java.base/unix/native/libnet/DefaultProxySelector.c Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.base/unix/native/libnet/DefaultProxySelector.c Thu Feb 02 21:55:34 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, 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,24 +23,20 @@
* questions.
*/
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
#include "jni.h"
#include "jni_util.h"
#include "jvm.h"
#include "jvm_md.h"
-#include "jlong.h"
+
+#include "proxy_util.h"
+
#include "sun_net_spi_DefaultProxySelector.h"
-#include <dlfcn.h>
-#include <stdio.h>
-#include <stdlib.h>
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
-#include <string.h>
-#else
-#include <strings.h>
-#endif
-#ifndef CHECK_NULL_RETURN
-#define CHECK_NULL_RETURN(x, y) if ((x) == NULL) return y;
-#endif
/**
* These functions are used by the sun.net.spi.DefaultProxySelector class
@@ -112,43 +108,11 @@
static g_network_address_get_port_func* g_network_address_get_port = NULL;
static g_strfreev_func* g_strfreev = NULL;
-
-static jclass proxy_class;
-static jclass isaddr_class;
-static jclass ptype_class;
-static jmethodID isaddr_createUnresolvedID;
-static jmethodID proxy_ctrID;
-static jfieldID ptype_httpID;
-static jfieldID ptype_socksID;
-
-
static void* gconf_client = NULL;
static int use_gproxyResolver = 0;
static int use_gconf = 0;
-static jobject createProxy(JNIEnv *env, jfieldID ptype_ID,
- const char* phost, unsigned short pport)
-{
- jobject jProxy = NULL;
- jobject type_proxy = NULL;
- type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_ID);
- if (type_proxy) {
- jstring jhost = NULL;
- jhost = (*env)->NewStringUTF(env, phost);
- if (jhost) {
- jobject isa = NULL;
- isa = (*env)->CallStaticObjectMethod(env, isaddr_class,
- isaddr_createUnresolvedID, jhost, pport);
- if (isa) {
- jProxy = (*env)->NewObject(env, proxy_class, proxy_ctrID,
- type_proxy, isa);
- }
- }
- }
- return jProxy;
-}
-
static int initGConf() {
/**
* Let's try to load GConf-2 library
@@ -196,18 +160,18 @@
return 0;
}
-static jobject getProxyByGConf(JNIEnv *env, const char* cproto,
- const char* chost)
+static jobjectArray getProxyByGConf(JNIEnv *env, const char* cproto,
+ const char* chost)
{
char *phost = NULL;
char *mode = NULL;
int pport = 0;
int use_proxy = 0;
int use_same_proxy = 0;
- jobject proxy = NULL;
+ jobjectArray proxy_array = NULL;
jfieldID ptype_ID = ptype_httpID;
- // We only check manual proxy configurations
+ /* We only check manual proxy configurations */
mode = (*my_get_string_func)(gconf_client, "/system/proxy/mode", NULL);
if (mode && !strcasecmp(mode, "manual")) {
/*
@@ -293,7 +257,7 @@
char *s;
/**
- * check for the exclude list (aka "No Proxy For" list).
+ * Check for the exclude list (aka "No Proxy For" list).
* It's a list of comma separated suffixes (e.g. domain name).
*/
noproxyfor = (*my_get_string_func)(gconf_client, "/system/proxy/no_proxy_for", NULL);
@@ -313,11 +277,25 @@
s = strtok_r(NULL, ", ", tmpbuf);
}
}
- if (use_proxy)
+ if (use_proxy) {
+ jobject proxy = NULL;
+ /* create a proxy array with one element. */
+ proxy_array = (*env)->NewObjectArray(env, 1, proxy_class, NULL);
+ if (proxy_array == NULL || (*env)->ExceptionCheck(env)) {
+ return NULL;
+ }
proxy = createProxy(env, ptype_ID, phost, pport);
+ if (proxy == NULL || (*env)->ExceptionCheck(env)) {
+ return NULL;
+ }
+ (*env)->SetObjectArrayElement(env, proxy_array, 0, proxy);
+ if ((*env)->ExceptionCheck(env)) {
+ return NULL;
+ }
+ }
}
- return proxy;
+ return proxy_array;
}
static int initGProxyResolver() {
@@ -371,8 +349,8 @@
return 1;
}
-static jobject getProxyByGProxyResolver(JNIEnv *env, const char* cproto,
- const char* chost)
+static jobjectArray getProxyByGProxyResolver(JNIEnv *env, const char *cproto,
+ const char *chost)
{
GProxyResolver* resolver = NULL;
char** proxies = NULL;
@@ -382,19 +360,19 @@
size_t hostLen = 0;
char* uri = NULL;
- jobject jProxy = NULL;
+ jobjectArray proxy_array = NULL;
resolver = (*g_proxy_resolver_get_default)();
if (resolver == NULL) {
return NULL;
}
- // Construct the uri, cproto + "://" + chost
+ /* Construct the uri, cproto + "://" + chost */
protoLen = strlen(cproto);
hostLen = strlen(chost);
uri = malloc(protoLen + hostLen + 4);
if (!uri) {
- // Out of memory
+ /* Out of memory */
return NULL;
}
memcpy(uri, cproto, protoLen);
@@ -414,22 +392,56 @@
if (proxies) {
if (!error) {
int i;
- for(i = 0; proxies[i] && !jProxy; i++) {
- if (strcmp(proxies[i], "direct://")) {
- GSocketConnectable* conn =
- (*g_network_address_parse_uri)(proxies[i], 0,
- &error);
- if (conn && !error) {
- const char* phost = NULL;
- unsigned short pport = 0;
- phost = (*g_network_address_get_hostname)(conn);
- pport = (*g_network_address_get_port)(conn);
- if (phost && pport > 0) {
- jfieldID ptype_ID = ptype_httpID;
- if (!strncmp(proxies[i], "socks", 5))
- ptype_ID = ptype_socksID;
+ int nr_proxies = 0;
+ char** p = proxies;
+ /* count the elements in the null terminated string vector. */
+ while (*p) {
+ nr_proxies++;
+ p++;
+ }
+ /* create a proxy array that has to be filled. */
+ proxy_array = (*env)->NewObjectArray(env, nr_proxies, proxy_class, NULL);
+ if (proxy_array != NULL && !(*env)->ExceptionCheck(env)) {
+ for (i = 0; proxies[i]; i++) {
+ if (strncmp(proxies[i], "direct://", 9)) {
+ GSocketConnectable* conn =
+ (*g_network_address_parse_uri)(proxies[i], 0,
+ &error);
+ if (conn && !error) {
+ const char *phost = NULL;
+ unsigned short pport = 0;
+ phost = (*g_network_address_get_hostname)(conn);
+ pport = (*g_network_address_get_port)(conn);
+ if (phost && pport > 0) {
+ jobject proxy = NULL;
+ jfieldID ptype_ID = ptype_httpID;
+ if (!strncmp(proxies[i], "socks", 5))
+ ptype_ID = ptype_socksID;
- jProxy = createProxy(env, ptype_ID, phost, pport);
+ proxy = createProxy(env, ptype_ID, phost, pport);
+ if (proxy == NULL || (*env)->ExceptionCheck(env)) {
+ proxy_array = NULL;
+ break;
+ }
+ (*env)->SetObjectArrayElement(env, proxy_array, i, proxy);
+ if ((*env)->ExceptionCheck(env)) {
+ proxy_array = NULL;
+ break;
+ }
+ }
+ }
+ } else {
+ /* direct connection - no proxy */
+ jobject proxy = (*env)->GetStaticObjectField(env, proxy_class,
+ pr_no_proxyID);
+ if (proxy == NULL || (*env)->ExceptionCheck(env)) {
+ proxy_array = NULL;
+ break;
+ }
+ (*env)->SetObjectArrayElement(env, proxy_array, i, proxy);
+ if ((*env)->ExceptionCheck(env)) {
+ proxy_array = NULL;
+ break;
}
}
}
@@ -438,48 +450,9 @@
(*g_strfreev)(proxies);
}
- return jProxy;
+ return proxy_array;
}
-static int initJavaClass(JNIEnv *env) {
- jclass proxy_cls = NULL;
- jclass ptype_cls = NULL;
- jclass isaddr_cls = NULL;
-
- // Proxy initialization
- proxy_cls = (*env)->FindClass(env,"java/net/Proxy");
- CHECK_NULL_RETURN(proxy_cls, 0);
- proxy_class = (*env)->NewGlobalRef(env, proxy_cls);
- CHECK_NULL_RETURN(proxy_class, 0);
- proxy_ctrID = (*env)->GetMethodID(env, proxy_class, "<init>",
- "(Ljava/net/Proxy$Type;Ljava/net/SocketAddress;)V");
- CHECK_NULL_RETURN(proxy_ctrID, 0);
-
- // Proxy$Type initialization
- ptype_cls = (*env)->FindClass(env,"java/net/Proxy$Type");
- CHECK_NULL_RETURN(ptype_cls, 0);
- ptype_class = (*env)->NewGlobalRef(env, ptype_cls);
- CHECK_NULL_RETURN(ptype_class, 0);
- ptype_httpID = (*env)->GetStaticFieldID(env, ptype_class, "HTTP",
- "Ljava/net/Proxy$Type;");
- CHECK_NULL_RETURN(ptype_httpID, 0);
- ptype_socksID = (*env)->GetStaticFieldID(env, ptype_class, "SOCKS",
- "Ljava/net/Proxy$Type;");
- CHECK_NULL_RETURN(ptype_socksID, 0);
-
- // InetSocketAddress initialization
- isaddr_cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
- CHECK_NULL_RETURN(isaddr_cls, 0);
- isaddr_class = (*env)->NewGlobalRef(env, isaddr_cls);
- CHECK_NULL_RETURN(isaddr_class, 0);
- isaddr_createUnresolvedID = (*env)->GetStaticMethodID(env, isaddr_class,
- "createUnresolved",
- "(Ljava/lang/String;I)Ljava/net/InetSocketAddress;");
-
- return isaddr_createUnresolvedID != NULL ? 1 : 0;
-}
-
-
/*
* Class: sun_net_spi_DefaultProxySelector
* Method: init
@@ -500,14 +473,14 @@
/*
* Class: sun_net_spi_DefaultProxySelector
- * Method: getSystemProxy
- * Signature: ([Ljava/lang/String;Ljava/lang/String;)Ljava/net/Proxy;
+ * Method: getSystemProxies
+ * Signature: ([Ljava/lang/String;Ljava/lang/String;)[Ljava/net/Proxy;
*/
-JNIEXPORT jobject JNICALL
-Java_sun_net_spi_DefaultProxySelector_getSystemProxy(JNIEnv *env,
- jobject this,
- jstring proto,
- jstring host)
+JNIEXPORT jobjectArray JNICALL
+Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env,
+ jobject this,
+ jstring proto,
+ jstring host)
{
const char* cproto;
const char* chost;
@@ -515,7 +488,7 @@
jboolean isProtoCopy;
jboolean isHostCopy;
- jobject proxy = NULL;
+ jobjectArray proxyArray = NULL;
cproto = (*env)->GetStringUTFChars(env, proto, &isProtoCopy);
@@ -523,16 +496,15 @@
chost = (*env)->GetStringUTFChars(env, host, &isHostCopy);
if (chost != NULL) {
if (use_gproxyResolver)
- proxy = getProxyByGProxyResolver(env, cproto, chost);
+ proxyArray = getProxyByGProxyResolver(env, cproto, chost);
else if (use_gconf)
- proxy = getProxyByGConf(env, cproto, chost);
-
+ proxyArray = getProxyByGConf(env, cproto, chost);
if (isHostCopy == JNI_TRUE)
(*env)->ReleaseStringUTFChars(env, host, chost);
}
if (isProtoCopy == JNI_TRUE)
(*env)->ReleaseStringUTFChars(env, proto, cproto);
}
- return proxy;
+ return proxyArray;
}
--- a/jdk/src/java.base/windows/native/libnet/DefaultProxySelector.c Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.base/windows/native/libnet/DefaultProxySelector.c Thu Feb 02 21:55:34 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2017, 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
@@ -24,26 +24,24 @@
*/
#include <windows.h>
+#include <Winhttp.h>
+
#include "jni.h"
#include "jni_util.h"
#include "jvm.h"
-#include "jlong.h"
+
+#include "proxy_util.h"
+
#include "sun_net_spi_DefaultProxySelector.h"
-/**
+/*
* These functions are used by the sun.net.spi.DefaultProxySelector class
* to access some platform specific settings.
- * This is the Windows code using the registry settings.
+ * On Windows use WinHTTP functions to get the system settings.
*/
-static jclass proxy_class;
-static jclass isaddr_class;
-static jclass ptype_class;
-static jmethodID isaddr_createUnresolvedID;
-static jmethodID proxy_ctrID;
-static jfieldID pr_no_proxyID;
-static jfieldID ptype_httpID;
-static jfieldID ptype_socksID;
+/* Keep one static session for all requests. */
+static HINTERNET session = NULL;
/*
* Class: sun_net_spi_DefaultProxySelector
@@ -52,233 +50,327 @@
*/
JNIEXPORT jboolean JNICALL
Java_sun_net_spi_DefaultProxySelector_init(JNIEnv *env, jclass clazz) {
- HKEY hKey;
- LONG ret;
- jclass cls;
+
+ /*
+ * Get one WinHTTP session handle to initialize the WinHTTP internal data
+ * structures. Keep and use only this one for the whole life time.
+ */
+ session = WinHttpOpen(L"Only used internal", /* we need no real agent string here */
+ WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
+ WINHTTP_NO_PROXY_NAME,
+ WINHTTP_NO_PROXY_BYPASS,
+ 0);
+ if (session == NULL) {
+ return JNI_FALSE;
+ }
+
+ if (!initJavaClass(env)) {
+ return JNI_FALSE;
+ }
+
+ return JNI_TRUE;
+}
- /**
- * Get all the method & field IDs for later use.
- */
- cls = (*env)->FindClass(env,"java/net/Proxy");
- CHECK_NULL_RETURN(cls, JNI_FALSE);
- proxy_class = (*env)->NewGlobalRef(env, cls);
- CHECK_NULL_RETURN(proxy_class, JNI_FALSE);
- cls = (*env)->FindClass(env,"java/net/Proxy$Type");
- CHECK_NULL_RETURN(cls, JNI_FALSE);
- ptype_class = (*env)->NewGlobalRef(env, cls);
- CHECK_NULL_RETURN(ptype_class, JNI_FALSE);
- cls = (*env)->FindClass(env, "java/net/InetSocketAddress");
- CHECK_NULL_RETURN(cls, JNI_FALSE);
- isaddr_class = (*env)->NewGlobalRef(env, cls);
- CHECK_NULL_RETURN(isaddr_class, JNI_FALSE);
- proxy_ctrID = (*env)->GetMethodID(env, proxy_class, "<init>",
- "(Ljava/net/Proxy$Type;Ljava/net/SocketAddress;)V");
- CHECK_NULL_RETURN(proxy_ctrID, JNI_FALSE);
- pr_no_proxyID = (*env)->GetStaticFieldID(env, proxy_class, "NO_PROXY", "Ljava/net/Proxy;");
- CHECK_NULL_RETURN(pr_no_proxyID, JNI_FALSE);
- ptype_httpID = (*env)->GetStaticFieldID(env, ptype_class, "HTTP", "Ljava/net/Proxy$Type;");
- CHECK_NULL_RETURN(ptype_httpID, JNI_FALSE);
- ptype_socksID = (*env)->GetStaticFieldID(env, ptype_class, "SOCKS", "Ljava/net/Proxy$Type;");
- CHECK_NULL_RETURN(ptype_socksID, JNI_FALSE);
- isaddr_createUnresolvedID = (*env)->GetStaticMethodID(env, isaddr_class, "createUnresolved",
- "(Ljava/lang/String;I)Ljava/net/InetSocketAddress;");
- CHECK_NULL_RETURN(isaddr_createUnresolvedID, JNI_FALSE);
+
+#define MAX_STR_LEN 1024
+
+/* A linked list element for a proxy */
+typedef struct list_item {
+ wchar_t *host;
+ int port;
+ struct list_item *next;
+} list_item;
- /**
- * Let's see if we can find the proper Registry entry.
- */
- ret = RegOpenKeyEx(HKEY_CURRENT_USER,
- "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
- 0, KEY_READ, (PHKEY)&hKey);
- if (ret == ERROR_SUCCESS) {
- RegCloseKey(hKey);
- /**
- * It worked, we can probably rely on it then.
- */
- return JNI_TRUE;
- }
-
- return JNI_FALSE;
+/* Free the linked list */
+static void freeList(list_item *head) {
+ list_item *next = NULL;
+ list_item *current = head;
+ while (current != NULL) {
+ next = current->next;
+ free(current->host);
+ free(current);
+ current = next;
+ }
}
-#define MAX_STR_LEN 1024
+
+/*
+ * Creates a linked list of list_item elements that has to be freed later on.
+ * Returns the size of the array as int.
+ */
+static int createProxyList(LPWSTR win_proxy, const WCHAR *pproto, list_item **head) {
+ static const wchar_t separators[] = L"\t\r\n ;";
+ list_item *current = NULL;
+ int nr_elems = 0;
+ wchar_t *context = NULL;
+ wchar_t *current_proxy = NULL;
+ BOOL error = FALSE;
+
+ /*
+ * The proxy server list contains one or more of the following strings
+ * separated by semicolons or whitespace:
+ * ([<scheme>=][<scheme>"://"]<server>[":"<port>])
+ */
+ current_proxy = wcstok_s(win_proxy, separators, &context);
+ while (current_proxy != NULL) {
+ LPWSTR pport;
+ LPWSTR phost;
+ int portVal = 0;
+ wchar_t *next_proxy = NULL;
+ list_item *proxy = NULL;
+ wchar_t* pos = NULL;
+
+ /* Filter based on the scheme, if there is one */
+ pos = wcschr(current_proxy, L'=');
+ if (pos) {
+ *pos = L'\0';
+ if (wcscmp(current_proxy, pproto) != 0) {
+ current_proxy = wcstok_s(NULL, separators, &context);
+ continue;
+ }
+ current_proxy = pos + 1;
+ }
+
+ /* Let's check for a scheme and ignore it. */
+ if ((phost = wcsstr(current_proxy, L"://")) != NULL) {
+ phost += 3;
+ } else {
+ phost = current_proxy;
+ }
+
+ /* Get the port */
+ pport = wcschr(phost, L':');
+ if (pport != NULL) {
+ *pport = 0;
+ pport++;
+ swscanf(pport, L"%d", &portVal);
+ }
+
+ proxy = (list_item *)malloc(sizeof(list_item));
+ if (proxy != NULL) {
+ proxy->next = NULL;
+ proxy->port = portVal;
+ proxy->host = _wcsdup(phost);
+
+ if (proxy->host != NULL) {
+ if (*head == NULL) {
+ *head = proxy; /* first elem */
+ }
+ if (current != NULL) {
+ current->next = proxy;
+ }
+ current = proxy;
+ nr_elems++;
+ } else {
+ free(proxy); /* cleanup */
+ }
+ }
+ /* goto next proxy if available... */
+ current_proxy = wcstok_s(NULL, separators, &context);
+ }
+ return nr_elems;
+}
+
+
/*
* Class: sun_net_spi_DefaultProxySelector
- * Method: getSystemProxy
- * Signature: ([Ljava/lang/String;Ljava/lang/String;)Ljava/net/Proxy;
+ * Method: getSystemProxies
+ * Signature: ([Ljava/lang/String;Ljava/lang/String;)[Ljava/net/Proxy;
*/
-JNIEXPORT jobject JNICALL
-Java_sun_net_spi_DefaultProxySelector_getSystemProxy(JNIEnv *env,
- jobject this,
- jstring proto,
- jstring host)
+JNIEXPORT jobjectArray JNICALL
+Java_sun_net_spi_DefaultProxySelector_getSystemProxies(JNIEnv *env,
+ jobject this,
+ jstring proto,
+ jstring host)
{
- jobject isa = NULL;
- jobject proxy = NULL;
- jobject type_proxy = NULL;
- jobject no_proxy = NULL;
- jboolean isCopy;
- HKEY hKey;
- LONG ret;
- const char* cproto;
- const char* urlhost;
- char pproto[MAX_STR_LEN];
- char regserver[MAX_STR_LEN];
- char override[MAX_STR_LEN];
- char *s, *s2;
- char *ctx = NULL;
- int pport = 0;
- int defport = 0;
- char *phost;
+ jobjectArray proxy_array = NULL;
+ jobject type_proxy = NULL;
+ LPCWSTR lpProto;
+ LPCWSTR lpHost;
+ list_item *head = NULL;
+
+ BOOL use_auto_proxy = FALSE;
+ WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ie_proxy_config;
+ WINHTTP_AUTOPROXY_OPTIONS auto_proxy_options;
+ WINHTTP_PROXY_INFO proxy_info;
+ LPWSTR win_proxy = NULL;
+ LPWSTR win_bypass_proxy = NULL;
+
+ memset(&ie_proxy_config, 0, sizeof(WINHTTP_CURRENT_USER_IE_PROXY_CONFIG));
+ memset(&auto_proxy_options, 0, sizeof(WINHTTP_AUTOPROXY_OPTIONS));
+ memset(&proxy_info, 0, sizeof(WINHTTP_PROXY_INFO));
+
+ lpHost = (*env)->GetStringChars(env, host, NULL);
+ if (lpHost == NULL) {
+ if (!(*env)->ExceptionCheck(env))
+ JNU_ThrowOutOfMemoryError(env, NULL);
+ return NULL;
+ }
- /**
- * Let's open the Registry entry. We'll check a few values in it:
- *
- * - ProxyEnable: 0 means no proxy, 1 means use the proxy
- * - ProxyServer: a string that can take 2 forms:
- * "server[:port]"
- * or
- * "protocol1=server[:port][;protocol2=server[:port]]..."
- * - ProxyOverride: a string containing a list of prefixes for hostnames.
- * e.g.: hoth;localhost;<local>
- */
- ret = RegOpenKeyEx(HKEY_CURRENT_USER,
- "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings",
- 0, KEY_READ, (PHKEY)&hKey);
- if (ret == ERROR_SUCCESS) {
- DWORD dwLen;
- DWORD dwProxyEnabled;
- ULONG ulType;
- dwLen = sizeof(dwProxyEnabled);
+ lpProto = (*env)->GetStringChars(env, proto, NULL);
+ if (lpProto == NULL) {
+ (*env)->ReleaseStringChars(env, host, lpHost);
+ if (!(*env)->ExceptionCheck(env))
+ JNU_ThrowOutOfMemoryError(env, NULL);
+ return NULL;
+ }
+
+ if (WinHttpGetIEProxyConfigForCurrentUser(&ie_proxy_config) == FALSE) {
+ /* cleanup and exit */
+ (*env)->ReleaseStringChars(env, host, lpHost);
+ (*env)->ReleaseStringChars(env, proto, lpProto);
+ return NULL;
+ }
+
+ if (ie_proxy_config.fAutoDetect) {
+ /* Windows uses WPAD */
+ auto_proxy_options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP |
+ WINHTTP_AUTO_DETECT_TYPE_DNS_A;
+ auto_proxy_options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT;
+ auto_proxy_options.fAutoLogonIfChallenged = TRUE;
+ use_auto_proxy = TRUE;
+ } else if (ie_proxy_config.lpszAutoConfigUrl != NULL) {
+ /* Windows uses PAC file */
+ auto_proxy_options.lpszAutoConfigUrl = ie_proxy_config.lpszAutoConfigUrl;
+ auto_proxy_options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL;
+ use_auto_proxy = TRUE;
+ } else if (ie_proxy_config.lpszProxy != NULL) {
+ /* Windows uses manually entered proxy. */
+ use_auto_proxy = FALSE;
+ win_bypass_proxy = ie_proxy_config.lpszProxyBypass;
+ win_proxy = ie_proxy_config.lpszProxy;
+ }
- /**
- * Let's see if the proxy settings are to be used.
- */
- ret = RegQueryValueEx(hKey, "ProxyEnable", NULL, &ulType,
- (LPBYTE)&dwProxyEnabled, &dwLen);
- if ((ret == ERROR_SUCCESS) && (dwProxyEnabled > 0)) {
- /*
- * Yes, ProxyEnable == 1
- */
- dwLen = sizeof(override);
- override[0] = 0;
- ret = RegQueryValueEx(hKey, "ProxyOverride", NULL, &ulType,
- (LPBYTE)&override, &dwLen);
- dwLen = sizeof(regserver);
- regserver[0] = 0;
- ret = RegQueryValueEx(hKey, "ProxyServer", NULL, &ulType,
- (LPBYTE)®server, &dwLen);
- RegCloseKey(hKey);
- if (ret == ERROR_SUCCESS) {
- if (strlen(override) > 0) {
- /**
- * we did get ProxyServer and may have an override.
- * So let's check the override list first, by walking down the list
- * The semicolons (;) separated entries have to be matched with the
- * the beginning of the hostname.
- */
- s = strtok_s(override, "; ", &ctx);
- urlhost = (*env)->GetStringUTFChars(env, host, &isCopy);
- if (urlhost == NULL) {
- if (!(*env)->ExceptionCheck(env))
- JNU_ThrowOutOfMemoryError(env, NULL);
- return NULL;
- }
- while (s != NULL) {
- if (strncmp(s, urlhost, strlen(s)) == 0) {
- /**
- * the URL host name matches with one of the prefixes,
- * therefore we have to use a direct connection.
- */
- if (isCopy == JNI_TRUE)
- (*env)->ReleaseStringUTFChars(env, host, urlhost);
- goto noproxy;
+ if (use_auto_proxy) {
+ WCHAR url[MAX_STR_LEN];
+ /* Create url for WinHttpGetProxyForUrl */
+ _snwprintf(url, sizeof(url) - 1, L"%s://%s", lpProto, lpHost);
+ /* Get proxy for URL from Windows */
+ use_auto_proxy = WinHttpGetProxyForUrl(session, &url[0], &auto_proxy_options, &proxy_info);
+ if (use_auto_proxy) {
+ win_proxy = proxy_info.lpszProxy;
+ win_bypass_proxy = proxy_info.lpszProxyBypass;
+ }
+ }
+
+ /* Check the bypass entry. */
+ if (NULL != win_bypass_proxy) {
+ /*
+ * From MSDN:
+ * The proxy bypass list contains one or more server names separated by
+ * semicolons or whitespace. The proxy bypass list can also contain the
+ * string "<local>" to indicate that all local intranet sites are
+ * bypassed. Local intranet sites are considered to be all servers that
+ * do not contain a period in their name.
+ */
+ wchar_t *context = NULL;
+ LPWSTR s = wcstok_s(win_bypass_proxy, L"; ", &context);
+
+ while (s != NULL) {
+ size_t maxlen = wcslen(s);
+ if (wcsncmp(s, lpHost, maxlen) == 0) {
+ /*
+ * The URL host name matches with one of the prefixes, use a
+ * direct connection.
+ */
+ goto noproxy;
}
- s = strtok_s(NULL, "; ", &ctx);
- }
- if (isCopy == JNI_TRUE)
- (*env)->ReleaseStringUTFChars(env, host, urlhost);
+ if (wcsncmp(s, L"<local>", maxlen) == 0) {
+ /*
+ * All local intranet sites are bypassed - Microsoft consider all
+ * servers that do not contain a period in their name to be local.
+ */
+ if (wcschr(lpHost, '.') == NULL) {
+ goto noproxy;
+ }
+ }
+ s = wcstok_s(NULL, L"; ", &context);
+ }
+ }
+
+ if (win_proxy != NULL) {
+ wchar_t *context = NULL;
+ int defport = 0;
+ int nr_elems = 0;
+
+ /* Set the default port value & proxy type from protocol. */
+ if ((wcscmp(lpProto, L"http") == 0) ||
+ (wcscmp(lpProto, L"ftp") == 0) ||
+ (wcscmp(lpProto, L"gopher") == 0))
+ defport = 80;
+ if (wcscmp(lpProto, L"https") == 0)
+ defport = 443;
+ if (wcscmp(lpProto, L"socks") == 0) {
+ defport = 1080;
+ type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_socksID);
+ } else {
+ type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID);
+ }
+ if (type_proxy == NULL || (*env)->ExceptionCheck(env)) {
+ goto noproxy;
}
- cproto = (*env)->GetStringUTFChars(env, proto, &isCopy);
- if (cproto == NULL) {
- if (!(*env)->ExceptionCheck(env))
- JNU_ThrowOutOfMemoryError(env, NULL);
- return NULL;
- }
-
- /*
- * Set default port value & proxy type from protocol.
- */
- if ((strcmp(cproto, "http") == 0) ||
- (strcmp(cproto, "ftp") == 0) ||
- (strcmp(cproto, "gopher") == 0))
- defport = 80;
- if (strcmp(cproto, "https") == 0)
- defport = 443;
- if (strcmp(cproto, "socks") == 0) {
- defport = 1080;
- type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_socksID);
- } else {
- type_proxy = (*env)->GetStaticObjectField(env, ptype_class, ptype_httpID);
- }
+ nr_elems = createProxyList(win_proxy, lpProto, &head);
+ if (nr_elems != 0 && head != NULL) {
+ int index = 0;
+ proxy_array = (*env)->NewObjectArray(env, nr_elems, proxy_class, NULL);
+ if (proxy_array == NULL || (*env)->ExceptionCheck(env)) {
+ goto noproxy;
+ }
+ while (head != NULL && index < nr_elems) {
+ jstring jhost;
+ jobject isa;
+ jobject proxy;
- sprintf(pproto,"%s=", cproto);
- if (isCopy == JNI_TRUE)
- (*env)->ReleaseStringUTFChars(env, proto, cproto);
- /**
- * Let's check the protocol specific form first.
- */
- if ((s = strstr(regserver, pproto)) != NULL) {
- s += strlen(pproto);
- } else {
- /**
- * If we couldn't find *this* protocol but the string is in the
- * protocol specific format, then don't use proxy
- */
- if (strchr(regserver, '=') != NULL)
- goto noproxy;
- s = regserver;
+ if (head->host != NULL && proxy_array != NULL) {
+ /* Let's create the appropriate Proxy object then. */
+ if (head->port == 0) {
+ head->port = defport;
+ }
+ jhost = (*env)->NewString(env, head->host, (jsize)wcslen(head->host));
+ if (jhost == NULL || (*env)->ExceptionCheck(env)) {
+ proxy_array = NULL;
+ }
+ isa = (*env)->CallStaticObjectMethod(env, isaddr_class,
+ isaddr_createUnresolvedID, jhost,
+ head->port);
+ if (isa == NULL || (*env)->ExceptionCheck(env)) {
+ proxy_array = NULL;
+ }
+ proxy = (*env)->NewObject(env, proxy_class, proxy_ctrID, type_proxy, isa);
+ if (proxy == NULL || (*env)->ExceptionCheck(env)) {
+ proxy_array = NULL;
+ }
+ (*env)->SetObjectArrayElement(env, proxy_array, index, proxy);
+ if ((*env)->ExceptionCheck(env)) {
+ proxy_array = NULL;
+ }
+ index++;
+ }
+ head = head->next;
+ }
}
- s2 = strchr(s, ';');
- if (s2 != NULL)
- *s2 = 0;
-
- /**
- * Is there a port specified?
- */
- s2 = strchr(s, ':');
- if (s2 != NULL) {
- *s2 = 0;
- s2++;
- sscanf(s2, "%d", &pport);
- }
- phost = s;
-
- if (phost != NULL) {
- /**
- * Let's create the appropriate Proxy object then.
- */
- jstring jhost;
- if (pport == 0)
- pport = defport;
- jhost = (*env)->NewStringUTF(env, phost);
- CHECK_NULL_RETURN(jhost, NULL);
- isa = (*env)->CallStaticObjectMethod(env, isaddr_class, isaddr_createUnresolvedID, jhost, pport);
- CHECK_NULL_RETURN(isa, NULL);
- proxy = (*env)->NewObject(env, proxy_class, proxy_ctrID, type_proxy, isa);
- return proxy;
- }
- }
- } else {
- /* ProxyEnable == 0 or Query failed */
- /* close the handle to the registry key */
- RegCloseKey(hKey);
}
- }
noproxy:
- no_proxy = (*env)->GetStaticObjectField(env, proxy_class, pr_no_proxyID);
- return no_proxy;
+ if (head != NULL) {
+ freeList(head);
+ }
+ if (proxy_info.lpszProxy != NULL)
+ GlobalFree(proxy_info.lpszProxy);
+ if (proxy_info.lpszProxyBypass != NULL)
+ GlobalFree(proxy_info.lpszProxyBypass);
+ if (ie_proxy_config.lpszAutoConfigUrl != NULL)
+ GlobalFree(ie_proxy_config.lpszAutoConfigUrl);
+ if (ie_proxy_config.lpszProxy != NULL)
+ GlobalFree(ie_proxy_config.lpszProxy);
+ if (ie_proxy_config.lpszProxyBypass != NULL)
+ GlobalFree(ie_proxy_config.lpszProxyBypass);
+ if (lpHost != NULL)
+ (*env)->ReleaseStringChars(env, host, lpHost);
+ if (lpProto != NULL)
+ (*env)->ReleaseStringChars(env, proto, lpProto);
+
+ return proxy_array;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management.rmi/share/classes/com/sun/jmx/remote/internal/rmi/ProxyRef.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.jmx.remote.internal.rmi;
+
+import java.io.IOException;
+import java.io.ObjectInput;
+import java.io.ObjectOutput;
+import java.lang.reflect.Method;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.server.RemoteObject;
+import java.rmi.server.RemoteRef;
+
+
+@SuppressWarnings("deprecation")
+public class ProxyRef implements RemoteRef {
+ private static final long serialVersionUID = -6503061366316814723L;
+
+ public ProxyRef(RemoteRef ref) {
+ this.ref = ref;
+ }
+
+ public void readExternal(ObjectInput in)
+ throws IOException, ClassNotFoundException {
+ ref.readExternal(in);
+ }
+
+ public void writeExternal(ObjectOutput out) throws IOException {
+ ref.writeExternal(out);
+ }
+
+ /**
+ * @deprecated
+ */
+ @Deprecated
+ public void invoke(java.rmi.server.RemoteCall call) throws Exception {
+ ref.invoke(call);
+ }
+
+ public Object invoke(Remote obj, Method method, Object[] params,
+ long opnum) throws Exception {
+ return ref.invoke(obj, method, params, opnum);
+ }
+
+ /**
+ * @deprecated
+ */
+ @Deprecated
+ public void done(java.rmi.server.RemoteCall call) throws RemoteException {
+ ref.done(call);
+ }
+
+ public String getRefClass(ObjectOutput out) {
+ return ref.getRefClass(out);
+ }
+
+ /**
+ * @deprecated
+ */
+ @Deprecated
+ public java.rmi.server.RemoteCall newCall(RemoteObject obj,
+ java.rmi.server.Operation[] op, int opnum,
+ long hash) throws RemoteException {
+ return ref.newCall(obj, op, opnum, hash);
+ }
+
+ public boolean remoteEquals(RemoteRef obj) {
+ return ref.remoteEquals(obj);
+ }
+
+ public int remoteHashCode() {
+ return ref.remoteHashCode();
+ }
+
+ public String remoteToString() {
+ return ref.remoteToString();
+ }
+
+ protected RemoteRef ref;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management.rmi/share/classes/com/sun/jmx/remote/internal/rmi/RMIExporter.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2003, 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.jmx.remote.internal.rmi;
+
+import java.rmi.NoSuchObjectException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+import java.rmi.server.UnicastRemoteObject;
+
+/**
+ * <p>Unpublished interface controlling how the RMI Connector Server
+ * exports objects. The RMIServerImpl object and each
+ * RMIConnectionImpl object are exported using the exporter. The
+ * default exporter calls {@link
+ * UnicastRemoteObject#exportObject(Remote, int,
+ * RMIClientSocketFactory, RMIServerSocketFactory)} to export objects
+ * and {@link UnicastRemoteObject#unexportObject(Remote, boolean)} to
+ * unexport them. A replacement exporter can be specified via the
+ * {@link #EXPORTER_ATTRIBUTE} property in the environment Map passed
+ * to the RMI connector server.</p>
+ */
+public interface RMIExporter {
+ public static final String EXPORTER_ATTRIBUTE =
+ "com.sun.jmx.remote.rmi.exporter";
+
+ public Remote exportObject(Remote obj,
+ int port,
+ RMIClientSocketFactory csf,
+ RMIServerSocketFactory ssf)
+ throws RemoteException;
+
+ public boolean unexportObject(Remote obj, boolean force)
+ throws NoSuchObjectException;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management.rmi/share/classes/com/sun/jmx/remote/protocol/rmi/ClientProvider.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2002, 2004, 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.jmx.remote.protocol.rmi;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import javax.management.remote.JMXConnectorProvider;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.rmi.RMIConnector;
+
+public class ClientProvider implements JMXConnectorProvider {
+
+ public JMXConnector newJMXConnector(JMXServiceURL serviceURL,
+ Map<String,?> environment)
+ throws IOException {
+ if (!serviceURL.getProtocol().equals("rmi")) {
+ throw new MalformedURLException("Protocol not rmi: " +
+ serviceURL.getProtocol());
+ }
+ return new RMIConnector(serviceURL, environment);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management.rmi/share/classes/com/sun/jmx/remote/protocol/rmi/ServerProvider.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2003, 2004, 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.jmx.remote.protocol.rmi;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.util.Map;
+
+import javax.management.MBeanServer;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerProvider;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.rmi.RMIConnectorServer;
+
+public class ServerProvider implements JMXConnectorServerProvider {
+
+ public JMXConnectorServer newJMXConnectorServer(JMXServiceURL serviceURL,
+ Map<String,?> environment,
+ MBeanServer mbeanServer)
+ throws IOException {
+ if (!serviceURL.getProtocol().equals("rmi")) {
+ throw new MalformedURLException("Protocol not rmi: " +
+ serviceURL.getProtocol());
+ }
+ return new RMIConnectorServer(serviceURL, environment, mbeanServer);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/NoCallStackClassLoader.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,296 @@
+/*
+ * 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 javax.management.remote.rmi;
+
+import java.security.ProtectionDomain;
+
+/**
+ <p>A class loader that only knows how to define a limited number
+ of classes, and load a limited number of other classes through
+ delegation to another loader. It is used to get around a problem
+ with Serialization, in particular as used by RMI. The JMX Remote API
+ defines exactly what class loader must be used to deserialize arguments on
+ the server, and return values on the client. We communicate this class
+ loader to RMI by setting it as the context class loader. RMI uses the
+ context class loader to load classes as it deserializes, which is what we
+ want. However, before consulting the context class loader, it
+ looks up the call stack for a class with a non-null class loader,
+ and uses that if it finds one. So, in the standalone version of
+ javax.management.remote, if the class you're looking for is known
+ to the loader of jmxremote.jar (typically the system class loader)
+ then that loader will load it. This contradicts the class-loading
+ semantics required.
+
+ <p>We get around the problem by ensuring that the search up the
+ call stack will find a non-null class loader that doesn't load any
+ classes of interest, namely this one. So even though this loader
+ is indeed consulted during deserialization, it never finds the
+ class being deserialized. RMI then proceeds to use the context
+ class loader, as we require.
+
+ <p>This loader is constructed with the name and byte-code of one
+ or more classes that it defines, and a class-loader to which it
+ will delegate certain other classes required by that byte-code.
+ We construct the byte-code somewhat painstakingly, by compiling
+ the Java code directly, converting into a string, copying that
+ string into the class that needs this loader, and using the
+ stringToBytes method to convert it into the byte array. We
+ compile with -g:none because there's not much point in having
+ line-number information and the like in these directly-encoded
+ classes.
+
+ <p>The referencedClassNames should contain the names of all
+ classes that are referenced by the classes defined by this loader.
+ It is not necessary to include standard J2SE classes, however.
+ Here, a class is referenced if it is the superclass or a
+ superinterface of a defined class, or if it is the type of a
+ field, parameter, or return value. A class is not referenced if
+ it only appears in the throws clause of a method or constructor.
+ Of course, referencedClassNames should not contain any classes
+ that the user might want to deserialize, because the whole point
+ of this loader is that it does not find such classes.
+*/
+
+class NoCallStackClassLoader extends ClassLoader {
+ /** Simplified constructor when this loader only defines one class. */
+ public NoCallStackClassLoader(String className,
+ byte[] byteCode,
+ String[] referencedClassNames,
+ ClassLoader referencedClassLoader,
+ ProtectionDomain protectionDomain) {
+ this(new String[] {className}, new byte[][] {byteCode},
+ referencedClassNames, referencedClassLoader, protectionDomain);
+ }
+
+ public NoCallStackClassLoader(String[] classNames,
+ byte[][] byteCodes,
+ String[] referencedClassNames,
+ ClassLoader referencedClassLoader,
+ ProtectionDomain protectionDomain) {
+ super(null);
+
+ /* Validation. */
+ if (classNames == null || classNames.length == 0
+ || byteCodes == null || classNames.length != byteCodes.length
+ || referencedClassNames == null || protectionDomain == null)
+ throw new IllegalArgumentException();
+ for (int i = 0; i < classNames.length; i++) {
+ if (classNames[i] == null || byteCodes[i] == null)
+ throw new IllegalArgumentException();
+ }
+ for (int i = 0; i < referencedClassNames.length; i++) {
+ if (referencedClassNames[i] == null)
+ throw new IllegalArgumentException();
+ }
+
+ this.classNames = classNames;
+ this.byteCodes = byteCodes;
+ this.referencedClassNames = referencedClassNames;
+ this.referencedClassLoader = referencedClassLoader;
+ this.protectionDomain = protectionDomain;
+ }
+
+ /* This method is called at most once per name. Define the name
+ * if it is one of the classes whose byte code we have, or
+ * delegate the load if it is one of the referenced classes.
+ */
+ @Override
+ protected Class<?> findClass(String name) throws ClassNotFoundException {
+ // Note: classNames is guaranteed by the constructor to be non-null.
+ for (int i = 0; i < classNames.length; i++) {
+ if (name.equals(classNames[i])) {
+ return defineClass(classNames[i], byteCodes[i], 0,
+ byteCodes[i].length, protectionDomain);
+ }
+ }
+
+ /* If the referencedClassLoader is null, it is the bootstrap
+ * class loader, and there's no point in delegating to it
+ * because it's already our parent class loader.
+ */
+ if (referencedClassLoader != null) {
+ for (int i = 0; i < referencedClassNames.length; i++) {
+ if (name.equals(referencedClassNames[i]))
+ return referencedClassLoader.loadClass(name);
+ }
+ }
+
+ throw new ClassNotFoundException(name);
+ }
+
+ private final String[] classNames;
+ private final byte[][] byteCodes;
+ private final String[] referencedClassNames;
+ private final ClassLoader referencedClassLoader;
+ private final ProtectionDomain protectionDomain;
+
+ /**
+ * <p>Construct a <code>byte[]</code> using the characters of the
+ * given <code>String</code>. Only the low-order byte of each
+ * character is used. This method is useful to reduce the
+ * footprint of classes that include big byte arrays (e.g. the
+ * byte code of other classes), because a string takes up much
+ * less space in a class file than the byte code to initialize a
+ * <code>byte[]</code> with the same number of bytes.</p>
+ *
+ * <p>We use just one byte per character even though characters
+ * contain two bytes. The resultant output length is much the
+ * same: using one byte per character is shorter because it has
+ * more characters in the optimal 1-127 range but longer because
+ * it has more zero bytes (which are frequent, and are encoded as
+ * two bytes in classfile UTF-8). But one byte per character has
+ * two key advantages: (1) you can see the string constants, which
+ * is reassuring, (2) you don't need to know whether the class
+ * file length is odd.</p>
+ *
+ * <p>This method differs from {@link String#getBytes()} in that
+ * it does not use any encoding. So it is guaranteed that each
+ * byte of the result is numerically identical (mod 256) to the
+ * corresponding character of the input.
+ */
+ public static byte[] stringToBytes(String s) {
+ final int slen = s.length();
+ byte[] bytes = new byte[slen];
+ for (int i = 0; i < slen; i++)
+ bytes[i] = (byte) s.charAt(i);
+ return bytes;
+ }
+}
+
+/*
+
+You can use the following Emacs function to convert class files into
+strings to be used by the stringToBytes method above. Select the
+whole (defun...) with the mouse and type M-x eval-region, or save it
+to a file and do M-x load-file. Then visit the *.class file and do
+M-x class-string.
+
+;; class-string.el
+;; visit the *.class file with emacs, then invoke this function
+
+(defun class-string ()
+ "Construct a Java string whose bytes are the same as the current
+buffer. The resultant string is put in a buffer called *string*,
+possibly with a numeric suffix like <2>. From there it can be
+insert-buffer'd into a Java program."
+ (interactive)
+ (let* ((s (buffer-string))
+ (slen (length s))
+ (i 0)
+ (buf (generate-new-buffer "*string*")))
+ (set-buffer buf)
+ (insert "\"")
+ (while (< i slen)
+ (if (> (current-column) 61)
+ (insert "\"+\n\""))
+ (let ((c (aref s i)))
+ (insert (cond
+ ((> c 126) (format "\\%o" c))
+ ((= c ?\") "\\\"")
+ ((= c ?\\) "\\\\")
+ ((< c 33)
+ (let ((nextc (if (< (1+ i) slen)
+ (aref s (1+ i))
+ ?\0)))
+ (cond
+ ((and (<= nextc ?7) (>= nextc ?0))
+ (format "\\%03o" c))
+ (t
+ (format "\\%o" c)))))
+ (t c))))
+ (setq i (1+ i)))
+ (insert "\"")
+ (switch-to-buffer buf)))
+
+Alternatively, the following class reads a class file and outputs a string
+that can be used by the stringToBytes method above.
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+public class BytesToString {
+
+ public static void main(String[] args) throws IOException {
+ File f = new File(args[0]);
+ int len = (int)f.length();
+ byte[] classBytes = new byte[len];
+
+ FileInputStream in = new FileInputStream(args[0]);
+ try {
+ int pos = 0;
+ for (;;) {
+ int n = in.read(classBytes, pos, (len-pos));
+ if (n < 0)
+ throw new RuntimeException("class file changed??");
+ pos += n;
+ if (pos >= n)
+ break;
+ }
+ } finally {
+ in.close();
+ }
+
+ int pos = 0;
+ boolean lastWasOctal = false;
+ for (int i=0; i<len; i++) {
+ int value = classBytes[i];
+ if (value < 0)
+ value += 256;
+ String s = null;
+ if (value == '\\')
+ s = "\\\\";
+ else if (value == '\"')
+ s = "\\\"";
+ else {
+ if ((value >= 32 && value < 127) && ((!lastWasOctal ||
+ (value < '0' || value > '7')))) {
+ s = Character.toString((char)value);
+ }
+ }
+ if (s == null) {
+ s = "\\" + Integer.toString(value, 8);
+ lastWasOctal = true;
+ } else {
+ lastWasOctal = false;
+ }
+ if (pos > 61) {
+ System.out.print("\"");
+ if (i<len)
+ System.out.print("+");
+ System.out.println();
+ pos = 0;
+ }
+ if (pos == 0)
+ System.out.print(" \"");
+ System.out.print(s);
+ pos += s.length();
+ }
+ System.out.println("\"");
+ }
+}
+
+*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnection.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,1092 @@
+/*
+ * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.management.remote.rmi;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.rmi.MarshalledObject;
+import java.rmi.Remote;
+import java.util.Set;
+
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.IntrospectionException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServerConnection;
+import javax.management.NotCompliantMBeanException;
+
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.RuntimeMBeanException;
+import javax.management.RuntimeOperationsException;
+import javax.management.remote.NotificationResult;
+import javax.security.auth.Subject;
+
+/**
+ * <p>RMI object used to forward an MBeanServer request from a client
+ * to its MBeanServer implementation on the server side. There is one
+ * Remote object implementing this interface for each remote client
+ * connected to an RMI connector.</p>
+ *
+ * <p>User code does not usually refer to this interface. It is
+ * specified as part of the public API so that different
+ * implementations of that API will interoperate.</p>
+ *
+ * <p>To ensure that client parameters will be deserialized at the
+ * server side with the correct classloader, client parameters such as
+ * parameters used to invoke a method are wrapped in a {@link
+ * MarshalledObject}. An implementation of this interface must first
+ * get the appropriate class loader for the operation and its target,
+ * then deserialize the marshalled parameters with this classloader.
+ * Except as noted, a parameter that is a
+ * <code>MarshalledObject</code> or <code>MarshalledObject[]</code>
+ * must not be null; the behavior is unspecified if it is.</p>
+ *
+ * <p>Class loading aspects are detailed in the
+ * <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
+ * JMX Specification, version 1.4</a> PDF document.</p>
+ *
+ * <p>Most methods in this interface parallel methods in the {@link
+ * MBeanServerConnection} interface. Where an aspect of the behavior
+ * of a method is not specified here, it is the same as in the
+ * corresponding <code>MBeanServerConnection</code> method.
+ *
+ * @since 1.5
+ */
+/*
+ * Notice that we omit the type parameter from MarshalledObject everywhere,
+ * even though it would add useful information to the documentation. The
+ * reason is that it was only added in Mustang (Java SE 6), whereas versions
+ * 1.4 and 2.0 of the JMX API must be implementable on Tiger per our
+ * commitments for JSR 255. This is also why we suppress rawtypes warnings.
+ */
+@SuppressWarnings("rawtypes")
+public interface RMIConnection extends Closeable, Remote {
+ /**
+ * <p>Returns the connection ID. This string is different for
+ * every open connection to a given RMI connector server.</p>
+ *
+ * @return the connection ID
+ *
+ * @see RMIConnector#connect RMIConnector.connect
+ *
+ * @throws IOException if a general communication exception occurred.
+ */
+ public String getConnectionId() throws IOException;
+
+ /**
+ * <p>Closes this connection. On return from this method, the RMI
+ * object implementing this interface is unexported, so further
+ * remote calls to it will fail.</p>
+ *
+ * @throws IOException if the connection could not be closed,
+ * or the Remote object could not be unexported, or there was a
+ * communication failure when transmitting the remote close
+ * request.
+ */
+ public void close() throws IOException;
+
+ /**
+ * Handles the method {@link
+ * javax.management.MBeanServerConnection#createMBean(String,
+ * ObjectName)}.
+ *
+ * @param className The class name of the MBean to be instantiated.
+ * @param name The object name of the MBean. May be null.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return An <code>ObjectInstance</code>, containing the
+ * <code>ObjectName</code> and the Java class name of the newly
+ * instantiated MBean. If the contained <code>ObjectName</code>
+ * is <code>n</code>, the contained Java class name is
+ * <code>{@link #getMBeanInfo getMBeanInfo(n)}.getClassName()</code>.
+ *
+ * @throws ReflectionException Wraps a
+ * <code>java.lang.ClassNotFoundException</code> or a
+ * <code>java.lang.Exception</code> that occurred
+ * when trying to invoke the MBean's constructor.
+ * @throws InstanceAlreadyExistsException The MBean is already
+ * under the control of the MBean server.
+ * @throws MBeanRegistrationException The
+ * <code>preRegister</code> (<code>MBeanRegistration</code>
+ * interface) method of the MBean has thrown an exception. The
+ * MBean will not be registered.
+ * @throws MBeanException The constructor of the MBean has
+ * thrown an exception.
+ * @throws NotCompliantMBeanException This class is not a JMX
+ * compliant MBean.
+ * @throws RuntimeOperationsException Wraps a
+ * <code>java.lang.IllegalArgumentException</code>: The className
+ * passed in parameter is null, the <code>ObjectName</code> passed
+ * in parameter contains a pattern or no <code>ObjectName</code>
+ * is specified for the MBean.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ */
+ public ObjectInstance createMBean(String className,
+ ObjectName name,
+ Subject delegationSubject)
+ throws
+ ReflectionException,
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ MBeanException,
+ NotCompliantMBeanException,
+ IOException;
+
+ /**
+ * Handles the method {@link
+ * javax.management.MBeanServerConnection#createMBean(String,
+ * ObjectName, ObjectName)}.
+ *
+ * @param className The class name of the MBean to be instantiated.
+ * @param name The object name of the MBean. May be null.
+ * @param loaderName The object name of the class loader to be used.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return An <code>ObjectInstance</code>, containing the
+ * <code>ObjectName</code> and the Java class name of the newly
+ * instantiated MBean. If the contained <code>ObjectName</code>
+ * is <code>n</code>, the contained Java class name is
+ * <code>{@link #getMBeanInfo getMBeanInfo(n)}.getClassName()</code>.
+ *
+ * @throws ReflectionException Wraps a
+ * <code>java.lang.ClassNotFoundException</code> or a
+ * <code>java.lang.Exception</code> that occurred when trying to
+ * invoke the MBean's constructor.
+ * @throws InstanceAlreadyExistsException The MBean is already
+ * under the control of the MBean server.
+ * @throws MBeanRegistrationException The
+ * <code>preRegister</code> (<code>MBeanRegistration</code>
+ * interface) method of the MBean has thrown an exception. The
+ * MBean will not be registered.
+ * @throws MBeanException The constructor of the MBean has
+ * thrown an exception.
+ * @throws NotCompliantMBeanException This class is not a JMX
+ * compliant MBean.
+ * @throws InstanceNotFoundException The specified class loader
+ * is not registered in the MBean server.
+ * @throws RuntimeOperationsException Wraps a
+ * <code>java.lang.IllegalArgumentException</code>: The className
+ * passed in parameter is null, the <code>ObjectName</code> passed
+ * in parameter contains a pattern or no <code>ObjectName</code>
+ * is specified for the MBean.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ */
+ public ObjectInstance createMBean(String className,
+ ObjectName name,
+ ObjectName loaderName,
+ Subject delegationSubject)
+ throws
+ ReflectionException,
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ MBeanException,
+ NotCompliantMBeanException,
+ InstanceNotFoundException,
+ IOException;
+
+ /**
+ * Handles the method {@link
+ * javax.management.MBeanServerConnection#createMBean(String,
+ * ObjectName, Object[], String[])}. The <code>Object[]</code>
+ * parameter is wrapped in a <code>MarshalledObject</code>.
+ *
+ * @param className The class name of the MBean to be instantiated.
+ * @param name The object name of the MBean. May be null.
+ * @param params An array containing the parameters of the
+ * constructor to be invoked, encapsulated into a
+ * <code>MarshalledObject</code>. The encapsulated array can be
+ * null, equivalent to an empty array.
+ * @param signature An array containing the signature of the
+ * constructor to be invoked. Can be null, equivalent to an empty
+ * array.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return An <code>ObjectInstance</code>, containing the
+ * <code>ObjectName</code> and the Java class name of the newly
+ * instantiated MBean. If the contained <code>ObjectName</code>
+ * is <code>n</code>, the contained Java class name is
+ * <code>{@link #getMBeanInfo getMBeanInfo(n)}.getClassName()</code>.
+ *
+ * @throws ReflectionException Wraps a
+ * <code>java.lang.ClassNotFoundException</code> or a
+ * <code>java.lang.Exception</code> that occurred when trying to
+ * invoke the MBean's constructor.
+ * @throws InstanceAlreadyExistsException The MBean is already
+ * under the control of the MBean server.
+ * @throws MBeanRegistrationException The
+ * <code>preRegister</code> (<code>MBeanRegistration</code>
+ * interface) method of the MBean has thrown an exception. The
+ * MBean will not be registered.
+ * @throws MBeanException The constructor of the MBean has
+ * thrown an exception.
+ * @throws NotCompliantMBeanException This class is not a JMX
+ * compliant MBean.
+ * @throws RuntimeOperationsException Wraps a
+ * <code>java.lang.IllegalArgumentException</code>: The className
+ * passed in parameter is null, the <code>ObjectName</code> passed
+ * in parameter contains a pattern, or no <code>ObjectName</code>
+ * is specified for the MBean.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ */
+ public ObjectInstance createMBean(String className,
+ ObjectName name,
+ MarshalledObject params,
+ String signature[],
+ Subject delegationSubject)
+ throws
+ ReflectionException,
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ MBeanException,
+ NotCompliantMBeanException,
+ IOException;
+
+ /**
+ * Handles the method {@link
+ * javax.management.MBeanServerConnection#createMBean(String,
+ * ObjectName, ObjectName, Object[], String[])}. The
+ * <code>Object[]</code> parameter is wrapped in a
+ * <code>MarshalledObject</code>.
+ *
+ * @param className The class name of the MBean to be instantiated.
+ * @param name The object name of the MBean. May be null.
+ * @param loaderName The object name of the class loader to be used.
+ * @param params An array containing the parameters of the
+ * constructor to be invoked, encapsulated into a
+ * <code>MarshalledObject</code>. The encapsulated array can be
+ * null, equivalent to an empty array.
+ * @param signature An array containing the signature of the
+ * constructor to be invoked. Can be null, equivalent to an empty
+ * array.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return An <code>ObjectInstance</code>, containing the
+ * <code>ObjectName</code> and the Java class name of the newly
+ * instantiated MBean. If the contained <code>ObjectName</code>
+ * is <code>n</code>, the contained Java class name is
+ * <code>{@link #getMBeanInfo getMBeanInfo(n)}.getClassName()</code>.
+ *
+ * @throws ReflectionException Wraps a
+ * <code>java.lang.ClassNotFoundException</code> or a
+ * <code>java.lang.Exception</code> that occurred when trying to
+ * invoke the MBean's constructor.
+ * @throws InstanceAlreadyExistsException The MBean is already
+ * under the control of the MBean server.
+ * @throws MBeanRegistrationException The
+ * <code>preRegister</code> (<code>MBeanRegistration</code>
+ * interface) method of the MBean has thrown an exception. The
+ * MBean will not be registered.
+ * @throws MBeanException The constructor of the MBean has
+ * thrown an exception.
+ * @throws NotCompliantMBeanException This class is not a JMX
+ * compliant MBean.
+ * @throws InstanceNotFoundException The specified class loader
+ * is not registered in the MBean server.
+ * @throws RuntimeOperationsException Wraps a
+ * <code>java.lang.IllegalArgumentException</code>: The className
+ * passed in parameter is null, the <code>ObjectName</code> passed
+ * in parameter contains a pattern, or no <code>ObjectName</code>
+ * is specified for the MBean.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ */
+ public ObjectInstance createMBean(String className,
+ ObjectName name,
+ ObjectName loaderName,
+ MarshalledObject params,
+ String signature[],
+ Subject delegationSubject)
+ throws
+ ReflectionException,
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ MBeanException,
+ NotCompliantMBeanException,
+ InstanceNotFoundException,
+ IOException;
+
+ /**
+ * Handles the method
+ * {@link javax.management.MBeanServerConnection#unregisterMBean(ObjectName)}.
+ *
+ * @param name The object name of the MBean to be unregistered.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @throws InstanceNotFoundException The MBean specified is not
+ * registered in the MBean server.
+ * @throws MBeanRegistrationException The preDeregister
+ * ((<code>MBeanRegistration</code> interface) method of the MBean
+ * has thrown an exception.
+ * @throws RuntimeOperationsException Wraps a
+ * <code>java.lang.IllegalArgumentException</code>: The object
+ * name in parameter is null or the MBean you are when trying to
+ * unregister is the {@link javax.management.MBeanServerDelegate
+ * MBeanServerDelegate} MBean.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ */
+ public void unregisterMBean(ObjectName name, Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ MBeanRegistrationException,
+ IOException;
+
+ /**
+ * Handles the method
+ * {@link javax.management.MBeanServerConnection#getObjectInstance(ObjectName)}.
+ *
+ * @param name The object name of the MBean.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return The <code>ObjectInstance</code> associated with the MBean
+ * specified by <var>name</var>. The contained <code>ObjectName</code>
+ * is <code>name</code> and the contained class name is
+ * <code>{@link #getMBeanInfo getMBeanInfo(name)}.getClassName()</code>.
+ *
+ * @throws InstanceNotFoundException The MBean specified is not
+ * registered in the MBean server.
+ * @throws RuntimeOperationsException Wraps a
+ * <code>java.lang.IllegalArgumentException</code>: The object
+ * name in parameter is null.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ */
+ public ObjectInstance getObjectInstance(ObjectName name,
+ Subject delegationSubject)
+ throws InstanceNotFoundException, IOException;
+
+ /**
+ * Handles the method {@link
+ * javax.management.MBeanServerConnection#queryMBeans(ObjectName,
+ * QueryExp)}. The <code>QueryExp</code> is wrapped in a
+ * <code>MarshalledObject</code>.
+ *
+ * @param name The object name pattern identifying the MBeans to
+ * be retrieved. If null or no domain and key properties are
+ * specified, all the MBeans registered will be retrieved.
+ * @param query The query expression to be applied for selecting
+ * MBeans, encapsulated into a <code>MarshalledObject</code>. If
+ * the <code>MarshalledObject</code> encapsulates a null value no
+ * query expression will be applied for selecting MBeans.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return A set containing the <code>ObjectInstance</code>
+ * objects for the selected MBeans. If no MBean satisfies the
+ * query an empty list is returned.
+ *
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ */
+ public Set<ObjectInstance>
+ queryMBeans(ObjectName name,
+ MarshalledObject query,
+ Subject delegationSubject)
+ throws IOException;
+
+ /**
+ * Handles the method {@link
+ * javax.management.MBeanServerConnection#queryNames(ObjectName,
+ * QueryExp)}. The <code>QueryExp</code> is wrapped in a
+ * <code>MarshalledObject</code>.
+ *
+ * @param name The object name pattern identifying the MBean names
+ * to be retrieved. If null or no domain and key properties are
+ * specified, the name of all registered MBeans will be retrieved.
+ * @param query The query expression to be applied for selecting
+ * MBeans, encapsulated into a <code>MarshalledObject</code>. If
+ * the <code>MarshalledObject</code> encapsulates a null value no
+ * query expression will be applied for selecting MBeans.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return A set containing the ObjectNames for the MBeans
+ * selected. If no MBean satisfies the query, an empty list is
+ * returned.
+ *
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ */
+ public Set<ObjectName>
+ queryNames(ObjectName name,
+ MarshalledObject query,
+ Subject delegationSubject)
+ throws IOException;
+
+ /**
+ * Handles the method
+ * {@link javax.management.MBeanServerConnection#isRegistered(ObjectName)}.
+ *
+ * @param name The object name of the MBean to be checked.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return True if the MBean is already registered in the MBean
+ * server, false otherwise.
+ *
+ * @throws RuntimeOperationsException Wraps a
+ * <code>java.lang.IllegalArgumentException</code>: The object
+ * name in parameter is null.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ */
+ public boolean isRegistered(ObjectName name, Subject delegationSubject)
+ throws IOException;
+
+ /**
+ * Handles the method
+ * {@link javax.management.MBeanServerConnection#getMBeanCount()}.
+ *
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return the number of MBeans registered.
+ *
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ */
+ public Integer getMBeanCount(Subject delegationSubject)
+ throws IOException;
+
+ /**
+ * Handles the method {@link
+ * javax.management.MBeanServerConnection#getAttribute(ObjectName,
+ * String)}.
+ *
+ * @param name The object name of the MBean from which the
+ * attribute is to be retrieved.
+ * @param attribute A String specifying the name of the attribute
+ * to be retrieved.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return The value of the retrieved attribute.
+ *
+ * @throws AttributeNotFoundException The attribute specified
+ * is not accessible in the MBean.
+ * @throws MBeanException Wraps an exception thrown by the
+ * MBean's getter.
+ * @throws InstanceNotFoundException The MBean specified is not
+ * registered in the MBean server.
+ * @throws ReflectionException Wraps a
+ * <code>java.lang.Exception</code> thrown when trying to invoke
+ * the getter.
+ * @throws RuntimeOperationsException Wraps a
+ * <code>java.lang.IllegalArgumentException</code>: The object
+ * name in parameter is null or the attribute in parameter is
+ * null.
+ * @throws RuntimeMBeanException Wraps a runtime exception thrown
+ * by the MBean's getter.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ *
+ * @see #setAttribute
+ */
+ public Object getAttribute(ObjectName name,
+ String attribute,
+ Subject delegationSubject)
+ throws
+ MBeanException,
+ AttributeNotFoundException,
+ InstanceNotFoundException,
+ ReflectionException,
+ IOException;
+
+ /**
+ * Handles the method {@link
+ * javax.management.MBeanServerConnection#getAttributes(ObjectName,
+ * String[])}.
+ *
+ * @param name The object name of the MBean from which the
+ * attributes are retrieved.
+ * @param attributes A list of the attributes to be retrieved.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return The list of the retrieved attributes.
+ *
+ * @throws InstanceNotFoundException The MBean specified is not
+ * registered in the MBean server.
+ * @throws ReflectionException An exception occurred when
+ * trying to invoke the getAttributes method of a Dynamic MBean.
+ * @throws RuntimeOperationsException Wrap a
+ * <code>java.lang.IllegalArgumentException</code>: The object
+ * name in parameter is null or attributes in parameter is null.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ *
+ * @see #setAttributes
+ */
+ public AttributeList getAttributes(ObjectName name,
+ String[] attributes,
+ Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ ReflectionException,
+ IOException;
+
+ /**
+ * Handles the method {@link
+ * javax.management.MBeanServerConnection#setAttribute(ObjectName,
+ * Attribute)}. The <code>Attribute</code> parameter is wrapped
+ * in a <code>MarshalledObject</code>.
+ *
+ * @param name The name of the MBean within which the attribute is
+ * to be set.
+ * @param attribute The identification of the attribute to be set
+ * and the value it is to be set to, encapsulated into a
+ * <code>MarshalledObject</code>.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @throws InstanceNotFoundException The MBean specified is not
+ * registered in the MBean server.
+ * @throws AttributeNotFoundException The attribute specified
+ * is not accessible in the MBean.
+ * @throws InvalidAttributeValueException The value specified
+ * for the attribute is not valid.
+ * @throws MBeanException Wraps an exception thrown by the
+ * MBean's setter.
+ * @throws ReflectionException Wraps a
+ * <code>java.lang.Exception</code> thrown when trying to invoke
+ * the setter.
+ * @throws RuntimeOperationsException Wraps a
+ * <code>java.lang.IllegalArgumentException</code>: The object
+ * name in parameter is null or the attribute in parameter is
+ * null.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ *
+ * @see #getAttribute
+ */
+ public void setAttribute(ObjectName name,
+ MarshalledObject attribute,
+ Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ AttributeNotFoundException,
+ InvalidAttributeValueException,
+ MBeanException,
+ ReflectionException,
+ IOException;
+
+ /**
+ * Handles the method {@link
+ * javax.management.MBeanServerConnection#setAttributes(ObjectName,
+ * AttributeList)}. The <code>AttributeList</code> parameter is
+ * wrapped in a <code>MarshalledObject</code>.
+ *
+ * @param name The object name of the MBean within which the
+ * attributes are to be set.
+ * @param attributes A list of attributes: The identification of
+ * the attributes to be set and the values they are to be set to,
+ * encapsulated into a <code>MarshalledObject</code>.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return The list of attributes that were set, with their new
+ * values.
+ *
+ * @throws InstanceNotFoundException The MBean specified is not
+ * registered in the MBean server.
+ * @throws ReflectionException An exception occurred when
+ * trying to invoke the getAttributes method of a Dynamic MBean.
+ * @throws RuntimeOperationsException Wraps a
+ * <code>java.lang.IllegalArgumentException</code>: The object
+ * name in parameter is null or attributes in parameter is null.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ *
+ * @see #getAttributes
+ */
+ public AttributeList setAttributes(ObjectName name,
+ MarshalledObject attributes,
+ Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ ReflectionException,
+ IOException;
+
+ /**
+ * Handles the method {@link
+ * javax.management.MBeanServerConnection#invoke(ObjectName,
+ * String, Object[], String[])}. The <code>Object[]</code>
+ * parameter is wrapped in a <code>MarshalledObject</code>.
+ *
+ * @param name The object name of the MBean on which the method is
+ * to be invoked.
+ * @param operationName The name of the operation to be invoked.
+ * @param params An array containing the parameters to be set when
+ * the operation is invoked, encapsulated into a
+ * <code>MarshalledObject</code>. The encapsulated array can be
+ * null, equivalent to an empty array.
+ * @param signature An array containing the signature of the
+ * operation. The class objects will be loaded using the same
+ * class loader as the one used for loading the MBean on which the
+ * operation was invoked. Can be null, equivalent to an empty
+ * array.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return The object returned by the operation, which represents
+ * the result of invoking the operation on the MBean specified.
+ *
+ * @throws InstanceNotFoundException The MBean specified is not
+ * registered in the MBean server.
+ * @throws MBeanException Wraps an exception thrown by the
+ * MBean's invoked method.
+ * @throws ReflectionException Wraps a
+ * <code>java.lang.Exception</code> thrown while trying to invoke
+ * the method.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ * @throws RuntimeOperationsException Wraps an {@link
+ * IllegalArgumentException} when <code>name</code> or
+ * <code>operationName</code> is null.
+ */
+ public Object invoke(ObjectName name,
+ String operationName,
+ MarshalledObject params,
+ String signature[],
+ Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ MBeanException,
+ ReflectionException,
+ IOException;
+
+ /**
+ * Handles the method
+ * {@link javax.management.MBeanServerConnection#getDefaultDomain()}.
+ *
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return the default domain.
+ *
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ */
+ public String getDefaultDomain(Subject delegationSubject)
+ throws IOException;
+
+ /**
+ * Handles the method
+ * {@link javax.management.MBeanServerConnection#getDomains()}.
+ *
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return the list of domains.
+ *
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ */
+ public String[] getDomains(Subject delegationSubject)
+ throws IOException;
+
+ /**
+ * Handles the method
+ * {@link javax.management.MBeanServerConnection#getMBeanInfo(ObjectName)}.
+ *
+ * @param name The name of the MBean to analyze
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return An instance of <code>MBeanInfo</code> allowing the
+ * retrieval of all attributes and operations of this MBean.
+ *
+ * @throws IntrospectionException An exception occurred during
+ * introspection.
+ * @throws InstanceNotFoundException The MBean specified was
+ * not found.
+ * @throws ReflectionException An exception occurred when
+ * trying to invoke the getMBeanInfo of a Dynamic MBean.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ * @throws RuntimeOperationsException Wraps a
+ * <code>java.lang.IllegalArgumentException</code>: The object
+ * name in parameter is null.
+ */
+ public MBeanInfo getMBeanInfo(ObjectName name, Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ IntrospectionException,
+ ReflectionException,
+ IOException;
+
+ /**
+ * Handles the method {@link
+ * javax.management.MBeanServerConnection#isInstanceOf(ObjectName,
+ * String)}.
+ *
+ * @param name The <code>ObjectName</code> of the MBean.
+ * @param className The name of the class.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @return true if the MBean specified is an instance of the
+ * specified class according to the rules above, false otherwise.
+ *
+ * @throws InstanceNotFoundException The MBean specified is not
+ * registered in the MBean server.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ * @throws RuntimeOperationsException Wraps a
+ * <code>java.lang.IllegalArgumentException</code>: The object
+ * name in parameter is null.
+ */
+ public boolean isInstanceOf(ObjectName name,
+ String className,
+ Subject delegationSubject)
+ throws InstanceNotFoundException, IOException;
+
+ /**
+ * Handles the method {@link
+ * javax.management.MBeanServerConnection#addNotificationListener(ObjectName,
+ * ObjectName, NotificationFilter, Object)}. The
+ * <code>NotificationFilter</code> parameter is wrapped in a
+ * <code>MarshalledObject</code>. The <code>Object</code>
+ * (handback) parameter is also wrapped in a
+ * <code>MarshalledObject</code>.
+ *
+ * @param name The name of the MBean on which the listener should
+ * be added.
+ * @param listener The object name of the listener which will
+ * handle the notifications emitted by the registered MBean.
+ * @param filter The filter object, encapsulated into a
+ * <code>MarshalledObject</code>. If filter encapsulated in the
+ * <code>MarshalledObject</code> has a null value, no filtering
+ * will be performed before handling notifications.
+ * @param handback The context to be sent to the listener when a
+ * notification is emitted, encapsulated into a
+ * <code>MarshalledObject</code>.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @throws InstanceNotFoundException The MBean name of the
+ * notification listener or of the notification broadcaster does
+ * not match any of the registered MBeans.
+ * @throws RuntimeOperationsException Wraps an {@link
+ * IllegalArgumentException}. The MBean named by
+ * <code>listener</code> exists but does not implement the
+ * {@link javax.management.NotificationListener} interface,
+ * or <code>name</code> or <code>listener</code> is null.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ *
+ * @see #removeNotificationListener(ObjectName, ObjectName, Subject)
+ * @see #removeNotificationListener(ObjectName, ObjectName,
+ * MarshalledObject, MarshalledObject, Subject)
+ */
+ public void addNotificationListener(ObjectName name,
+ ObjectName listener,
+ MarshalledObject filter,
+ MarshalledObject handback,
+ Subject delegationSubject)
+ throws InstanceNotFoundException, IOException;
+
+ /**
+ * Handles the method {@link
+ * javax.management.MBeanServerConnection#removeNotificationListener(ObjectName,
+ * ObjectName)}.
+ *
+ * @param name The name of the MBean on which the listener should
+ * be removed.
+ * @param listener The object name of the listener to be removed.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @throws InstanceNotFoundException The MBean name provided
+ * does not match any of the registered MBeans.
+ * @throws ListenerNotFoundException The listener is not
+ * registered in the MBean.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ * @throws RuntimeOperationsException Wraps an {@link
+ * IllegalArgumentException} when <code>name</code> or
+ * <code>listener</code> is null.
+ *
+ * @see #addNotificationListener
+ */
+ public void removeNotificationListener(ObjectName name,
+ ObjectName listener,
+ Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ ListenerNotFoundException,
+ IOException;
+
+ /**
+ * Handles the method {@link
+ * javax.management.MBeanServerConnection#removeNotificationListener(ObjectName,
+ * ObjectName, NotificationFilter, Object)}. The
+ * <code>NotificationFilter</code> parameter is wrapped in a
+ * <code>MarshalledObject</code>. The <code>Object</code>
+ * parameter is also wrapped in a <code>MarshalledObject</code>.
+ *
+ * @param name The name of the MBean on which the listener should
+ * be removed.
+ * @param listener A listener that was previously added to this
+ * MBean.
+ * @param filter The filter that was specified when the listener
+ * was added, encapsulated into a <code>MarshalledObject</code>.
+ * @param handback The handback that was specified when the
+ * listener was added, encapsulated into a <code>MarshalledObject</code>.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @throws InstanceNotFoundException The MBean name provided
+ * does not match any of the registered MBeans.
+ * @throws ListenerNotFoundException The listener is not
+ * registered in the MBean, or it is not registered with the given
+ * filter and handback.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to perform this operation.
+ * @throws IOException if a general communication exception occurred.
+ * @throws RuntimeOperationsException Wraps an {@link
+ * IllegalArgumentException} when <code>name</code> or
+ * <code>listener</code> is null.
+ *
+ * @see #addNotificationListener
+ */
+ public void removeNotificationListener(ObjectName name,
+ ObjectName listener,
+ MarshalledObject filter,
+ MarshalledObject handback,
+ Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ ListenerNotFoundException,
+ IOException;
+
+ // Special Handling of Notifications -------------------------------------
+
+ /**
+ * <p>Handles the method {@link
+ * javax.management.MBeanServerConnection#addNotificationListener(ObjectName,
+ * NotificationListener, NotificationFilter, Object)}.</p>
+ *
+ * <p>Register for notifications from the given MBeans that match
+ * the given filters. The remote client can subsequently retrieve
+ * the notifications using the {@link #fetchNotifications
+ * fetchNotifications} method.</p>
+ *
+ * <p>For each listener, the original
+ * <code>NotificationListener</code> and <code>handback</code> are
+ * kept on the client side; in order for the client to be able to
+ * identify them, the server generates and returns a unique
+ * <code>listenerID</code>. This <code>listenerID</code> is
+ * forwarded with the <code>Notifications</code> to the remote
+ * client.</p>
+ *
+ * <p>If any one of the given (name, filter) pairs cannot be
+ * registered, then the operation fails with an exception, and no
+ * names or filters are registered.</p>
+ *
+ * @param names the <code>ObjectNames</code> identifying the
+ * MBeans emitting the Notifications.
+ * @param filters an array of marshalled representations of the
+ * <code>NotificationFilters</code>. Elements of this array can
+ * be null.
+ * @param delegationSubjects the <code>Subjects</code> on behalf
+ * of which the listeners are being added. Elements of this array
+ * can be null. Also, the <code>delegationSubjects</code>
+ * parameter itself can be null, which is equivalent to an array
+ * of null values with the same size as the <code>names</code> and
+ * <code>filters</code> arrays.
+ *
+ * @return an array of <code>listenerIDs</code> identifying the
+ * local listeners. This array has the same number of elements as
+ * the parameters.
+ *
+ * @throws IllegalArgumentException if <code>names</code> or
+ * <code>filters</code> is null, or if <code>names</code> contains
+ * a null element, or if the three arrays do not all have the same
+ * size.
+ * @throws ClassCastException if one of the elements of
+ * <code>filters</code> unmarshalls as a non-null object that is
+ * not a <code>NotificationFilter</code>.
+ * @throws InstanceNotFoundException if one of the
+ * <code>names</code> does not correspond to any registered MBean.
+ * @throws SecurityException if, for one of the MBeans, the
+ * client, or the delegated Subject if any, does not have
+ * permission to add a listener.
+ * @throws IOException if a general communication exception occurred.
+ */
+ public Integer[] addNotificationListeners(ObjectName[] names,
+ MarshalledObject[] filters,
+ Subject[] delegationSubjects)
+ throws InstanceNotFoundException, IOException;
+
+ /**
+ * <p>Handles the
+ * {@link javax.management.MBeanServerConnection#removeNotificationListener(ObjectName,NotificationListener)
+ * removeNotificationListener(ObjectName, NotificationListener)} and
+ * {@link javax.management.MBeanServerConnection#removeNotificationListener(ObjectName,NotificationListener,NotificationFilter,Object)
+ * removeNotificationListener(ObjectName, NotificationListener, NotificationFilter, Object)} methods.</p>
+ *
+ * <p>This method removes one or more
+ * <code>NotificationListener</code>s from a given MBean in the
+ * MBean server.</p>
+ *
+ * <p>The <code>NotificationListeners</code> are identified by the
+ * IDs which were returned by the {@link
+ * #addNotificationListeners(ObjectName[], MarshalledObject[],
+ * Subject[])} method.</p>
+ *
+ * @param name the <code>ObjectName</code> identifying the MBean
+ * emitting the Notifications.
+ * @param listenerIDs the list of the IDs corresponding to the
+ * listeners to remove.
+ * @param delegationSubject The <code>Subject</code> containing the
+ * delegation principals or <code>null</code> if the authentication
+ * principal is used instead.
+ *
+ * @throws InstanceNotFoundException if the given
+ * <code>name</code> does not correspond to any registered MBean.
+ * @throws ListenerNotFoundException if one of the listeners was
+ * not found on the server side. This exception can happen if the
+ * MBean discarded a listener for some reason other than a call to
+ * <code>MBeanServer.removeNotificationListener</code>.
+ * @throws SecurityException if the client, or the delegated Subject
+ * if any, does not have permission to remove the listeners.
+ * @throws IOException if a general communication exception occurred.
+ * @throws IllegalArgumentException if <code>ObjectName</code> or
+ * <code>listenerIds</code> is null or if <code>listenerIds</code>
+ * contains a null element.
+ */
+ public void removeNotificationListeners(ObjectName name,
+ Integer[] listenerIDs,
+ Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ ListenerNotFoundException,
+ IOException;
+
+ /**
+ * <p>Retrieves notifications from the connector server. This
+ * method can block until there is at least one notification or
+ * until the specified timeout is reached. The method can also
+ * return at any time with zero notifications.</p>
+ *
+ * <p>A notification can be included in the result if its sequence
+ * number is no less than <code>clientSequenceNumber</code> and
+ * this client has registered at least one listener for the MBean
+ * generating the notification, with a filter that accepts the
+ * notification. Each listener that is interested in the
+ * notification is identified by an Integer ID that was returned
+ * by {@link #addNotificationListeners(ObjectName[],
+ * MarshalledObject[], Subject[])}.</p>
+ *
+ * @param clientSequenceNumber the first sequence number that the
+ * client is interested in. If negative, it is interpreted as
+ * meaning the sequence number that the next notification will
+ * have.
+ *
+ * @param maxNotifications the maximum number of different
+ * notifications to return. The <code>TargetedNotification</code>
+ * array in the returned <code>NotificationResult</code> can have
+ * more elements than this if the same notification appears more
+ * than once. The behavior is unspecified if this parameter is
+ * negative.
+ *
+ * @param timeout the maximum time in milliseconds to wait for a
+ * notification to arrive. This can be 0 to indicate that the
+ * method should not wait if there are no notifications, but
+ * should return at once. It can be <code>Long.MAX_VALUE</code>
+ * to indicate that there is no timeout. The behavior is
+ * unspecified if this parameter is negative.
+ *
+ * @return A <code>NotificationResult</code>.
+ *
+ * @throws IOException if a general communication exception occurred.
+ */
+ public NotificationResult fetchNotifications(long clientSequenceNumber,
+ int maxNotifications,
+ long timeout)
+ throws IOException;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,1834 @@
+/*
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.management.remote.rmi;
+
+import java.io.IOException;
+import java.rmi.MarshalledObject;
+import java.rmi.UnmarshalException;
+import java.rmi.server.Unreferenced;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.Permissions;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.*;
+import javax.management.remote.JMXServerErrorException;
+import javax.management.remote.NotificationResult;
+import javax.security.auth.Subject;
+import sun.reflect.misc.ReflectUtil;
+
+import static javax.management.remote.rmi.RMIConnector.Util.cast;
+import com.sun.jmx.remote.internal.ServerCommunicatorAdmin;
+import com.sun.jmx.remote.internal.ServerNotifForwarder;
+import com.sun.jmx.remote.security.JMXSubjectDomainCombiner;
+import com.sun.jmx.remote.security.SubjectDelegator;
+import com.sun.jmx.remote.util.ClassLoaderWithRepository;
+import com.sun.jmx.remote.util.ClassLogger;
+import com.sun.jmx.remote.util.EnvHelp;
+import com.sun.jmx.remote.util.OrderClassLoaders;
+import javax.management.loading.ClassLoaderRepository;
+
+/**
+ * <p>Implementation of the {@link RMIConnection} interface. User
+ * code will not usually reference this class.</p>
+ *
+ * @since 1.5
+ */
+/*
+ * Notice that we omit the type parameter from MarshalledObject everywhere,
+ * even though it would add useful information to the documentation. The
+ * reason is that it was only added in Mustang (Java SE 6), whereas versions
+ * 1.4 and 2.0 of the JMX API must be implementable on Tiger per our
+ * commitments for JSR 255.
+ */
+public class RMIConnectionImpl implements RMIConnection, Unreferenced {
+
+ /**
+ * Constructs a new {@link RMIConnection}. This connection can be
+ * used with the JRMP transport. This object does
+ * not export itself: it is the responsibility of the caller to
+ * export it appropriately (see {@link
+ * RMIJRMPServerImpl#makeClient(String,Subject)}).
+ *
+ * @param rmiServer The RMIServerImpl object for which this
+ * connection is created. The behavior is unspecified if this
+ * parameter is null.
+ * @param connectionId The ID for this connection. The behavior
+ * is unspecified if this parameter is null.
+ * @param defaultClassLoader The default ClassLoader to be used
+ * when deserializing marshalled objects. Can be null, to signify
+ * the bootstrap class loader.
+ * @param subject the authenticated subject to be used for
+ * authorization. Can be null, to signify that no subject has
+ * been authenticated.
+ * @param env the environment containing attributes for the new
+ * <code>RMIServerImpl</code>. Can be null, equivalent to an
+ * empty map.
+ */
+ public RMIConnectionImpl(RMIServerImpl rmiServer,
+ String connectionId,
+ ClassLoader defaultClassLoader,
+ Subject subject,
+ Map<String,?> env) {
+ if (rmiServer == null || connectionId == null)
+ throw new NullPointerException("Illegal null argument");
+ if (env == null)
+ env = Collections.emptyMap();
+ this.rmiServer = rmiServer;
+ this.connectionId = connectionId;
+ this.defaultClassLoader = defaultClassLoader;
+
+ this.subjectDelegator = new SubjectDelegator();
+ this.subject = subject;
+ if (subject == null) {
+ this.acc = null;
+ this.removeCallerContext = false;
+ } else {
+ this.removeCallerContext =
+ SubjectDelegator.checkRemoveCallerContext(subject);
+ if (this.removeCallerContext) {
+ this.acc =
+ JMXSubjectDomainCombiner.getDomainCombinerContext(subject);
+ } else {
+ this.acc =
+ JMXSubjectDomainCombiner.getContext(subject);
+ }
+ }
+ this.mbeanServer = rmiServer.getMBeanServer();
+
+ final ClassLoader dcl = defaultClassLoader;
+
+ ClassLoaderRepository repository = AccessController.doPrivileged(
+ new PrivilegedAction<ClassLoaderRepository>() {
+ public ClassLoaderRepository run() {
+ return mbeanServer.getClassLoaderRepository();
+ }
+ },
+ withPermissions(new MBeanPermission("*", "getClassLoaderRepository"))
+ );
+ this.classLoaderWithRepository = AccessController.doPrivileged(
+ new PrivilegedAction<ClassLoaderWithRepository>() {
+ public ClassLoaderWithRepository run() {
+ return new ClassLoaderWithRepository(
+ repository,
+ dcl);
+ }
+ },
+ withPermissions(new RuntimePermission("createClassLoader"))
+ );
+
+ this.defaultContextClassLoader =
+ AccessController.doPrivileged(
+ new PrivilegedAction<ClassLoader>() {
+ @Override
+ public ClassLoader run() {
+ return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(),
+ dcl);
+ }
+ });
+
+ serverCommunicatorAdmin = new
+ RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env));
+
+ this.env = env;
+ }
+
+ private static AccessControlContext withPermissions(Permission ... perms){
+ Permissions col = new Permissions();
+
+ for (Permission thePerm : perms ) {
+ col.add(thePerm);
+ }
+
+ final ProtectionDomain pd = new ProtectionDomain(null, col);
+ return new AccessControlContext( new ProtectionDomain[] { pd });
+ }
+
+ private synchronized ServerNotifForwarder getServerNotifFwd() {
+ // Lazily created when first use. Mainly when
+ // addNotificationListener is first called.
+ if (serverNotifForwarder == null)
+ serverNotifForwarder =
+ new ServerNotifForwarder(mbeanServer,
+ env,
+ rmiServer.getNotifBuffer(),
+ connectionId);
+ return serverNotifForwarder;
+ }
+
+ public String getConnectionId() throws IOException {
+ // We should call reqIncomming() here... shouldn't we?
+ return connectionId;
+ }
+
+ public void close() throws IOException {
+ final boolean debug = logger.debugOn();
+ final String idstr = (debug?"["+this.toString()+"]":null);
+
+ synchronized (this) {
+ if (terminated) {
+ if (debug) logger.debug("close",idstr + " already terminated.");
+ return;
+ }
+
+ if (debug) logger.debug("close",idstr + " closing.");
+
+ terminated = true;
+
+ if (serverCommunicatorAdmin != null) {
+ serverCommunicatorAdmin.terminate();
+ }
+
+ if (serverNotifForwarder != null) {
+ serverNotifForwarder.terminate();
+ }
+ }
+
+ rmiServer.clientClosed(this);
+
+ if (debug) logger.debug("close",idstr + " closed.");
+ }
+
+ public void unreferenced() {
+ logger.debug("unreferenced", "called");
+ try {
+ close();
+ logger.debug("unreferenced", "done");
+ } catch (IOException e) {
+ logger.fine("unreferenced", e);
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ // MBeanServerConnection Wrapper
+ //-------------------------------------------------------------------------
+
+ public ObjectInstance createMBean(String className,
+ ObjectName name,
+ Subject delegationSubject)
+ throws
+ ReflectionException,
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ MBeanException,
+ NotCompliantMBeanException,
+ IOException {
+ try {
+ final Object params[] =
+ new Object[] { className, name };
+
+ if (logger.debugOn())
+ logger.debug("createMBean(String,ObjectName)",
+ "connectionId=" + connectionId +", className=" +
+ className+", name=" + name);
+
+ return (ObjectInstance)
+ doPrivilegedOperation(
+ CREATE_MBEAN,
+ params,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof ReflectionException)
+ throw (ReflectionException) e;
+ if (e instanceof InstanceAlreadyExistsException)
+ throw (InstanceAlreadyExistsException) e;
+ if (e instanceof MBeanRegistrationException)
+ throw (MBeanRegistrationException) e;
+ if (e instanceof MBeanException)
+ throw (MBeanException) e;
+ if (e instanceof NotCompliantMBeanException)
+ throw (NotCompliantMBeanException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ public ObjectInstance createMBean(String className,
+ ObjectName name,
+ ObjectName loaderName,
+ Subject delegationSubject)
+ throws
+ ReflectionException,
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ MBeanException,
+ NotCompliantMBeanException,
+ InstanceNotFoundException,
+ IOException {
+ try {
+ final Object params[] =
+ new Object[] { className, name, loaderName };
+
+ if (logger.debugOn())
+ logger.debug("createMBean(String,ObjectName,ObjectName)",
+ "connectionId=" + connectionId
+ +", className=" + className
+ +", name=" + name
+ +", loaderName=" + loaderName);
+
+ return (ObjectInstance)
+ doPrivilegedOperation(
+ CREATE_MBEAN_LOADER,
+ params,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof ReflectionException)
+ throw (ReflectionException) e;
+ if (e instanceof InstanceAlreadyExistsException)
+ throw (InstanceAlreadyExistsException) e;
+ if (e instanceof MBeanRegistrationException)
+ throw (MBeanRegistrationException) e;
+ if (e instanceof MBeanException)
+ throw (MBeanException) e;
+ if (e instanceof NotCompliantMBeanException)
+ throw (NotCompliantMBeanException) e;
+ if (e instanceof InstanceNotFoundException)
+ throw (InstanceNotFoundException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ @SuppressWarnings("rawtypes") // MarshalledObject
+ public ObjectInstance createMBean(String className,
+ ObjectName name,
+ MarshalledObject params,
+ String signature[],
+ Subject delegationSubject)
+ throws
+ ReflectionException,
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ MBeanException,
+ NotCompliantMBeanException,
+ IOException {
+
+ final Object[] values;
+ final boolean debug = logger.debugOn();
+
+ if (debug) logger.debug(
+ "createMBean(String,ObjectName,Object[],String[])",
+ "connectionId=" + connectionId
+ +", unwrapping parameters using classLoaderWithRepository.");
+
+ values =
+ nullIsEmpty(unwrap(params, classLoaderWithRepository, Object[].class,delegationSubject));
+
+ try {
+ final Object params2[] =
+ new Object[] { className, name, values,
+ nullIsEmpty(signature) };
+
+ if (debug)
+ logger.debug("createMBean(String,ObjectName,Object[],String[])",
+ "connectionId=" + connectionId
+ +", className=" + className
+ +", name=" + name
+ +", signature=" + strings(signature));
+
+ return (ObjectInstance)
+ doPrivilegedOperation(
+ CREATE_MBEAN_PARAMS,
+ params2,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof ReflectionException)
+ throw (ReflectionException) e;
+ if (e instanceof InstanceAlreadyExistsException)
+ throw (InstanceAlreadyExistsException) e;
+ if (e instanceof MBeanRegistrationException)
+ throw (MBeanRegistrationException) e;
+ if (e instanceof MBeanException)
+ throw (MBeanException) e;
+ if (e instanceof NotCompliantMBeanException)
+ throw (NotCompliantMBeanException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ @SuppressWarnings("rawtypes") // MarshalledObject
+ public ObjectInstance createMBean(String className,
+ ObjectName name,
+ ObjectName loaderName,
+ MarshalledObject params,
+ String signature[],
+ Subject delegationSubject)
+ throws
+ ReflectionException,
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ MBeanException,
+ NotCompliantMBeanException,
+ InstanceNotFoundException,
+ IOException {
+
+ final Object[] values;
+ final boolean debug = logger.debugOn();
+
+ if (debug) logger.debug(
+ "createMBean(String,ObjectName,ObjectName,Object[],String[])",
+ "connectionId=" + connectionId
+ +", unwrapping params with MBean extended ClassLoader.");
+
+ values = nullIsEmpty(unwrap(params,
+ getClassLoader(loaderName),
+ defaultClassLoader,
+ Object[].class,delegationSubject));
+
+ try {
+ final Object params2[] =
+ new Object[] { className, name, loaderName, values,
+ nullIsEmpty(signature) };
+
+ if (debug) logger.debug(
+ "createMBean(String,ObjectName,ObjectName,Object[],String[])",
+ "connectionId=" + connectionId
+ +", className=" + className
+ +", name=" + name
+ +", loaderName=" + loaderName
+ +", signature=" + strings(signature));
+
+ return (ObjectInstance)
+ doPrivilegedOperation(
+ CREATE_MBEAN_LOADER_PARAMS,
+ params2,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof ReflectionException)
+ throw (ReflectionException) e;
+ if (e instanceof InstanceAlreadyExistsException)
+ throw (InstanceAlreadyExistsException) e;
+ if (e instanceof MBeanRegistrationException)
+ throw (MBeanRegistrationException) e;
+ if (e instanceof MBeanException)
+ throw (MBeanException) e;
+ if (e instanceof NotCompliantMBeanException)
+ throw (NotCompliantMBeanException) e;
+ if (e instanceof InstanceNotFoundException)
+ throw (InstanceNotFoundException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ public void unregisterMBean(ObjectName name, Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ MBeanRegistrationException,
+ IOException {
+ try {
+ final Object params[] = new Object[] { name };
+
+ if (logger.debugOn()) logger.debug("unregisterMBean",
+ "connectionId=" + connectionId
+ +", name="+name);
+
+ doPrivilegedOperation(
+ UNREGISTER_MBEAN,
+ params,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof InstanceNotFoundException)
+ throw (InstanceNotFoundException) e;
+ if (e instanceof MBeanRegistrationException)
+ throw (MBeanRegistrationException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ public ObjectInstance getObjectInstance(ObjectName name,
+ Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ IOException {
+
+ checkNonNull("ObjectName", name);
+
+ try {
+ final Object params[] = new Object[] { name };
+
+ if (logger.debugOn()) logger.debug("getObjectInstance",
+ "connectionId=" + connectionId
+ +", name="+name);
+
+ return (ObjectInstance)
+ doPrivilegedOperation(
+ GET_OBJECT_INSTANCE,
+ params,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof InstanceNotFoundException)
+ throw (InstanceNotFoundException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ @SuppressWarnings("rawtypes") // MarshalledObject
+ public Set<ObjectInstance>
+ queryMBeans(ObjectName name,
+ MarshalledObject query,
+ Subject delegationSubject)
+ throws IOException {
+ final QueryExp queryValue;
+ final boolean debug=logger.debugOn();
+
+ if (debug) logger.debug("queryMBeans",
+ "connectionId=" + connectionId
+ +" unwrapping query with defaultClassLoader.");
+
+ queryValue = unwrap(query, defaultContextClassLoader, QueryExp.class, delegationSubject);
+
+ try {
+ final Object params[] = new Object[] { name, queryValue };
+
+ if (debug) logger.debug("queryMBeans",
+ "connectionId=" + connectionId
+ +", name="+name +", query="+query);
+
+ return cast(
+ doPrivilegedOperation(
+ QUERY_MBEANS,
+ params,
+ delegationSubject));
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ @SuppressWarnings("rawtypes") // MarshalledObject
+ public Set<ObjectName>
+ queryNames(ObjectName name,
+ MarshalledObject query,
+ Subject delegationSubject)
+ throws IOException {
+ final QueryExp queryValue;
+ final boolean debug=logger.debugOn();
+
+ if (debug) logger.debug("queryNames",
+ "connectionId=" + connectionId
+ +" unwrapping query with defaultClassLoader.");
+
+ queryValue = unwrap(query, defaultContextClassLoader, QueryExp.class, delegationSubject);
+
+ try {
+ final Object params[] = new Object[] { name, queryValue };
+
+ if (debug) logger.debug("queryNames",
+ "connectionId=" + connectionId
+ +", name="+name +", query="+query);
+
+ return cast(
+ doPrivilegedOperation(
+ QUERY_NAMES,
+ params,
+ delegationSubject));
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ public boolean isRegistered(ObjectName name,
+ Subject delegationSubject) throws IOException {
+ try {
+ final Object params[] = new Object[] { name };
+ return ((Boolean)
+ doPrivilegedOperation(
+ IS_REGISTERED,
+ params,
+ delegationSubject)).booleanValue();
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ public Integer getMBeanCount(Subject delegationSubject)
+ throws IOException {
+ try {
+ final Object params[] = new Object[] { };
+
+ if (logger.debugOn()) logger.debug("getMBeanCount",
+ "connectionId=" + connectionId);
+
+ return (Integer)
+ doPrivilegedOperation(
+ GET_MBEAN_COUNT,
+ params,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ public Object getAttribute(ObjectName name,
+ String attribute,
+ Subject delegationSubject)
+ throws
+ MBeanException,
+ AttributeNotFoundException,
+ InstanceNotFoundException,
+ ReflectionException,
+ IOException {
+ try {
+ final Object params[] = new Object[] { name, attribute };
+ if (logger.debugOn()) logger.debug("getAttribute",
+ "connectionId=" + connectionId
+ +", name=" + name
+ +", attribute="+ attribute);
+
+ return
+ doPrivilegedOperation(
+ GET_ATTRIBUTE,
+ params,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof MBeanException)
+ throw (MBeanException) e;
+ if (e instanceof AttributeNotFoundException)
+ throw (AttributeNotFoundException) e;
+ if (e instanceof InstanceNotFoundException)
+ throw (InstanceNotFoundException) e;
+ if (e instanceof ReflectionException)
+ throw (ReflectionException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ public AttributeList getAttributes(ObjectName name,
+ String[] attributes,
+ Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ ReflectionException,
+ IOException {
+ try {
+ final Object params[] = new Object[] { name, attributes };
+
+ if (logger.debugOn()) logger.debug("getAttributes",
+ "connectionId=" + connectionId
+ +", name=" + name
+ +", attributes="+ strings(attributes));
+
+ return (AttributeList)
+ doPrivilegedOperation(
+ GET_ATTRIBUTES,
+ params,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof InstanceNotFoundException)
+ throw (InstanceNotFoundException) e;
+ if (e instanceof ReflectionException)
+ throw (ReflectionException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ @SuppressWarnings("rawtypes") // MarshalledObject
+ public void setAttribute(ObjectName name,
+ MarshalledObject attribute,
+ Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ AttributeNotFoundException,
+ InvalidAttributeValueException,
+ MBeanException,
+ ReflectionException,
+ IOException {
+ final Attribute attr;
+ final boolean debug=logger.debugOn();
+
+ if (debug) logger.debug("setAttribute",
+ "connectionId=" + connectionId
+ +" unwrapping attribute with MBean extended ClassLoader.");
+
+ attr = unwrap(attribute,
+ getClassLoaderFor(name),
+ defaultClassLoader,
+ Attribute.class, delegationSubject);
+
+ try {
+ final Object params[] = new Object[] { name, attr };
+
+ if (debug) logger.debug("setAttribute",
+ "connectionId=" + connectionId
+ +", name="+name
+ +", attribute name="+attr.getName());
+
+ doPrivilegedOperation(
+ SET_ATTRIBUTE,
+ params,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof InstanceNotFoundException)
+ throw (InstanceNotFoundException) e;
+ if (e instanceof AttributeNotFoundException)
+ throw (AttributeNotFoundException) e;
+ if (e instanceof InvalidAttributeValueException)
+ throw (InvalidAttributeValueException) e;
+ if (e instanceof MBeanException)
+ throw (MBeanException) e;
+ if (e instanceof ReflectionException)
+ throw (ReflectionException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ @SuppressWarnings("rawtypes") // MarshalledObject
+ public AttributeList setAttributes(ObjectName name,
+ MarshalledObject attributes,
+ Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ ReflectionException,
+ IOException {
+ final AttributeList attrlist;
+ final boolean debug=logger.debugOn();
+
+ if (debug) logger.debug("setAttributes",
+ "connectionId=" + connectionId
+ +" unwrapping attributes with MBean extended ClassLoader.");
+
+ attrlist =
+ unwrap(attributes,
+ getClassLoaderFor(name),
+ defaultClassLoader,
+ AttributeList.class, delegationSubject);
+
+ try {
+ final Object params[] = new Object[] { name, attrlist };
+
+ if (debug) logger.debug("setAttributes",
+ "connectionId=" + connectionId
+ +", name="+name
+ +", attribute names="+RMIConnector.getAttributesNames(attrlist));
+
+ return (AttributeList)
+ doPrivilegedOperation(
+ SET_ATTRIBUTES,
+ params,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof InstanceNotFoundException)
+ throw (InstanceNotFoundException) e;
+ if (e instanceof ReflectionException)
+ throw (ReflectionException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ @SuppressWarnings("rawtypes") // MarshalledObject
+ public Object invoke(ObjectName name,
+ String operationName,
+ MarshalledObject params,
+ String signature[],
+ Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ MBeanException,
+ ReflectionException,
+ IOException {
+
+ checkNonNull("ObjectName", name);
+ checkNonNull("Operation name", operationName);
+
+ final Object[] values;
+ final boolean debug=logger.debugOn();
+
+ if (debug) logger.debug("invoke",
+ "connectionId=" + connectionId
+ +" unwrapping params with MBean extended ClassLoader.");
+
+ values = nullIsEmpty(unwrap(params,
+ getClassLoaderFor(name),
+ defaultClassLoader,
+ Object[].class, delegationSubject));
+
+ try {
+ final Object params2[] =
+ new Object[] { name, operationName, values,
+ nullIsEmpty(signature) };
+
+ if (debug) logger.debug("invoke",
+ "connectionId=" + connectionId
+ +", name="+name
+ +", operationName="+operationName
+ +", signature="+strings(signature));
+
+ return
+ doPrivilegedOperation(
+ INVOKE,
+ params2,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof InstanceNotFoundException)
+ throw (InstanceNotFoundException) e;
+ if (e instanceof MBeanException)
+ throw (MBeanException) e;
+ if (e instanceof ReflectionException)
+ throw (ReflectionException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ public String getDefaultDomain(Subject delegationSubject)
+ throws IOException {
+ try {
+ final Object params[] = new Object[] { };
+
+ if (logger.debugOn()) logger.debug("getDefaultDomain",
+ "connectionId=" + connectionId);
+
+ return (String)
+ doPrivilegedOperation(
+ GET_DEFAULT_DOMAIN,
+ params,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ public String[] getDomains(Subject delegationSubject) throws IOException {
+ try {
+ final Object params[] = new Object[] { };
+
+ if (logger.debugOn()) logger.debug("getDomains",
+ "connectionId=" + connectionId);
+
+ return (String[])
+ doPrivilegedOperation(
+ GET_DOMAINS,
+ params,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ public MBeanInfo getMBeanInfo(ObjectName name, Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ IntrospectionException,
+ ReflectionException,
+ IOException {
+
+ checkNonNull("ObjectName", name);
+
+ try {
+ final Object params[] = new Object[] { name };
+
+ if (logger.debugOn()) logger.debug("getMBeanInfo",
+ "connectionId=" + connectionId
+ +", name="+name);
+
+ return (MBeanInfo)
+ doPrivilegedOperation(
+ GET_MBEAN_INFO,
+ params,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof InstanceNotFoundException)
+ throw (InstanceNotFoundException) e;
+ if (e instanceof IntrospectionException)
+ throw (IntrospectionException) e;
+ if (e instanceof ReflectionException)
+ throw (ReflectionException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ public boolean isInstanceOf(ObjectName name,
+ String className,
+ Subject delegationSubject)
+ throws InstanceNotFoundException, IOException {
+
+ checkNonNull("ObjectName", name);
+
+ try {
+ final Object params[] = new Object[] { name, className };
+
+ if (logger.debugOn()) logger.debug("isInstanceOf",
+ "connectionId=" + connectionId
+ +", name="+name
+ +", className="+className);
+
+ return ((Boolean)
+ doPrivilegedOperation(
+ IS_INSTANCE_OF,
+ params,
+ delegationSubject)).booleanValue();
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof InstanceNotFoundException)
+ throw (InstanceNotFoundException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ @SuppressWarnings("rawtypes") // MarshalledObject
+ public Integer[] addNotificationListeners(ObjectName[] names,
+ MarshalledObject[] filters,
+ Subject[] delegationSubjects)
+ throws InstanceNotFoundException, IOException {
+
+ if (names == null || filters == null) {
+ throw new IllegalArgumentException("Got null arguments.");
+ }
+
+ Subject[] sbjs = (delegationSubjects != null) ? delegationSubjects :
+ new Subject[names.length];
+ if (names.length != filters.length || filters.length != sbjs.length) {
+ final String msg =
+ "The value lengths of 3 parameters are not same.";
+ throw new IllegalArgumentException(msg);
+ }
+
+ for (int i=0; i<names.length; i++) {
+ if (names[i] == null) {
+ throw new IllegalArgumentException("Null Object name.");
+ }
+ }
+
+ int i=0;
+ ClassLoader targetCl;
+ NotificationFilter[] filterValues =
+ new NotificationFilter[names.length];
+ Integer[] ids = new Integer[names.length];
+ final boolean debug=logger.debugOn();
+
+ try {
+ for (; i<names.length; i++) {
+ targetCl = getClassLoaderFor(names[i]);
+
+ if (debug) logger.debug("addNotificationListener"+
+ "(ObjectName,NotificationFilter)",
+ "connectionId=" + connectionId +
+ " unwrapping filter with target extended ClassLoader.");
+
+ filterValues[i] =
+ unwrap(filters[i], targetCl, defaultClassLoader,
+ NotificationFilter.class, sbjs[i]);
+
+ if (debug) logger.debug("addNotificationListener"+
+ "(ObjectName,NotificationFilter)",
+ "connectionId=" + connectionId
+ +", name=" + names[i]
+ +", filter=" + filterValues[i]);
+
+ ids[i] = (Integer)
+ doPrivilegedOperation(ADD_NOTIFICATION_LISTENERS,
+ new Object[] { names[i],
+ filterValues[i] },
+ sbjs[i]);
+ }
+
+ return ids;
+ } catch (Exception e) {
+ // remove all registered listeners
+ for (int j=0; j<i; j++) {
+ try {
+ getServerNotifFwd().removeNotificationListener(names[j],
+ ids[j]);
+ } catch (Exception eee) {
+ // strange
+ }
+ }
+
+ if (e instanceof PrivilegedActionException) {
+ e = extractException(e);
+ }
+
+ if (e instanceof ClassCastException) {
+ throw (ClassCastException) e;
+ } else if (e instanceof IOException) {
+ throw (IOException)e;
+ } else if (e instanceof InstanceNotFoundException) {
+ throw (InstanceNotFoundException) e;
+ } else if (e instanceof RuntimeException) {
+ throw (RuntimeException) e;
+ } else {
+ throw newIOException("Got unexpected server exception: "+e,e);
+ }
+ }
+ }
+
+ @SuppressWarnings("rawtypes") // MarshalledObject
+ public void addNotificationListener(ObjectName name,
+ ObjectName listener,
+ MarshalledObject filter,
+ MarshalledObject handback,
+ Subject delegationSubject)
+ throws InstanceNotFoundException, IOException {
+
+ checkNonNull("Target MBean name", name);
+ checkNonNull("Listener MBean name", listener);
+
+ final NotificationFilter filterValue;
+ final Object handbackValue;
+ final boolean debug=logger.debugOn();
+
+ final ClassLoader targetCl = getClassLoaderFor(name);
+
+ if (debug) logger.debug("addNotificationListener"+
+ "(ObjectName,ObjectName,NotificationFilter,Object)",
+ "connectionId=" + connectionId
+ +" unwrapping filter with target extended ClassLoader.");
+
+ filterValue =
+ unwrap(filter, targetCl, defaultClassLoader, NotificationFilter.class, delegationSubject);
+
+ if (debug) logger.debug("addNotificationListener"+
+ "(ObjectName,ObjectName,NotificationFilter,Object)",
+ "connectionId=" + connectionId
+ +" unwrapping handback with target extended ClassLoader.");
+
+ handbackValue =
+ unwrap(handback, targetCl, defaultClassLoader, Object.class, delegationSubject);
+
+ try {
+ final Object params[] =
+ new Object[] { name, listener, filterValue, handbackValue };
+
+ if (debug) logger.debug("addNotificationListener"+
+ "(ObjectName,ObjectName,NotificationFilter,Object)",
+ "connectionId=" + connectionId
+ +", name=" + name
+ +", listenerName=" + listener
+ +", filter=" + filterValue
+ +", handback=" + handbackValue);
+
+ doPrivilegedOperation(
+ ADD_NOTIFICATION_LISTENER_OBJECTNAME,
+ params,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof InstanceNotFoundException)
+ throw (InstanceNotFoundException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ public void removeNotificationListeners(ObjectName name,
+ Integer[] listenerIDs,
+ Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ ListenerNotFoundException,
+ IOException {
+
+ if (name == null || listenerIDs == null)
+ throw new IllegalArgumentException("Illegal null parameter");
+
+ for (int i = 0; i < listenerIDs.length; i++) {
+ if (listenerIDs[i] == null)
+ throw new IllegalArgumentException("Null listener ID");
+ }
+
+ try {
+ final Object params[] = new Object[] { name, listenerIDs };
+
+ if (logger.debugOn()) logger.debug("removeNotificationListener"+
+ "(ObjectName,Integer[])",
+ "connectionId=" + connectionId
+ +", name=" + name
+ +", listenerIDs=" + objects(listenerIDs));
+
+ doPrivilegedOperation(
+ REMOVE_NOTIFICATION_LISTENER,
+ params,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof InstanceNotFoundException)
+ throw (InstanceNotFoundException) e;
+ if (e instanceof ListenerNotFoundException)
+ throw (ListenerNotFoundException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ public void removeNotificationListener(ObjectName name,
+ ObjectName listener,
+ Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ ListenerNotFoundException,
+ IOException {
+
+ checkNonNull("Target MBean name", name);
+ checkNonNull("Listener MBean name", listener);
+
+ try {
+ final Object params[] = new Object[] { name, listener };
+
+ if (logger.debugOn()) logger.debug("removeNotificationListener"+
+ "(ObjectName,ObjectName)",
+ "connectionId=" + connectionId
+ +", name=" + name
+ +", listenerName=" + listener);
+
+ doPrivilegedOperation(
+ REMOVE_NOTIFICATION_LISTENER_OBJECTNAME,
+ params,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof InstanceNotFoundException)
+ throw (InstanceNotFoundException) e;
+ if (e instanceof ListenerNotFoundException)
+ throw (ListenerNotFoundException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ @SuppressWarnings("rawtypes") // MarshalledObject
+ public void removeNotificationListener(ObjectName name,
+ ObjectName listener,
+ MarshalledObject filter,
+ MarshalledObject handback,
+ Subject delegationSubject)
+ throws
+ InstanceNotFoundException,
+ ListenerNotFoundException,
+ IOException {
+
+ checkNonNull("Target MBean name", name);
+ checkNonNull("Listener MBean name", listener);
+
+ final NotificationFilter filterValue;
+ final Object handbackValue;
+ final boolean debug=logger.debugOn();
+
+ final ClassLoader targetCl = getClassLoaderFor(name);
+
+ if (debug) logger.debug("removeNotificationListener"+
+ "(ObjectName,ObjectName,NotificationFilter,Object)",
+ "connectionId=" + connectionId
+ +" unwrapping filter with target extended ClassLoader.");
+
+ filterValue =
+ unwrap(filter, targetCl, defaultClassLoader, NotificationFilter.class, delegationSubject);
+
+ if (debug) logger.debug("removeNotificationListener"+
+ "(ObjectName,ObjectName,NotificationFilter,Object)",
+ "connectionId=" + connectionId
+ +" unwrapping handback with target extended ClassLoader.");
+
+ handbackValue =
+ unwrap(handback, targetCl, defaultClassLoader, Object.class, delegationSubject);
+
+ try {
+ final Object params[] =
+ new Object[] { name, listener, filterValue, handbackValue };
+
+ if (debug) logger.debug("removeNotificationListener"+
+ "(ObjectName,ObjectName,NotificationFilter,Object)",
+ "connectionId=" + connectionId
+ +", name=" + name
+ +", listenerName=" + listener
+ +", filter=" + filterValue
+ +", handback=" + handbackValue);
+
+ doPrivilegedOperation(
+ REMOVE_NOTIFICATION_LISTENER_OBJECTNAME_FILTER_HANDBACK,
+ params,
+ delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof InstanceNotFoundException)
+ throw (InstanceNotFoundException) e;
+ if (e instanceof ListenerNotFoundException)
+ throw (ListenerNotFoundException) e;
+ if (e instanceof IOException)
+ throw (IOException) e;
+ throw newIOException("Got unexpected server exception: " + e, e);
+ }
+ }
+
+ public NotificationResult fetchNotifications(long clientSequenceNumber,
+ int maxNotifications,
+ long timeout)
+ throws IOException {
+
+ if (logger.debugOn()) logger.debug("fetchNotifications",
+ "connectionId=" + connectionId
+ +", timeout=" + timeout);
+
+ if (maxNotifications < 0 || timeout < 0)
+ throw new IllegalArgumentException("Illegal negative argument");
+
+ final boolean serverTerminated =
+ serverCommunicatorAdmin.reqIncoming();
+ try {
+ if (serverTerminated) {
+ // we must not call fetchNotifs() if the server is
+ // terminated (timeout elapsed).
+ // returns null to force the client to stop fetching
+ if (logger.debugOn()) logger.debug("fetchNotifications",
+ "The notification server has been closed, "
+ + "returns null to force the client to stop fetching");
+ return null;
+ }
+ final long csn = clientSequenceNumber;
+ final int mn = maxNotifications;
+ final long t = timeout;
+ PrivilegedAction<NotificationResult> action =
+ new PrivilegedAction<NotificationResult>() {
+ public NotificationResult run() {
+ return getServerNotifFwd().fetchNotifs(csn, t, mn);
+ }
+ };
+ if (acc == null)
+ return action.run();
+ else
+ return AccessController.doPrivileged(action, acc);
+ } finally {
+ serverCommunicatorAdmin.rspOutgoing();
+ }
+ }
+
+ /**
+ * <p>Returns a string representation of this object. In general,
+ * the <code>toString</code> method returns a string that
+ * "textually represents" this object. The result should be a
+ * concise but informative representation that is easy for a
+ * person to read.</p>
+ *
+ * @return a String representation of this object.
+ **/
+ @Override
+ public String toString() {
+ return super.toString() + ": connectionId=" + connectionId;
+ }
+
+ //------------------------------------------------------------------------
+ // private classes
+ //------------------------------------------------------------------------
+
+ private class PrivilegedOperation
+ implements PrivilegedExceptionAction<Object> {
+
+ public PrivilegedOperation(int operation, Object[] params) {
+ this.operation = operation;
+ this.params = params;
+ }
+
+ public Object run() throws Exception {
+ return doOperation(operation, params);
+ }
+
+ private int operation;
+ private Object[] params;
+ }
+
+ //------------------------------------------------------------------------
+ // private classes
+ //------------------------------------------------------------------------
+ private class RMIServerCommunicatorAdmin extends ServerCommunicatorAdmin {
+ public RMIServerCommunicatorAdmin(long timeout) {
+ super(timeout);
+ }
+
+ protected void doStop() {
+ try {
+ close();
+ } catch (IOException ie) {
+ logger.warning("RMIServerCommunicatorAdmin-doStop",
+ "Failed to close: " + ie);
+ logger.debug("RMIServerCommunicatorAdmin-doStop",ie);
+ }
+ }
+
+ }
+
+
+ //------------------------------------------------------------------------
+ // private methods
+ //------------------------------------------------------------------------
+
+ private ClassLoader getClassLoader(final ObjectName name)
+ throws InstanceNotFoundException {
+ try {
+ return
+ AccessController.doPrivileged(
+ new PrivilegedExceptionAction<ClassLoader>() {
+ public ClassLoader run() throws InstanceNotFoundException {
+ return mbeanServer.getClassLoader(name);
+ }
+ },
+ withPermissions(new MBeanPermission("*", "getClassLoader"))
+ );
+ } catch (PrivilegedActionException pe) {
+ throw (InstanceNotFoundException) extractException(pe);
+ }
+ }
+
+ private ClassLoader getClassLoaderFor(final ObjectName name)
+ throws InstanceNotFoundException {
+ try {
+ return (ClassLoader)
+ AccessController.doPrivileged(
+ new PrivilegedExceptionAction<Object>() {
+ public Object run() throws InstanceNotFoundException {
+ return mbeanServer.getClassLoaderFor(name);
+ }
+ },
+ withPermissions(new MBeanPermission("*", "getClassLoaderFor"))
+ );
+ } catch (PrivilegedActionException pe) {
+ throw (InstanceNotFoundException) extractException(pe);
+ }
+ }
+
+ private Object doPrivilegedOperation(final int operation,
+ final Object[] params,
+ final Subject delegationSubject)
+ throws PrivilegedActionException, IOException {
+
+ serverCommunicatorAdmin.reqIncoming();
+ try {
+
+ final AccessControlContext reqACC;
+ if (delegationSubject == null)
+ reqACC = acc;
+ else {
+ if (subject == null) {
+ final String msg =
+ "Subject delegation cannot be enabled unless " +
+ "an authenticated subject is put in place";
+ throw new SecurityException(msg);
+ }
+ reqACC = subjectDelegator.delegatedContext(
+ acc, delegationSubject, removeCallerContext);
+ }
+
+ PrivilegedOperation op =
+ new PrivilegedOperation(operation, params);
+ if (reqACC == null) {
+ try {
+ return op.run();
+ } catch (Exception e) {
+ if (e instanceof RuntimeException)
+ throw (RuntimeException) e;
+ throw new PrivilegedActionException(e);
+ }
+ } else {
+ return AccessController.doPrivileged(op, reqACC);
+ }
+ } catch (Error e) {
+ throw new JMXServerErrorException(e.toString(),e);
+ } finally {
+ serverCommunicatorAdmin.rspOutgoing();
+ }
+ }
+
+ private Object doOperation(int operation, Object[] params)
+ throws Exception {
+
+ switch (operation) {
+
+ case CREATE_MBEAN:
+ return mbeanServer.createMBean((String)params[0],
+ (ObjectName)params[1]);
+
+ case CREATE_MBEAN_LOADER:
+ return mbeanServer.createMBean((String)params[0],
+ (ObjectName)params[1],
+ (ObjectName)params[2]);
+
+ case CREATE_MBEAN_PARAMS:
+ return mbeanServer.createMBean((String)params[0],
+ (ObjectName)params[1],
+ (Object[])params[2],
+ (String[])params[3]);
+
+ case CREATE_MBEAN_LOADER_PARAMS:
+ return mbeanServer.createMBean((String)params[0],
+ (ObjectName)params[1],
+ (ObjectName)params[2],
+ (Object[])params[3],
+ (String[])params[4]);
+
+ case GET_ATTRIBUTE:
+ return mbeanServer.getAttribute((ObjectName)params[0],
+ (String)params[1]);
+
+ case GET_ATTRIBUTES:
+ return mbeanServer.getAttributes((ObjectName)params[0],
+ (String[])params[1]);
+
+ case GET_DEFAULT_DOMAIN:
+ return mbeanServer.getDefaultDomain();
+
+ case GET_DOMAINS:
+ return mbeanServer.getDomains();
+
+ case GET_MBEAN_COUNT:
+ return mbeanServer.getMBeanCount();
+
+ case GET_MBEAN_INFO:
+ return mbeanServer.getMBeanInfo((ObjectName)params[0]);
+
+ case GET_OBJECT_INSTANCE:
+ return mbeanServer.getObjectInstance((ObjectName)params[0]);
+
+ case INVOKE:
+ return mbeanServer.invoke((ObjectName)params[0],
+ (String)params[1],
+ (Object[])params[2],
+ (String[])params[3]);
+
+ case IS_INSTANCE_OF:
+ return mbeanServer.isInstanceOf((ObjectName)params[0],
+ (String)params[1])
+ ? Boolean.TRUE : Boolean.FALSE;
+
+ case IS_REGISTERED:
+ return mbeanServer.isRegistered((ObjectName)params[0])
+ ? Boolean.TRUE : Boolean.FALSE;
+
+ case QUERY_MBEANS:
+ return mbeanServer.queryMBeans((ObjectName)params[0],
+ (QueryExp)params[1]);
+
+ case QUERY_NAMES:
+ return mbeanServer.queryNames((ObjectName)params[0],
+ (QueryExp)params[1]);
+
+ case SET_ATTRIBUTE:
+ mbeanServer.setAttribute((ObjectName)params[0],
+ (Attribute)params[1]);
+ return null;
+
+ case SET_ATTRIBUTES:
+ return mbeanServer.setAttributes((ObjectName)params[0],
+ (AttributeList)params[1]);
+
+ case UNREGISTER_MBEAN:
+ mbeanServer.unregisterMBean((ObjectName)params[0]);
+ return null;
+
+ case ADD_NOTIFICATION_LISTENERS:
+ return getServerNotifFwd().addNotificationListener(
+ (ObjectName)params[0],
+ (NotificationFilter)params[1]);
+
+ case ADD_NOTIFICATION_LISTENER_OBJECTNAME:
+ mbeanServer.addNotificationListener((ObjectName)params[0],
+ (ObjectName)params[1],
+ (NotificationFilter)params[2],
+ params[3]);
+ return null;
+
+ case REMOVE_NOTIFICATION_LISTENER:
+ getServerNotifFwd().removeNotificationListener(
+ (ObjectName)params[0],
+ (Integer[])params[1]);
+ return null;
+
+ case REMOVE_NOTIFICATION_LISTENER_OBJECTNAME:
+ mbeanServer.removeNotificationListener((ObjectName)params[0],
+ (ObjectName)params[1]);
+ return null;
+
+ case REMOVE_NOTIFICATION_LISTENER_OBJECTNAME_FILTER_HANDBACK:
+ mbeanServer.removeNotificationListener(
+ (ObjectName)params[0],
+ (ObjectName)params[1],
+ (NotificationFilter)params[2],
+ params[3]);
+ return null;
+
+ default:
+ throw new IllegalArgumentException("Invalid operation");
+ }
+ }
+
+ private static class SetCcl implements PrivilegedExceptionAction<ClassLoader> {
+ private final ClassLoader classLoader;
+
+ SetCcl(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
+ public ClassLoader run() {
+ Thread currentThread = Thread.currentThread();
+ ClassLoader old = currentThread.getContextClassLoader();
+ currentThread.setContextClassLoader(classLoader);
+ return old;
+ }
+ }
+
+ private <T> T unwrap(final MarshalledObject<?> mo,
+ final ClassLoader cl,
+ final Class<T> wrappedClass,
+ Subject delegationSubject)
+ throws IOException {
+ if (mo == null) {
+ return null;
+ }
+ try {
+ final ClassLoader old = AccessController.doPrivileged(new SetCcl(cl));
+ try{
+ final AccessControlContext reqACC;
+ if (delegationSubject == null)
+ reqACC = acc;
+ else {
+ if (subject == null) {
+ final String msg =
+ "Subject delegation cannot be enabled unless " +
+ "an authenticated subject is put in place";
+ throw new SecurityException(msg);
+ }
+ reqACC = subjectDelegator.delegatedContext(
+ acc, delegationSubject, removeCallerContext);
+ }
+ if(reqACC != null){
+ return AccessController.doPrivileged(
+ (PrivilegedExceptionAction<T>) () ->
+ wrappedClass.cast(mo.get()), reqACC);
+ }else{
+ return wrappedClass.cast(mo.get());
+ }
+ }finally{
+ AccessController.doPrivileged(new SetCcl(old));
+ }
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof IOException) {
+ throw (IOException) e;
+ }
+ if (e instanceof ClassNotFoundException) {
+ throw new UnmarshalException(e.toString(), e);
+ }
+ logger.warning("unwrap", "Failed to unmarshall object: " + e);
+ logger.debug("unwrap", e);
+ }catch (ClassNotFoundException ex) {
+ logger.warning("unwrap", "Failed to unmarshall object: " + ex);
+ logger.debug("unwrap", ex);
+ throw new UnmarshalException(ex.toString(), ex);
+ }
+ return null;
+ }
+
+ private <T> T unwrap(final MarshalledObject<?> mo,
+ final ClassLoader cl1,
+ final ClassLoader cl2,
+ final Class<T> wrappedClass,
+ Subject delegationSubject)
+ throws IOException {
+ if (mo == null) {
+ return null;
+ }
+ try {
+ ClassLoader orderCL = AccessController.doPrivileged(
+ new PrivilegedExceptionAction<ClassLoader>() {
+ public ClassLoader run() throws Exception {
+ return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(),
+ new OrderClassLoaders(cl1, cl2));
+ }
+ }
+ );
+ return unwrap(mo, orderCL, wrappedClass,delegationSubject);
+ } catch (PrivilegedActionException pe) {
+ Exception e = extractException(pe);
+ if (e instanceof IOException) {
+ throw (IOException) e;
+ }
+ if (e instanceof ClassNotFoundException) {
+ throw new UnmarshalException(e.toString(), e);
+ }
+ logger.warning("unwrap", "Failed to unmarshall object: " + e);
+ logger.debug("unwrap", e);
+ }
+ return null;
+ }
+
+ /**
+ * Construct a new IOException with a nested exception.
+ * The nested exception is set only if JDK {@literal >= 1.4}
+ */
+ private static IOException newIOException(String message,
+ Throwable cause) {
+ final IOException x = new IOException(message);
+ return EnvHelp.initCause(x,cause);
+ }
+
+ /**
+ * Iterate until we extract the real exception
+ * from a stack of PrivilegedActionExceptions.
+ */
+ private static Exception extractException(Exception e) {
+ while (e instanceof PrivilegedActionException) {
+ e = ((PrivilegedActionException)e).getException();
+ }
+ return e;
+ }
+
+ private static final Object[] NO_OBJECTS = new Object[0];
+ private static final String[] NO_STRINGS = new String[0];
+
+ /*
+ * The JMX spec doesn't explicitly say that a null Object[] or
+ * String[] in e.g. MBeanServer.invoke is equivalent to an empty
+ * array, but the RI behaves that way. In the interests of
+ * maximal interoperability, we make it so even when we're
+ * connected to some other JMX implementation that might not do
+ * that. This should be clarified in the next version of JMX.
+ */
+ private static Object[] nullIsEmpty(Object[] array) {
+ return (array == null) ? NO_OBJECTS : array;
+ }
+
+ private static String[] nullIsEmpty(String[] array) {
+ return (array == null) ? NO_STRINGS : array;
+ }
+
+ /*
+ * Similarly, the JMX spec says for some but not all methods in
+ * MBeanServer that take an ObjectName target, that if it's null
+ * you get this exception. We specify it for all of them, and
+ * make it so for the ones where it's not specified in JMX even if
+ * the JMX implementation doesn't do so.
+ */
+ private static void checkNonNull(String what, Object x) {
+ if (x == null) {
+ RuntimeException wrapped =
+ new IllegalArgumentException(what + " must not be null");
+ throw new RuntimeOperationsException(wrapped);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ // private variables
+ //------------------------------------------------------------------------
+
+ private final Subject subject;
+
+ private final SubjectDelegator subjectDelegator;
+
+ private final boolean removeCallerContext;
+
+ private final AccessControlContext acc;
+
+ private final RMIServerImpl rmiServer;
+
+ private final MBeanServer mbeanServer;
+
+ private final ClassLoader defaultClassLoader;
+
+ private final ClassLoader defaultContextClassLoader;
+
+ private final ClassLoaderWithRepository classLoaderWithRepository;
+
+ private boolean terminated = false;
+
+ private final String connectionId;
+
+ private final ServerCommunicatorAdmin serverCommunicatorAdmin;
+
+ // Method IDs for doOperation
+ //---------------------------
+
+ private final static int
+ ADD_NOTIFICATION_LISTENERS = 1;
+ private final static int
+ ADD_NOTIFICATION_LISTENER_OBJECTNAME = 2;
+ private final static int
+ CREATE_MBEAN = 3;
+ private final static int
+ CREATE_MBEAN_PARAMS = 4;
+ private final static int
+ CREATE_MBEAN_LOADER = 5;
+ private final static int
+ CREATE_MBEAN_LOADER_PARAMS = 6;
+ private final static int
+ GET_ATTRIBUTE = 7;
+ private final static int
+ GET_ATTRIBUTES = 8;
+ private final static int
+ GET_DEFAULT_DOMAIN = 9;
+ private final static int
+ GET_DOMAINS = 10;
+ private final static int
+ GET_MBEAN_COUNT = 11;
+ private final static int
+ GET_MBEAN_INFO = 12;
+ private final static int
+ GET_OBJECT_INSTANCE = 13;
+ private final static int
+ INVOKE = 14;
+ private final static int
+ IS_INSTANCE_OF = 15;
+ private final static int
+ IS_REGISTERED = 16;
+ private final static int
+ QUERY_MBEANS = 17;
+ private final static int
+ QUERY_NAMES = 18;
+ private final static int
+ REMOVE_NOTIFICATION_LISTENER = 19;
+ private final static int
+ REMOVE_NOTIFICATION_LISTENER_OBJECTNAME = 20;
+ private final static int
+ REMOVE_NOTIFICATION_LISTENER_OBJECTNAME_FILTER_HANDBACK = 21;
+ private final static int
+ SET_ATTRIBUTE = 22;
+ private final static int
+ SET_ATTRIBUTES = 23;
+ private final static int
+ UNREGISTER_MBEAN = 24;
+
+ // SERVER NOTIFICATION
+ //--------------------
+
+ private ServerNotifForwarder serverNotifForwarder;
+ private Map<String, ?> env;
+
+ // TRACES & DEBUG
+ //---------------
+
+ private static String objects(final Object[] objs) {
+ if (objs == null)
+ return "null";
+ else
+ return Arrays.asList(objs).toString();
+ }
+
+ private static String strings(final String[] strs) {
+ return objects(strs);
+ }
+
+ private static final ClassLogger logger =
+ new ClassLogger("javax.management.remote.rmi", "RMIConnectionImpl");
+
+ private static final class CombinedClassLoader extends ClassLoader {
+
+ private final static class ClassLoaderWrapper extends ClassLoader {
+ ClassLoaderWrapper(ClassLoader cl) {
+ super(cl);
+ }
+
+ @Override
+ protected Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
+ return super.loadClass(name, resolve);
+ }
+ };
+
+ final ClassLoaderWrapper defaultCL;
+
+ private CombinedClassLoader(ClassLoader parent, ClassLoader defaultCL) {
+ super(parent);
+ this.defaultCL = new ClassLoaderWrapper(defaultCL);
+ }
+
+ @Override
+ protected Class<?> loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
+ ReflectUtil.checkPackageAccess(name);
+ try {
+ super.loadClass(name, resolve);
+ } catch(Exception e) {
+ for(Throwable t = e; t != null; t = t.getCause()) {
+ if(t instanceof SecurityException) {
+ throw t==e?(SecurityException)t:new SecurityException(t.getMessage(), e);
+ }
+ }
+ }
+ final Class<?> cl = defaultCL.loadClass(name, resolve);
+ return cl;
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnector.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,2309 @@
+/*
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.management.remote.rmi;
+
+import com.sun.jmx.remote.internal.ClientCommunicatorAdmin;
+import com.sun.jmx.remote.internal.ClientListenerInfo;
+import com.sun.jmx.remote.internal.ClientNotifForwarder;
+import com.sun.jmx.remote.internal.rmi.ProxyRef;
+import com.sun.jmx.remote.util.ClassLogger;
+import com.sun.jmx.remote.util.EnvHelp;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamClass;
+import java.io.Serializable;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Module;
+import java.lang.reflect.Proxy;
+import java.net.MalformedURLException;
+import java.rmi.MarshalledObject;
+import java.rmi.NoSuchObjectException;
+import java.rmi.Remote;
+import java.rmi.ServerException;
+import java.rmi.UnmarshalException;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RemoteObject;
+import java.rmi.server.RemoteObjectInvocationHandler;
+import java.rmi.server.RemoteRef;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.WeakHashMap;
+import java.util.stream.Collectors;
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.InstanceNotFoundException;
+import javax.management.IntrospectionException;
+import javax.management.InvalidAttributeValueException;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServerConnection;
+import javax.management.MBeanServerDelegate;
+import javax.management.MBeanServerNotification;
+import javax.management.NotCompliantMBeanException;
+import javax.management.Notification;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationFilter;
+import javax.management.NotificationFilterSupport;
+import javax.management.NotificationListener;
+import javax.management.ObjectInstance;
+import javax.management.ObjectName;
+import javax.management.QueryExp;
+import javax.management.ReflectionException;
+import javax.management.remote.JMXConnectionNotification;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorFactory;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.NotificationResult;
+import javax.management.remote.JMXAddressable;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.rmi.ssl.SslRMIClientSocketFactory;
+import javax.security.auth.Subject;
+import jdk.internal.module.Modules;
+import sun.reflect.misc.ReflectUtil;
+import sun.rmi.server.UnicastRef2;
+import sun.rmi.transport.LiveRef;
+import java.io.NotSerializableException;
+
+/**
+ * <p>A connection to a remote RMI connector. Usually, such
+ * connections are made using {@link
+ * javax.management.remote.JMXConnectorFactory JMXConnectorFactory}.
+ * However, specialized applications can use this class directly, for
+ * example with an {@link RMIServer} stub obtained without going
+ * through JNDI.</p>
+ *
+ * @since 1.5
+ */
+public class RMIConnector implements JMXConnector, Serializable, JMXAddressable {
+
+ private static final ClassLogger logger =
+ new ClassLogger("javax.management.remote.rmi", "RMIConnector");
+
+ private static final long serialVersionUID = 817323035842634473L;
+
+ static final class Util {
+ private Util() {}
+
+ /* This method can be used by code that is deliberately violating the
+ * allowed checked casts. Rather than marking the whole method containing
+ * the code with @SuppressWarnings, you can use a call to this method for
+ * the exact place where you need to escape the constraints. Typically
+ * you will "import static" this method and then write either
+ * X x = cast(y);
+ * or, if that doesn't work (e.g. X is a type variable)
+ * Util.<X>cast(y);
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T cast(Object x) {
+ return (T) x;
+ }
+ }
+
+ private RMIConnector(RMIServer rmiServer, JMXServiceURL address,
+ Map<String, ?> environment) {
+ if (rmiServer == null && address == null) throw new
+ IllegalArgumentException("rmiServer and jmxServiceURL both null");
+ initTransients();
+
+ this.rmiServer = rmiServer;
+ this.jmxServiceURL = address;
+ if (environment == null) {
+ this.env = Collections.emptyMap();
+ } else {
+ EnvHelp.checkAttributes(environment);
+ this.env = Collections.unmodifiableMap(environment);
+ }
+ }
+
+ /**
+ * <p>Constructs an {@code RMIConnector} that will connect
+ * the RMI connector server with the given address.</p>
+ *
+ * <p>The address can refer directly to the connector server,
+ * using the following syntax:</p>
+ *
+ * <pre>
+ * service:jmx:rmi://<em>[host[:port]]</em>/stub/<em>encoded-stub</em>
+ * </pre>
+ *
+ * <p>(Here, the square brackets {@code []} are not part of the
+ * address but indicate that the host and port are optional.)</p>
+ *
+ * <p>The address can instead indicate where to find an RMI stub
+ * through JNDI, using the following syntax:</p>
+ *
+ * <pre>
+ * service:jmx:rmi://<em>[host[:port]]</em>/jndi/<em>jndi-name</em>
+ * </pre>
+ *
+ * <p>An implementation may also recognize additional address
+ * syntaxes, for example:</p>
+ *
+ * <pre>
+ * service:jmx:iiop://<em>[host[:port]]</em>/stub/<em>encoded-stub</em>
+ * </pre>
+ *
+ * @param url the address of the RMI connector server.
+ *
+ * @param environment additional attributes specifying how to make
+ * the connection. For JNDI-based addresses, these attributes can
+ * usefully include JNDI attributes recognized by {@link
+ * InitialContext#InitialContext(Hashtable) InitialContext}. This
+ * parameter can be null, which is equivalent to an empty Map.
+ *
+ * @exception IllegalArgumentException if {@code url}
+ * is null.
+ */
+ public RMIConnector(JMXServiceURL url, Map<String,?> environment) {
+ this(null, url, environment);
+ }
+
+ /**
+ * <p>Constructs an {@code RMIConnector} using the given RMI stub.
+ *
+ * @param rmiServer an RMI stub representing the RMI connector server.
+ * @param environment additional attributes specifying how to make
+ * the connection. This parameter can be null, which is
+ * equivalent to an empty Map.
+ *
+ * @exception IllegalArgumentException if {@code rmiServer}
+ * is null.
+ */
+ public RMIConnector(RMIServer rmiServer, Map<String,?> environment) {
+ this(rmiServer, null, environment);
+ }
+
+ /**
+ * <p>Returns a string representation of this object. In general,
+ * the {@code toString} method returns a string that
+ * "textually represents" this object. The result should be a
+ * concise but informative representation that is easy for a
+ * person to read.</p>
+ *
+ * @return a String representation of this object.
+ **/
+ @Override
+ public String toString() {
+ final StringBuilder b = new StringBuilder(this.getClass().getName());
+ b.append(":");
+ if (rmiServer != null) {
+ b.append(" rmiServer=").append(rmiServer.toString());
+ }
+ if (jmxServiceURL != null) {
+ if (rmiServer!=null) b.append(",");
+ b.append(" jmxServiceURL=").append(jmxServiceURL.toString());
+ }
+ return b.toString();
+ }
+
+ /**
+ * <p>The address of this connector.</p>
+ *
+ * @return the address of this connector, or null if it
+ * does not have one.
+ *
+ * @since 1.6
+ */
+ public JMXServiceURL getAddress() {
+ return jmxServiceURL;
+ }
+
+ //--------------------------------------------------------------------
+ // implements JMXConnector interface
+ //--------------------------------------------------------------------
+
+ /**
+ * @throws IOException if the connection could not be made because of a
+ * communication problem
+ */
+ public void connect() throws IOException {
+ connect(null);
+ }
+
+ /**
+ * @throws IOException if the connection could not be made because of a
+ * communication problem
+ */
+ public synchronized void connect(Map<String,?> environment)
+ throws IOException {
+ final boolean tracing = logger.traceOn();
+ String idstr = (tracing?"["+this.toString()+"]":null);
+
+ if (terminated) {
+ logger.trace("connect",idstr + " already closed.");
+ throw new IOException("Connector closed");
+ }
+ if (connected) {
+ logger.trace("connect",idstr + " already connected.");
+ return;
+ }
+
+ try {
+ if (tracing) logger.trace("connect",idstr + " connecting...");
+
+ final Map<String, Object> usemap =
+ new HashMap<String, Object>((this.env==null) ?
+ Collections.<String, Object>emptyMap() : this.env);
+
+
+ if (environment != null) {
+ EnvHelp.checkAttributes(environment);
+ usemap.putAll(environment);
+ }
+
+ // Get RMIServer stub from directory or URL encoding if needed.
+ if (tracing) logger.trace("connect",idstr + " finding stub...");
+ RMIServer stub = (rmiServer!=null)?rmiServer:
+ findRMIServer(jmxServiceURL, usemap);
+
+ // Check for secure RMIServer stub if the corresponding
+ // client-side environment property is set to "true".
+ //
+ String stringBoolean = (String) usemap.get("jmx.remote.x.check.stub");
+ boolean checkStub = EnvHelp.computeBooleanFromString(stringBoolean);
+
+ if (checkStub) checkStub(stub, rmiServerImplStubClass);
+
+ if (tracing) logger.trace("connect",idstr + " connecting stub...");
+ idstr = (tracing?"["+this.toString()+"]":null);
+
+ // Calling newClient on the RMIServer stub.
+ if (tracing)
+ logger.trace("connect",idstr + " getting connection...");
+ Object credentials = usemap.get(CREDENTIALS);
+
+ try {
+ connection = getConnection(stub, credentials, checkStub);
+ } catch (java.rmi.RemoteException re) {
+ throw re;
+ }
+
+ // Always use one of:
+ // ClassLoader provided in Map at connect time,
+ // or contextClassLoader at connect time.
+ if (tracing)
+ logger.trace("connect",idstr + " getting class loader...");
+ defaultClassLoader = EnvHelp.resolveClientClassLoader(usemap);
+
+ usemap.put(JMXConnectorFactory.DEFAULT_CLASS_LOADER,
+ defaultClassLoader);
+
+ rmiNotifClient = new RMINotifClient(defaultClassLoader, usemap);
+
+ env = usemap;
+ final long checkPeriod = EnvHelp.getConnectionCheckPeriod(usemap);
+ communicatorAdmin = new RMIClientCommunicatorAdmin(checkPeriod);
+
+ connected = true;
+
+ // The connectionId variable is used in doStart(), when
+ // reconnecting, to identify the "old" connection.
+ //
+ connectionId = getConnectionId();
+
+ Notification connectedNotif =
+ new JMXConnectionNotification(JMXConnectionNotification.OPENED,
+ this,
+ connectionId,
+ clientNotifSeqNo++,
+ "Successful connection",
+ null);
+ sendNotification(connectedNotif);
+
+ if (tracing) logger.trace("connect",idstr + " done...");
+ } catch (IOException e) {
+ if (tracing)
+ logger.trace("connect",idstr + " failed to connect: " + e);
+ throw e;
+ } catch (RuntimeException e) {
+ if (tracing)
+ logger.trace("connect",idstr + " failed to connect: " + e);
+ throw e;
+ } catch (NamingException e) {
+ final String msg = "Failed to retrieve RMIServer stub: " + e;
+ if (tracing) logger.trace("connect",idstr + " " + msg);
+ throw EnvHelp.initCause(new IOException(msg),e);
+ }
+ }
+
+ public synchronized String getConnectionId() throws IOException {
+ if (terminated || !connected) {
+ if (logger.traceOn())
+ logger.trace("getConnectionId","["+this.toString()+
+ "] not connected.");
+
+ throw new IOException("Not connected");
+ }
+
+ // we do a remote call to have an IOException if the connection is broken.
+ // see the bug 4939578
+ return connection.getConnectionId();
+ }
+
+ public synchronized MBeanServerConnection getMBeanServerConnection()
+ throws IOException {
+ return getMBeanServerConnection(null);
+ }
+
+ public synchronized MBeanServerConnection
+ getMBeanServerConnection(Subject delegationSubject)
+ throws IOException {
+
+ if (terminated) {
+ if (logger.traceOn())
+ logger.trace("getMBeanServerConnection","[" + this.toString() +
+ "] already closed.");
+ throw new IOException("Connection closed");
+ } else if (!connected) {
+ if (logger.traceOn())
+ logger.trace("getMBeanServerConnection","[" + this.toString() +
+ "] is not connected.");
+ throw new IOException("Not connected");
+ }
+
+ return getConnectionWithSubject(delegationSubject);
+ }
+
+ public void
+ addConnectionNotificationListener(NotificationListener listener,
+ NotificationFilter filter,
+ Object handback) {
+ if (listener == null)
+ throw new NullPointerException("listener");
+ connectionBroadcaster.addNotificationListener(listener, filter,
+ handback);
+ }
+
+ public void
+ removeConnectionNotificationListener(NotificationListener listener)
+ throws ListenerNotFoundException {
+ if (listener == null)
+ throw new NullPointerException("listener");
+ connectionBroadcaster.removeNotificationListener(listener);
+ }
+
+ public void
+ removeConnectionNotificationListener(NotificationListener listener,
+ NotificationFilter filter,
+ Object handback)
+ throws ListenerNotFoundException {
+ if (listener == null)
+ throw new NullPointerException("listener");
+ connectionBroadcaster.removeNotificationListener(listener, filter,
+ handback);
+ }
+
+ private void sendNotification(Notification n) {
+ connectionBroadcaster.sendNotification(n);
+ }
+
+ public synchronized void close() throws IOException {
+ close(false);
+ }
+
+ // allows to do close after setting the flag "terminated" to true.
+ // It is necessary to avoid a deadlock, see 6296324
+ private synchronized void close(boolean intern) throws IOException {
+ final boolean tracing = logger.traceOn();
+ final boolean debug = logger.debugOn();
+ final String idstr = (tracing?"["+this.toString()+"]":null);
+
+ if (!intern) {
+ // Return if already cleanly closed.
+ //
+ if (terminated) {
+ if (closeException == null) {
+ if (tracing) logger.trace("close",idstr + " already closed.");
+ return;
+ }
+ } else {
+ terminated = true;
+ }
+ }
+
+ if (closeException != null && tracing) {
+ // Already closed, but not cleanly. Attempt again.
+ //
+ if (tracing) {
+ logger.trace("close",idstr + " had failed: " + closeException);
+ logger.trace("close",idstr + " attempting to close again.");
+ }
+ }
+
+ String savedConnectionId = null;
+ if (connected) {
+ savedConnectionId = connectionId;
+ }
+
+ closeException = null;
+
+ if (tracing) logger.trace("close",idstr + " closing.");
+
+ if (communicatorAdmin != null) {
+ communicatorAdmin.terminate();
+ }
+
+ if (rmiNotifClient != null) {
+ try {
+ rmiNotifClient.terminate();
+ if (tracing) logger.trace("close",idstr +
+ " RMI Notification client terminated.");
+ } catch (RuntimeException x) {
+ closeException = x;
+ if (tracing) logger.trace("close",idstr +
+ " Failed to terminate RMI Notification client: " + x);
+ if (debug) logger.debug("close",x);
+ }
+ }
+
+ if (connection != null) {
+ try {
+ connection.close();
+ if (tracing) logger.trace("close",idstr + " closed.");
+ } catch (NoSuchObjectException nse) {
+ // OK, the server maybe closed itself.
+ } catch (IOException e) {
+ closeException = e;
+ if (tracing) logger.trace("close",idstr +
+ " Failed to close RMIServer: " + e);
+ if (debug) logger.debug("close",e);
+ }
+ }
+
+ // Clean up MBeanServerConnection table
+ //
+ rmbscMap.clear();
+
+ /* Send notification of closure. We don't do this if the user
+ * never called connect() on the connector, because there's no
+ * connection id in that case. */
+
+ if (savedConnectionId != null) {
+ Notification closedNotif =
+ new JMXConnectionNotification(JMXConnectionNotification.CLOSED,
+ this,
+ savedConnectionId,
+ clientNotifSeqNo++,
+ "Client has been closed",
+ null);
+ sendNotification(closedNotif);
+ }
+
+ // throw exception if needed
+ //
+ if (closeException != null) {
+ if (tracing) logger.trace("close",idstr + " failed to close: " +
+ closeException);
+ if (closeException instanceof IOException)
+ throw (IOException) closeException;
+ if (closeException instanceof RuntimeException)
+ throw (RuntimeException) closeException;
+ final IOException x =
+ new IOException("Failed to close: " + closeException);
+ throw EnvHelp.initCause(x,closeException);
+ }
+ }
+
+ // added for re-connection
+ private Integer addListenerWithSubject(ObjectName name,
+ MarshalledObject<NotificationFilter> filter,
+ Subject delegationSubject,
+ boolean reconnect)
+ throws InstanceNotFoundException, IOException {
+
+ final boolean debug = logger.debugOn();
+ if (debug)
+ logger.debug("addListenerWithSubject",
+ "(ObjectName,MarshalledObject,Subject)");
+
+ final ObjectName[] names = new ObjectName[] {name};
+ final MarshalledObject<NotificationFilter>[] filters =
+ Util.cast(new MarshalledObject<?>[] {filter});
+ final Subject[] delegationSubjects = new Subject[] {
+ delegationSubject
+ };
+
+ final Integer[] listenerIDs =
+ addListenersWithSubjects(names,filters,delegationSubjects,
+ reconnect);
+
+ if (debug) logger.debug("addListenerWithSubject","listenerID="
+ + listenerIDs[0]);
+ return listenerIDs[0];
+ }
+
+ // added for re-connection
+ private Integer[] addListenersWithSubjects(ObjectName[] names,
+ MarshalledObject<NotificationFilter>[] filters,
+ Subject[] delegationSubjects,
+ boolean reconnect)
+ throws InstanceNotFoundException, IOException {
+
+ final boolean debug = logger.debugOn();
+ if (debug)
+ logger.debug("addListenersWithSubjects",
+ "(ObjectName[],MarshalledObject[],Subject[])");
+
+ final ClassLoader old = pushDefaultClassLoader();
+ Integer[] listenerIDs = null;
+
+ try {
+ listenerIDs = connection.addNotificationListeners(names,
+ filters,
+ delegationSubjects);
+ } catch (NoSuchObjectException noe) {
+ // maybe reconnect
+ if (reconnect) {
+ communicatorAdmin.gotIOException(noe);
+
+ listenerIDs = connection.addNotificationListeners(names,
+ filters,
+ delegationSubjects);
+ } else {
+ throw noe;
+ }
+ } catch (IOException ioe) {
+ // send a failed notif if necessary
+ communicatorAdmin.gotIOException(ioe);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+
+ if (debug) logger.debug("addListenersWithSubjects","registered "
+ + ((listenerIDs==null)?0:listenerIDs.length)
+ + " listener(s)");
+ return listenerIDs;
+ }
+
+ //--------------------------------------------------------------------
+ // Implementation of MBeanServerConnection
+ //--------------------------------------------------------------------
+ private class RemoteMBeanServerConnection implements MBeanServerConnection {
+ private Subject delegationSubject;
+
+ public RemoteMBeanServerConnection() {
+ this(null);
+ }
+
+ public RemoteMBeanServerConnection(Subject delegationSubject) {
+ this.delegationSubject = delegationSubject;
+ }
+
+ public ObjectInstance createMBean(String className,
+ ObjectName name)
+ throws ReflectionException,
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ MBeanException,
+ NotCompliantMBeanException,
+ IOException {
+ if (logger.debugOn())
+ logger.debug("createMBean(String,ObjectName)",
+ "className=" + className + ", name=" +
+ name);
+
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.createMBean(className,
+ name,
+ delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.createMBean(className,
+ name,
+ delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public ObjectInstance createMBean(String className,
+ ObjectName name,
+ ObjectName loaderName)
+ throws ReflectionException,
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ MBeanException,
+ NotCompliantMBeanException,
+ InstanceNotFoundException,
+ IOException {
+
+ if (logger.debugOn())
+ logger.debug("createMBean(String,ObjectName,ObjectName)",
+ "className=" + className + ", name="
+ + name + ", loaderName="
+ + loaderName + ")");
+
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.createMBean(className,
+ name,
+ loaderName,
+ delegationSubject);
+
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.createMBean(className,
+ name,
+ loaderName,
+ delegationSubject);
+
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public ObjectInstance createMBean(String className,
+ ObjectName name,
+ Object params[],
+ String signature[])
+ throws ReflectionException,
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ MBeanException,
+ NotCompliantMBeanException,
+ IOException {
+ if (logger.debugOn())
+ logger.debug("createMBean(String,ObjectName,Object[],String[])",
+ "className=" + className + ", name="
+ + name + ", signature=" + strings(signature));
+
+ final MarshalledObject<Object[]> sParams =
+ new MarshalledObject<Object[]>(params);
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.createMBean(className,
+ name,
+ sParams,
+ signature,
+ delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.createMBean(className,
+ name,
+ sParams,
+ signature,
+ delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public ObjectInstance createMBean(String className,
+ ObjectName name,
+ ObjectName loaderName,
+ Object params[],
+ String signature[])
+ throws ReflectionException,
+ InstanceAlreadyExistsException,
+ MBeanRegistrationException,
+ MBeanException,
+ NotCompliantMBeanException,
+ InstanceNotFoundException,
+ IOException {
+ if (logger.debugOn()) logger.debug(
+ "createMBean(String,ObjectName,ObjectName,Object[],String[])",
+ "className=" + className + ", name=" + name + ", loaderName="
+ + loaderName + ", signature=" + strings(signature));
+
+ final MarshalledObject<Object[]> sParams =
+ new MarshalledObject<Object[]>(params);
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.createMBean(className,
+ name,
+ loaderName,
+ sParams,
+ signature,
+ delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.createMBean(className,
+ name,
+ loaderName,
+ sParams,
+ signature,
+ delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public void unregisterMBean(ObjectName name)
+ throws InstanceNotFoundException,
+ MBeanRegistrationException,
+ IOException {
+ if (logger.debugOn())
+ logger.debug("unregisterMBean", "name=" + name);
+
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ connection.unregisterMBean(name, delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ connection.unregisterMBean(name, delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public ObjectInstance getObjectInstance(ObjectName name)
+ throws InstanceNotFoundException,
+ IOException {
+ if (logger.debugOn())
+ logger.debug("getObjectInstance", "name=" + name);
+
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.getObjectInstance(name, delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.getObjectInstance(name, delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public Set<ObjectInstance> queryMBeans(ObjectName name,
+ QueryExp query)
+ throws IOException {
+ if (logger.debugOn()) logger.debug("queryMBeans",
+ "name=" + name + ", query=" + query);
+
+ final MarshalledObject<QueryExp> sQuery =
+ new MarshalledObject<QueryExp>(query);
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.queryMBeans(name, sQuery, delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.queryMBeans(name, sQuery, delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public Set<ObjectName> queryNames(ObjectName name,
+ QueryExp query)
+ throws IOException {
+ if (logger.debugOn()) logger.debug("queryNames",
+ "name=" + name + ", query=" + query);
+
+ final MarshalledObject<QueryExp> sQuery =
+ new MarshalledObject<QueryExp>(query);
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.queryNames(name, sQuery, delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.queryNames(name, sQuery, delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public boolean isRegistered(ObjectName name)
+ throws IOException {
+ if (logger.debugOn())
+ logger.debug("isRegistered", "name=" + name);
+
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.isRegistered(name, delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.isRegistered(name, delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public Integer getMBeanCount()
+ throws IOException {
+ if (logger.debugOn()) logger.debug("getMBeanCount", "");
+
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.getMBeanCount(delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.getMBeanCount(delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public Object getAttribute(ObjectName name,
+ String attribute)
+ throws MBeanException,
+ AttributeNotFoundException,
+ InstanceNotFoundException,
+ ReflectionException,
+ IOException {
+ if (logger.debugOn()) logger.debug("getAttribute",
+ "name=" + name + ", attribute="
+ + attribute);
+
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.getAttribute(name,
+ attribute,
+ delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.getAttribute(name,
+ attribute,
+ delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public AttributeList getAttributes(ObjectName name,
+ String[] attributes)
+ throws InstanceNotFoundException,
+ ReflectionException,
+ IOException {
+ if (logger.debugOn()) logger.debug("getAttributes",
+ "name=" + name + ", attributes="
+ + strings(attributes));
+
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.getAttributes(name,
+ attributes,
+ delegationSubject);
+
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.getAttributes(name,
+ attributes,
+ delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+
+ public void setAttribute(ObjectName name,
+ Attribute attribute)
+ throws InstanceNotFoundException,
+ AttributeNotFoundException,
+ InvalidAttributeValueException,
+ MBeanException,
+ ReflectionException,
+ IOException {
+
+ if (logger.debugOn()) logger.debug("setAttribute",
+ "name=" + name + ", attribute name="
+ + attribute.getName());
+
+ final MarshalledObject<Attribute> sAttribute =
+ new MarshalledObject<Attribute>(attribute);
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ connection.setAttribute(name, sAttribute, delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ connection.setAttribute(name, sAttribute, delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public AttributeList setAttributes(ObjectName name,
+ AttributeList attributes)
+ throws InstanceNotFoundException,
+ ReflectionException,
+ IOException {
+
+ if (logger.debugOn()) {
+ logger.debug("setAttributes",
+ "name=" + name + ", attribute names="
+ + getAttributesNames(attributes));
+ }
+
+ final MarshalledObject<AttributeList> sAttributes =
+ new MarshalledObject<AttributeList>(attributes);
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.setAttributes(name,
+ sAttributes,
+ delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.setAttributes(name,
+ sAttributes,
+ delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+
+ public Object invoke(ObjectName name,
+ String operationName,
+ Object params[],
+ String signature[])
+ throws InstanceNotFoundException,
+ MBeanException,
+ ReflectionException,
+ IOException {
+
+ if (logger.debugOn()) logger.debug("invoke",
+ "name=" + name
+ + ", operationName=" + operationName
+ + ", signature=" + strings(signature));
+
+ final MarshalledObject<Object[]> sParams =
+ new MarshalledObject<Object[]>(params);
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.invoke(name,
+ operationName,
+ sParams,
+ signature,
+ delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.invoke(name,
+ operationName,
+ sParams,
+ signature,
+ delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+
+ public String getDefaultDomain()
+ throws IOException {
+ if (logger.debugOn()) logger.debug("getDefaultDomain", "");
+
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.getDefaultDomain(delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.getDefaultDomain(delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public String[] getDomains() throws IOException {
+ if (logger.debugOn()) logger.debug("getDomains", "");
+
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.getDomains(delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.getDomains(delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public MBeanInfo getMBeanInfo(ObjectName name)
+ throws InstanceNotFoundException,
+ IntrospectionException,
+ ReflectionException,
+ IOException {
+
+ if (logger.debugOn()) logger.debug("getMBeanInfo", "name=" + name);
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.getMBeanInfo(name, delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.getMBeanInfo(name, delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+
+ public boolean isInstanceOf(ObjectName name,
+ String className)
+ throws InstanceNotFoundException,
+ IOException {
+ if (logger.debugOn())
+ logger.debug("isInstanceOf", "name=" + name +
+ ", className=" + className);
+
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ return connection.isInstanceOf(name,
+ className,
+ delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ return connection.isInstanceOf(name,
+ className,
+ delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public void addNotificationListener(ObjectName name,
+ ObjectName listener,
+ NotificationFilter filter,
+ Object handback)
+ throws InstanceNotFoundException,
+ IOException {
+
+ if (logger.debugOn())
+ logger.debug("addNotificationListener" +
+ "(ObjectName,ObjectName,NotificationFilter,Object)",
+ "name=" + name + ", listener=" + listener
+ + ", filter=" + filter + ", handback=" + handback);
+
+ final MarshalledObject<NotificationFilter> sFilter =
+ new MarshalledObject<NotificationFilter>(filter);
+ final MarshalledObject<Object> sHandback =
+ new MarshalledObject<Object>(handback);
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ connection.addNotificationListener(name,
+ listener,
+ sFilter,
+ sHandback,
+ delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ connection.addNotificationListener(name,
+ listener,
+ sFilter,
+ sHandback,
+ delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public void removeNotificationListener(ObjectName name,
+ ObjectName listener)
+ throws InstanceNotFoundException,
+ ListenerNotFoundException,
+ IOException {
+
+ if (logger.debugOn()) logger.debug("removeNotificationListener" +
+ "(ObjectName,ObjectName)",
+ "name=" + name
+ + ", listener=" + listener);
+
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ connection.removeNotificationListener(name,
+ listener,
+ delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ connection.removeNotificationListener(name,
+ listener,
+ delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ public void removeNotificationListener(ObjectName name,
+ ObjectName listener,
+ NotificationFilter filter,
+ Object handback)
+ throws InstanceNotFoundException,
+ ListenerNotFoundException,
+ IOException {
+ if (logger.debugOn())
+ logger.debug("removeNotificationListener" +
+ "(ObjectName,ObjectName,NotificationFilter,Object)",
+ "name=" + name
+ + ", listener=" + listener
+ + ", filter=" + filter
+ + ", handback=" + handback);
+
+ final MarshalledObject<NotificationFilter> sFilter =
+ new MarshalledObject<NotificationFilter>(filter);
+ final MarshalledObject<Object> sHandback =
+ new MarshalledObject<Object>(handback);
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ connection.removeNotificationListener(name,
+ listener,
+ sFilter,
+ sHandback,
+ delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ connection.removeNotificationListener(name,
+ listener,
+ sFilter,
+ sHandback,
+ delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+ }
+
+ // Specific Notification Handle ----------------------------------
+
+ public void addNotificationListener(ObjectName name,
+ NotificationListener listener,
+ NotificationFilter filter,
+ Object handback)
+ throws InstanceNotFoundException,
+ IOException {
+
+ final boolean debug = logger.debugOn();
+
+ if (debug)
+ logger.debug("addNotificationListener" +
+ "(ObjectName,NotificationListener,"+
+ "NotificationFilter,Object)",
+ "name=" + name
+ + ", listener=" + listener
+ + ", filter=" + filter
+ + ", handback=" + handback);
+
+ final Integer listenerID =
+ addListenerWithSubject(name,
+ new MarshalledObject<NotificationFilter>(filter),
+ delegationSubject,true);
+ rmiNotifClient.addNotificationListener(listenerID, name, listener,
+ filter, handback,
+ delegationSubject);
+ }
+
+ public void removeNotificationListener(ObjectName name,
+ NotificationListener listener)
+ throws InstanceNotFoundException,
+ ListenerNotFoundException,
+ IOException {
+
+ final boolean debug = logger.debugOn();
+
+ if (debug) logger.debug("removeNotificationListener"+
+ "(ObjectName,NotificationListener)",
+ "name=" + name
+ + ", listener=" + listener);
+
+ final Integer[] ret =
+ rmiNotifClient.removeNotificationListener(name, listener);
+
+ if (debug) logger.debug("removeNotificationListener",
+ "listenerIDs=" + objects(ret));
+
+ final ClassLoader old = pushDefaultClassLoader();
+
+ try {
+ connection.removeNotificationListeners(name,
+ ret,
+ delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ connection.removeNotificationListeners(name,
+ ret,
+ delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+
+ }
+
+ public void removeNotificationListener(ObjectName name,
+ NotificationListener listener,
+ NotificationFilter filter,
+ Object handback)
+ throws InstanceNotFoundException,
+ ListenerNotFoundException,
+ IOException {
+ final boolean debug = logger.debugOn();
+
+ if (debug)
+ logger.debug("removeNotificationListener"+
+ "(ObjectName,NotificationListener,"+
+ "NotificationFilter,Object)",
+ "name=" + name
+ + ", listener=" + listener
+ + ", filter=" + filter
+ + ", handback=" + handback);
+
+ final Integer ret =
+ rmiNotifClient.removeNotificationListener(name, listener,
+ filter, handback);
+
+ if (debug) logger.debug("removeNotificationListener",
+ "listenerID=" + ret);
+
+ final ClassLoader old = pushDefaultClassLoader();
+ try {
+ connection.removeNotificationListeners(name,
+ new Integer[] {ret},
+ delegationSubject);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ connection.removeNotificationListeners(name,
+ new Integer[] {ret},
+ delegationSubject);
+ } finally {
+ popDefaultClassLoader(old);
+ }
+
+ }
+ }
+
+ //--------------------------------------------------------------------
+ private class RMINotifClient extends ClientNotifForwarder {
+ public RMINotifClient(ClassLoader cl, Map<String, ?> env) {
+ super(cl, env);
+ }
+
+ protected NotificationResult fetchNotifs(long clientSequenceNumber,
+ int maxNotifications,
+ long timeout)
+ throws IOException, ClassNotFoundException {
+
+ boolean retried = false;
+ while (true) { // used for a successful re-connection
+ // or a transient network problem
+ try {
+ return connection.fetchNotifications(clientSequenceNumber,
+ maxNotifications,
+ timeout); // return normally
+ } catch (IOException ioe) {
+ // Examine the chain of exceptions to determine whether this
+ // is a deserialization issue. If so - we propagate the
+ // appropriate exception to the caller, who will then
+ // proceed with fetching notifications one by one
+ rethrowDeserializationException(ioe);
+
+ try {
+ communicatorAdmin.gotIOException(ioe);
+ // reconnection OK, back to "while" to do again
+ } catch (IOException ee) {
+ boolean toClose = false;
+
+ synchronized (this) {
+ if (terminated) {
+ // the connection is closed.
+ throw ioe;
+ } else if (retried) {
+ toClose = true;
+ }
+ }
+
+ if (toClose) {
+ // JDK-8049303
+ // We received an IOException - but the communicatorAdmin
+ // did not close the connection - possibly because
+ // the original exception was raised by a transient network
+ // problem?
+ // We already know that this exception is not due to a deserialization
+ // issue as we already took care of that before involving the
+ // communicatorAdmin. Moreover - we already made one retry attempt
+ // at fetching the same batch of notifications - and the
+ // problem persisted.
+ // Since trying again doesn't seem to solve the issue, we will now
+ // close the connection. Doing otherwise might cause the
+ // NotifFetcher thread to die silently.
+ final Notification failedNotif =
+ new JMXConnectionNotification(
+ JMXConnectionNotification.FAILED,
+ this,
+ connectionId,
+ clientNotifSeqNo++,
+ "Failed to communicate with the server: " + ioe.toString(),
+ ioe);
+
+ sendNotification(failedNotif);
+
+ try {
+ close(true);
+ } catch (Exception e) {
+ // OK.
+ // We are closing
+ }
+ throw ioe; // the connection is closed here.
+ } else {
+ // JDK-8049303 possible transient network problem,
+ // let's try one more time
+ retried = true;
+ }
+ }
+ }
+ }
+ }
+
+ private void rethrowDeserializationException(IOException ioe)
+ throws ClassNotFoundException, IOException {
+ // specially treating for an UnmarshalException
+ if (ioe instanceof UnmarshalException) {
+ NotSerializableException nse = new NotSerializableException();
+ nse.initCause(ioe);
+ throw nse; // the fix of 6937053 made ClientNotifForwarder.fetchNotifs
+ // fetch one by one with UnmarshalException
+ }
+
+ // Not serialization problem, return.
+ }
+
+ protected Integer addListenerForMBeanRemovedNotif()
+ throws IOException, InstanceNotFoundException {
+ NotificationFilterSupport clientFilter =
+ new NotificationFilterSupport();
+ clientFilter.enableType(
+ MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
+ MarshalledObject<NotificationFilter> sFilter =
+ new MarshalledObject<NotificationFilter>(clientFilter);
+
+ Integer[] listenerIDs;
+ final ObjectName[] names =
+ new ObjectName[] {MBeanServerDelegate.DELEGATE_NAME};
+ final MarshalledObject<NotificationFilter>[] filters =
+ Util.cast(new MarshalledObject<?>[] {sFilter});
+ final Subject[] subjects = new Subject[] {null};
+ try {
+ listenerIDs =
+ connection.addNotificationListeners(names,
+ filters,
+ subjects);
+
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ listenerIDs =
+ connection.addNotificationListeners(names,
+ filters,
+ subjects);
+ }
+ return listenerIDs[0];
+ }
+
+ protected void removeListenerForMBeanRemovedNotif(Integer id)
+ throws IOException, InstanceNotFoundException,
+ ListenerNotFoundException {
+ try {
+ connection.removeNotificationListeners(
+ MBeanServerDelegate.DELEGATE_NAME,
+ new Integer[] {id},
+ null);
+ } catch (IOException ioe) {
+ communicatorAdmin.gotIOException(ioe);
+
+ connection.removeNotificationListeners(
+ MBeanServerDelegate.DELEGATE_NAME,
+ new Integer[] {id},
+ null);
+ }
+
+ }
+
+ protected void lostNotifs(String message, long number) {
+ final String notifType = JMXConnectionNotification.NOTIFS_LOST;
+
+ final JMXConnectionNotification n =
+ new JMXConnectionNotification(notifType,
+ RMIConnector.this,
+ connectionId,
+ clientNotifCounter++,
+ message,
+ Long.valueOf(number));
+ sendNotification(n);
+ }
+ }
+
+ private class RMIClientCommunicatorAdmin extends ClientCommunicatorAdmin {
+ public RMIClientCommunicatorAdmin(long period) {
+ super(period);
+ }
+
+ @Override
+ public void gotIOException(IOException ioe) throws IOException {
+ if (ioe instanceof NoSuchObjectException) {
+ // need to restart
+ super.gotIOException(ioe);
+
+ return;
+ }
+
+ // check if the connection is broken
+ try {
+ connection.getDefaultDomain(null);
+ } catch (IOException ioexc) {
+ boolean toClose = false;
+
+ synchronized(this) {
+ if (!terminated) {
+ terminated = true;
+
+ toClose = true;
+ }
+ }
+
+ if (toClose) {
+ // we should close the connection,
+ // but send a failed notif at first
+ final Notification failedNotif =
+ new JMXConnectionNotification(
+ JMXConnectionNotification.FAILED,
+ this,
+ connectionId,
+ clientNotifSeqNo++,
+ "Failed to communicate with the server: "+ioe.toString(),
+ ioe);
+
+ sendNotification(failedNotif);
+
+ try {
+ close(true);
+ } catch (Exception e) {
+ // OK.
+ // We are closing
+ }
+ }
+ }
+
+ // forward the exception
+ if (ioe instanceof ServerException) {
+ /* Need to unwrap the exception.
+ Some user-thrown exception at server side will be wrapped by
+ rmi into a ServerException.
+ For example, a RMIConnnectorServer will wrap a
+ ClassNotFoundException into a UnmarshalException, and rmi
+ will throw a ServerException at client side which wraps this
+ UnmarshalException.
+ No failed notif here.
+ */
+ Throwable tt = ((ServerException)ioe).detail;
+
+ if (tt instanceof IOException) {
+ throw (IOException)tt;
+ } else if (tt instanceof RuntimeException) {
+ throw (RuntimeException)tt;
+ }
+ }
+
+ throw ioe;
+ }
+
+ public void reconnectNotificationListeners(ClientListenerInfo[] old) throws IOException {
+ final int len = old.length;
+ int i;
+
+ ClientListenerInfo[] clis = new ClientListenerInfo[len];
+
+ final Subject[] subjects = new Subject[len];
+ final ObjectName[] names = new ObjectName[len];
+ final NotificationListener[] listeners = new NotificationListener[len];
+ final NotificationFilter[] filters = new NotificationFilter[len];
+ final MarshalledObject<NotificationFilter>[] mFilters =
+ Util.cast(new MarshalledObject<?>[len]);
+ final Object[] handbacks = new Object[len];
+
+ for (i=0;i<len;i++) {
+ subjects[i] = old[i].getDelegationSubject();
+ names[i] = old[i].getObjectName();
+ listeners[i] = old[i].getListener();
+ filters[i] = old[i].getNotificationFilter();
+ mFilters[i] = new MarshalledObject<NotificationFilter>(filters[i]);
+ handbacks[i] = old[i].getHandback();
+ }
+
+ try {
+ Integer[] ids = addListenersWithSubjects(names,mFilters,subjects,false);
+
+ for (i=0;i<len;i++) {
+ clis[i] = new ClientListenerInfo(ids[i],
+ names[i],
+ listeners[i],
+ filters[i],
+ handbacks[i],
+ subjects[i]);
+ }
+
+ rmiNotifClient.postReconnection(clis);
+
+ return;
+ } catch (InstanceNotFoundException infe) {
+ // OK, we will do one by one
+ }
+
+ int j = 0;
+ for (i=0;i<len;i++) {
+ try {
+ Integer id = addListenerWithSubject(names[i],
+ new MarshalledObject<NotificationFilter>(filters[i]),
+ subjects[i],
+ false);
+
+ clis[j++] = new ClientListenerInfo(id,
+ names[i],
+ listeners[i],
+ filters[i],
+ handbacks[i],
+ subjects[i]);
+ } catch (InstanceNotFoundException infe) {
+ logger.warning("reconnectNotificationListeners",
+ "Can't reconnect listener for " +
+ names[i]);
+ }
+ }
+
+ if (j != len) {
+ ClientListenerInfo[] tmp = clis;
+ clis = new ClientListenerInfo[j];
+ System.arraycopy(tmp, 0, clis, 0, j);
+ }
+
+ rmiNotifClient.postReconnection(clis);
+ }
+
+ protected void checkConnection() throws IOException {
+ if (logger.debugOn())
+ logger.debug("RMIClientCommunicatorAdmin-checkConnection",
+ "Calling the method getDefaultDomain.");
+
+ connection.getDefaultDomain(null);
+ }
+
+ protected void doStart() throws IOException {
+ // Get RMIServer stub from directory or URL encoding if needed.
+ RMIServer stub;
+ try {
+ stub = (rmiServer!=null)?rmiServer:
+ findRMIServer(jmxServiceURL, env);
+ } catch (NamingException ne) {
+ throw new IOException("Failed to get a RMI stub: "+ne);
+ }
+
+ // Calling newClient on the RMIServer stub.
+ Object credentials = env.get(CREDENTIALS);
+ connection = stub.newClient(credentials);
+
+ // notif issues
+ final ClientListenerInfo[] old = rmiNotifClient.preReconnection();
+
+ reconnectNotificationListeners(old);
+
+ connectionId = getConnectionId();
+
+ Notification reconnectedNotif =
+ new JMXConnectionNotification(JMXConnectionNotification.OPENED,
+ this,
+ connectionId,
+ clientNotifSeqNo++,
+ "Reconnected to server",
+ null);
+ sendNotification(reconnectedNotif);
+
+ }
+
+ protected void doStop() {
+ try {
+ close();
+ } catch (IOException ioe) {
+ logger.warning("RMIClientCommunicatorAdmin-doStop",
+ "Failed to call the method close():" + ioe);
+ logger.debug("RMIClientCommunicatorAdmin-doStop",ioe);
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------
+ // Private stuff - Serialization
+ //--------------------------------------------------------------------
+ /**
+ * Read RMIConnector fields from an {@link java.io.ObjectInputStream
+ * ObjectInputStream}.
+ * Calls {@code s.defaultReadObject()} and then initializes
+ * all transient variables that need initializing.
+ * @param s The ObjectInputStream to read from.
+ * @exception InvalidObjectException if none of <var>rmiServer</var> stub
+ * or <var>jmxServiceURL</var> are set.
+ * @see #RMIConnector(JMXServiceURL,Map)
+ * @see #RMIConnector(RMIServer,Map)
+ **/
+ private void readObject(java.io.ObjectInputStream s)
+ throws IOException, ClassNotFoundException {
+ s.defaultReadObject();
+
+ if (rmiServer == null && jmxServiceURL == null) throw new
+ InvalidObjectException("rmiServer and jmxServiceURL both null");
+
+ initTransients();
+ }
+
+ /**
+ * Writes the RMIConnector fields to an {@link java.io.ObjectOutputStream
+ * ObjectOutputStream}.
+ * <p>Connects the underlying RMIServer stub to an ORB, if needed,
+ * before serializing it. This is done using the environment
+ * map that was provided to the constructor, if any, and as documented
+ * in {@link javax.management.remote.rmi}.</p>
+ * <p>This method then calls {@code s.defaultWriteObject()}.
+ * Usually, <var>rmiServer</var> is null if this object
+ * was constructed with a JMXServiceURL, and <var>jmxServiceURL</var>
+ * is null if this object is constructed with a RMIServer stub.
+ * <p>Note that the environment Map is not serialized, since the objects
+ * it contains are assumed to be contextual and relevant only
+ * with respect to the local environment (class loader, ORB, etc...).</p>
+ * <p>After an RMIConnector is deserialized, it is assumed that the
+ * user will call {@link #connect(Map)}, providing a new Map that
+ * can contain values which are contextually relevant to the new
+ * local environment.</p>
+ * <p>Since connection to the ORB is needed prior to serializing, and
+ * since the ORB to connect to is one of those contextual parameters,
+ * it is not recommended to re-serialize a just de-serialized object -
+ * as the de-serialized object has no map. Thus, when an RMIConnector
+ * object is needed for serialization or transmission to a remote
+ * application, it is recommended to obtain a new RMIConnector stub
+ * by calling {@link RMIConnectorServer#toJMXConnector(Map)}.</p>
+ * @param s The ObjectOutputStream to write to.
+ * @exception InvalidObjectException if none of <var>rmiServer</var> stub
+ * or <var>jmxServiceURL</var> are set.
+ * @see #RMIConnector(JMXServiceURL,Map)
+ * @see #RMIConnector(RMIServer,Map)
+ **/
+ private void writeObject(java.io.ObjectOutputStream s)
+ throws IOException {
+ if (rmiServer == null && jmxServiceURL == null) throw new
+ InvalidObjectException("rmiServer and jmxServiceURL both null.");
+ s.defaultWriteObject();
+ }
+
+ // Initialization of transient variables.
+ private void initTransients() {
+ rmbscMap = new WeakHashMap<Subject, WeakReference<MBeanServerConnection>>();
+ connected = false;
+ terminated = false;
+
+ connectionBroadcaster = new NotificationBroadcasterSupport();
+ }
+
+ //--------------------------------------------------------------------
+ // Private stuff - Check if stub can be trusted.
+ //--------------------------------------------------------------------
+
+ private static void checkStub(Remote stub,
+ Class<?> stubClass) {
+
+ // Check remote stub is from the expected class.
+ //
+ if (stub.getClass() != stubClass) {
+ if (!Proxy.isProxyClass(stub.getClass())) {
+ throw new SecurityException(
+ "Expecting a " + stubClass.getName() + " stub!");
+ } else {
+ InvocationHandler handler = Proxy.getInvocationHandler(stub);
+ if (handler.getClass() != RemoteObjectInvocationHandler.class)
+ throw new SecurityException(
+ "Expecting a dynamic proxy instance with a " +
+ RemoteObjectInvocationHandler.class.getName() +
+ " invocation handler!");
+ else
+ stub = (Remote) handler;
+ }
+ }
+
+ // Check RemoteRef in stub is from the expected class
+ // "sun.rmi.server.UnicastRef2".
+ //
+ RemoteRef ref = ((RemoteObject)stub).getRef();
+ if (ref.getClass() != UnicastRef2.class)
+ throw new SecurityException(
+ "Expecting a " + UnicastRef2.class.getName() +
+ " remote reference in stub!");
+
+ // Check RMIClientSocketFactory in stub is from the expected class
+ // "javax.rmi.ssl.SslRMIClientSocketFactory".
+ //
+ LiveRef liveRef = ((UnicastRef2)ref).getLiveRef();
+ RMIClientSocketFactory csf = liveRef.getClientSocketFactory();
+ if (csf == null || csf.getClass() != SslRMIClientSocketFactory.class)
+ throw new SecurityException(
+ "Expecting a " + SslRMIClientSocketFactory.class.getName() +
+ " RMI client socket factory in stub!");
+ }
+
+ //--------------------------------------------------------------------
+ // Private stuff - RMIServer creation
+ //--------------------------------------------------------------------
+
+ private RMIServer findRMIServer(JMXServiceURL directoryURL,
+ Map<String, Object> environment)
+ throws NamingException, IOException {
+
+ String path = directoryURL.getURLPath();
+ int end = path.indexOf(';');
+ if (end < 0) end = path.length();
+ if (path.startsWith("/jndi/"))
+ return findRMIServerJNDI(path.substring(6,end), environment);
+ else if (path.startsWith("/stub/"))
+ return findRMIServerJRMP(path.substring(6,end), environment);
+ else {
+ final String msg = "URL path must begin with /jndi/ or /stub/ " +
+ "or /ior/: " + path;
+ throw new MalformedURLException(msg);
+ }
+ }
+
+ /**
+ * Lookup the RMIServer stub in a directory.
+ * @param jndiURL A JNDI URL indicating the location of the Stub
+ * (see {@link javax.management.remote.rmi}), e.g.:
+ * <ul><li>{@code rmi://registry-host:port/rmi-stub-name}</li>
+ * <li>or {@code ldap://ldap-host:port/java-container-dn}</li>
+ * </ul>
+ * @param env the environment Map passed to the connector.
+ * @return The retrieved RMIServer stub.
+ * @exception NamingException if the stub couldn't be found.
+ **/
+ private RMIServer findRMIServerJNDI(String jndiURL, Map<String, ?> env)
+ throws NamingException {
+
+ InitialContext ctx = new InitialContext(EnvHelp.mapToHashtable(env));
+
+ Object objref = ctx.lookup(jndiURL);
+ ctx.close();
+
+ return narrowJRMPServer(objref);
+ }
+
+ private static RMIServer narrowJRMPServer(Object objref) {
+
+ return (RMIServer) objref;
+ }
+
+ private RMIServer findRMIServerJRMP(String base64, Map<String, ?> env)
+ throws IOException {
+ final byte[] serialized;
+ try {
+ serialized = base64ToByteArray(base64);
+ } catch (IllegalArgumentException e) {
+ throw new MalformedURLException("Bad BASE64 encoding: " +
+ e.getMessage());
+ }
+ final ByteArrayInputStream bin = new ByteArrayInputStream(serialized);
+
+ final ClassLoader loader = EnvHelp.resolveClientClassLoader(env);
+ final ObjectInputStream oin =
+ (loader == null) ?
+ new ObjectInputStream(bin) :
+ new ObjectInputStreamWithLoader(bin, loader);
+ final Object stub;
+ try {
+ stub = oin.readObject();
+ } catch (ClassNotFoundException e) {
+ throw new MalformedURLException("Class not found: " + e);
+ }
+ return (RMIServer)stub;
+ }
+
+ private static final class ObjectInputStreamWithLoader
+ extends ObjectInputStream {
+ ObjectInputStreamWithLoader(InputStream in, ClassLoader cl)
+ throws IOException, IllegalArgumentException {
+ super(in);
+ if (cl == null ) {
+ throw new IllegalArgumentException("class loader is null");
+ }
+ this.loader = cl;
+ }
+
+ @Override
+ protected Class<?> resolveClass(ObjectStreamClass classDesc)
+ throws IOException, ClassNotFoundException {
+ String name = classDesc.getName();
+ ReflectUtil.checkPackageAccess(name);
+ return Class.forName(name, false, Objects.requireNonNull(loader));
+ }
+
+ private final ClassLoader loader;
+ }
+
+ private MBeanServerConnection getConnectionWithSubject(Subject delegationSubject) {
+ MBeanServerConnection conn = null;
+
+ if (delegationSubject == null) {
+ if (nullSubjectConnRef == null
+ || (conn = nullSubjectConnRef.get()) == null) {
+ conn = new RemoteMBeanServerConnection(null);
+ nullSubjectConnRef = new WeakReference<MBeanServerConnection>(conn);
+ }
+ } else {
+ WeakReference<MBeanServerConnection> wr = rmbscMap.get(delegationSubject);
+ if (wr == null || (conn = wr.get()) == null) {
+ conn = new RemoteMBeanServerConnection(delegationSubject);
+ rmbscMap.put(delegationSubject, new WeakReference<MBeanServerConnection>(conn));
+ }
+ }
+ return conn;
+ }
+
+ /*
+ The following section of code avoids a class loading problem
+ with RMI. The problem is that an RMI stub, when deserializing
+ a remote method return value or exception, will first of all
+ consult the first non-bootstrap class loader it finds in the
+ call stack. This can lead to behavior that is not portable
+ between implementations of the JMX Remote API. Notably, an
+ implementation on J2SE 1.4 will find the RMI stub's loader on
+ the stack. But in J2SE 5, this stub is loaded by the
+ bootstrap loader, so RMI will find the loader of the user code
+ that called an MBeanServerConnection method.
+
+ To avoid this problem, we take advantage of what the RMI stub
+ is doing internally. Each remote call will end up calling
+ ref.invoke(...), where ref is the RemoteRef parameter given to
+ the RMI stub's constructor. It is within this call that the
+ deserialization will happen. So we fabricate our own RemoteRef
+ that delegates everything to the "real" one but that is loaded
+ by a class loader that knows no other classes. The class
+ loader NoCallStackClassLoader does this: the RemoteRef is an
+ instance of the class named by proxyRefClassName, which is
+ fabricated by the class loader using byte code that is defined
+ by the string below.
+
+ The call stack when the deserialization happens is thus this:
+ MBeanServerConnection.getAttribute (or whatever)
+ -> RMIConnectionImpl_Stub.getAttribute
+ -> ProxyRef.invoke(...getAttribute...)
+ -> UnicastRef.invoke(...getAttribute...)
+ -> internal RMI stuff
+
+ Here UnicastRef is the RemoteRef created when the stub was
+ deserialized (which is of some RMI internal class). It and the
+ "internal RMI stuff" are loaded by the bootstrap loader, so are
+ transparent to the stack search. The first non-bootstrap
+ loader found is our ProxyRefLoader, as required.
+
+ In a future version of this code as integrated into J2SE 5,
+ this workaround could be replaced by direct access to the
+ internals of RMI. For now, we use the same code base for J2SE
+ and for the standalone Reference Implementation.
+
+ The byte code below encodes the following class, compiled using
+ J2SE 1.4.2 with the -g:none option.
+
+ package jdk.jmx.remote.internal.rmi;
+
+ import java.lang.reflect.Method;
+ import java.rmi.Remote;
+ import java.rmi.server.RemoteRef;
+ import com.sun.jmx.remote.internal.rmi.ProxyRef;
+
+ public class PRef extends ProxyRef {
+ public PRef(RemoteRef ref) {
+ super(ref);
+ }
+
+ public Object invoke(Remote obj, Method method,
+ Object[] params, long opnum)
+ throws Exception {
+ return ref.invoke(obj, method, params, opnum);
+ }
+ }
+ */
+
+ private static final String rmiServerImplStubClassName =
+ RMIServer.class.getName() + "Impl_Stub";
+ private static final Class<?> rmiServerImplStubClass;
+ private static final String rmiConnectionImplStubClassName =
+ RMIConnection.class.getName() + "Impl_Stub";
+ private static final Class<?> rmiConnectionImplStubClass;
+ private static final String pRefClassName =
+ "jdk.jmx.remote.internal.rmi.PRef";
+ private static final Constructor<?> proxyRefConstructor;
+ static {
+ final String pRefByteCodeString =
+ "\312\376\272\276\0\0\0\65\0\27\12\0\5\0\15\11\0\4\0\16\13\0\17"+
+ "\0\20\7\0\21\7\0\22\1\0\6<init>\1\0\36(Ljava/rmi/server/Remote"+
+ "Ref;)V\1\0\4Code\1\0\6invoke\1\0S(Ljava/rmi/Remote;Ljava/lang/"+
+ "reflect/Method;[Ljava/lang/Object;J)Ljava/lang/Object;\1\0\12E"+
+ "xceptions\7\0\23\14\0\6\0\7\14\0\24\0\25\7\0\26\14\0\11\0\12\1"+
+ "\0 jdk/jmx/remote/internal/rmi/PRef\1\0(com/sun/jmx/remote/int"+
+ "ernal/rmi/ProxyRef\1\0\23java/lang/Exception\1\0\3ref\1\0\33Lj"+
+ "ava/rmi/server/RemoteRef;\1\0\31java/rmi/server/RemoteRef\0!\0"+
+ "\4\0\5\0\0\0\0\0\2\0\1\0\6\0\7\0\1\0\10\0\0\0\22\0\2\0\2\0\0\0"+
+ "\6*+\267\0\1\261\0\0\0\0\0\1\0\11\0\12\0\2\0\10\0\0\0\33\0\6\0"+
+ "\6\0\0\0\17*\264\0\2+,-\26\4\271\0\3\6\0\260\0\0\0\0\0\13\0\0\0"+
+ "\4\0\1\0\14\0\0";
+ final byte[] pRefByteCode =
+ NoCallStackClassLoader.stringToBytes(pRefByteCodeString);
+ PrivilegedExceptionAction<Constructor<?>> action =
+ new PrivilegedExceptionAction<Constructor<?>>() {
+ public Constructor<?> run() throws Exception {
+ Class<RMIConnector> thisClass = RMIConnector.class;
+ ClassLoader thisLoader = thisClass.getClassLoader();
+ ProtectionDomain thisProtectionDomain =
+ thisClass.getProtectionDomain();
+
+ String proxyRefCName = ProxyRef.class.getName();
+ ClassLoader cl =
+ new NoCallStackClassLoader(pRefClassName,
+ pRefByteCode,
+ new String[] { proxyRefCName },
+ thisLoader,
+ thisProtectionDomain);
+
+ Module jmxModule = ProxyRef.class.getModule();
+ Module rmiModule = RemoteRef.class.getModule();
+
+ String pkg = packageOf(pRefClassName);
+ assert pkg != null && pkg.length() > 0 && !pkg.equals(packageOf(proxyRefCName));
+ Module m = Modules.defineModule(cl, "jdk.remoteref", Collections.singleton(pkg));
+
+ // jdk.remoteref needs to read to java.base and jmxModule
+ Modules.addReads(m, Object.class.getModule());
+ Modules.addReads(m, jmxModule);
+ Modules.addReads(m, rmiModule);
+
+ // jdk.remoteref needs access to ProxyRef class
+ Modules.addExports(jmxModule, packageOf(proxyRefCName), m);
+
+ // java.management needs to instantiate the fabricated RemoteRef class
+ Modules.addReads(jmxModule, m);
+ Modules.addExports(m, pkg, jmxModule);
+
+ Class<?> c = cl.loadClass(pRefClassName);
+ return c.getConstructor(RemoteRef.class);
+ }
+ };
+
+ Class<?> serverStubClass;
+ try {
+ serverStubClass = Class.forName(rmiServerImplStubClassName);
+ } catch (Exception e) {
+ logger.error("<clinit>",
+ "Failed to instantiate " +
+ rmiServerImplStubClassName + ": " + e);
+ logger.debug("<clinit>",e);
+ serverStubClass = null;
+ }
+ rmiServerImplStubClass = serverStubClass;
+
+ Class<?> stubClass;
+ Constructor<?> constr;
+ try {
+ stubClass = Class.forName(rmiConnectionImplStubClassName);
+ constr = (Constructor<?>) AccessController.doPrivileged(action);
+ } catch (Exception e) {
+ logger.error("<clinit>",
+ "Failed to initialize proxy reference constructor "+
+ "for " + rmiConnectionImplStubClassName + ": " + e);
+ logger.debug("<clinit>",e);
+ stubClass = null;
+ constr = null;
+ }
+ rmiConnectionImplStubClass = stubClass;
+ proxyRefConstructor = constr;
+ }
+
+ private static String packageOf(String cn) {
+ int i = cn.lastIndexOf('.');
+ return i > 0 ? cn.substring(0, i) : "";
+ }
+
+ private static RMIConnection shadowJrmpStub(RemoteObject stub)
+ throws InstantiationException, IllegalAccessException,
+ InvocationTargetException, ClassNotFoundException,
+ NoSuchMethodException {
+ RemoteRef ref = stub.getRef();
+ RemoteRef proxyRef = (RemoteRef)
+ proxyRefConstructor.newInstance(new Object[] {ref});
+ final Constructor<?> rmiConnectionImplStubConstructor =
+ rmiConnectionImplStubClass.getConstructor(RemoteRef.class);
+ Object[] args = {proxyRef};
+ RMIConnection proxyStub = (RMIConnection)
+ rmiConnectionImplStubConstructor.newInstance(args);
+ return proxyStub;
+ }
+
+ private static RMIConnection getConnection(RMIServer server,
+ Object credentials,
+ boolean checkStub)
+ throws IOException {
+ RMIConnection c = server.newClient(credentials);
+ if (checkStub) checkStub(c, rmiConnectionImplStubClass);
+ try {
+ if (c.getClass() == rmiConnectionImplStubClass)
+ return shadowJrmpStub((RemoteObject) c);
+ logger.trace("getConnection",
+ "Did not wrap " + c.getClass() + " to foil " +
+ "stack search for classes: class loading semantics " +
+ "may be incorrect");
+ } catch (Exception e) {
+ logger.error("getConnection",
+ "Could not wrap " + c.getClass() + " to foil " +
+ "stack search for classes: class loading semantics " +
+ "may be incorrect: " + e);
+ logger.debug("getConnection",e);
+ // so just return the original stub, which will work for all
+ // but the most exotic class loading situations
+ }
+ return c;
+ }
+
+ private static byte[] base64ToByteArray(String s) {
+ int sLen = s.length();
+ int numGroups = sLen/4;
+ if (4*numGroups != sLen)
+ throw new IllegalArgumentException(
+ "String length must be a multiple of four.");
+ int missingBytesInLastGroup = 0;
+ int numFullGroups = numGroups;
+ if (sLen != 0) {
+ if (s.charAt(sLen-1) == '=') {
+ missingBytesInLastGroup++;
+ numFullGroups--;
+ }
+ if (s.charAt(sLen-2) == '=')
+ missingBytesInLastGroup++;
+ }
+ byte[] result = new byte[3*numGroups - missingBytesInLastGroup];
+
+ // Translate all full groups from base64 to byte array elements
+ int inCursor = 0, outCursor = 0;
+ for (int i=0; i<numFullGroups; i++) {
+ int ch0 = base64toInt(s.charAt(inCursor++));
+ int ch1 = base64toInt(s.charAt(inCursor++));
+ int ch2 = base64toInt(s.charAt(inCursor++));
+ int ch3 = base64toInt(s.charAt(inCursor++));
+ result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
+ result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
+ result[outCursor++] = (byte) ((ch2 << 6) | ch3);
+ }
+
+ // Translate partial group, if present
+ if (missingBytesInLastGroup != 0) {
+ int ch0 = base64toInt(s.charAt(inCursor++));
+ int ch1 = base64toInt(s.charAt(inCursor++));
+ result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
+
+ if (missingBytesInLastGroup == 1) {
+ int ch2 = base64toInt(s.charAt(inCursor++));
+ result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
+ }
+ }
+ // assert inCursor == s.length()-missingBytesInLastGroup;
+ // assert outCursor == result.length;
+ return result;
+ }
+
+ /**
+ * Translates the specified character, which is assumed to be in the
+ * "Base 64 Alphabet" into its equivalent 6-bit positive integer.
+ *
+ * @throws IllegalArgumentException if
+ * c is not in the Base64 Alphabet.
+ */
+ private static int base64toInt(char c) {
+ int result;
+
+ if (c >= base64ToInt.length)
+ result = -1;
+ else
+ result = base64ToInt[c];
+
+ if (result < 0)
+ throw new IllegalArgumentException("Illegal character " + c);
+ return result;
+ }
+
+ /**
+ * This array is a lookup table that translates unicode characters
+ * drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045)
+ * into their 6-bit positive integer equivalents. Characters that
+ * are not in the Base64 alphabet but fall within the bounds of the
+ * array are translated to -1.
+ */
+ private static final byte base64ToInt[] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
+ };
+
+ //--------------------------------------------------------------------
+ // Private stuff - Find / Set default class loader
+ //--------------------------------------------------------------------
+ private ClassLoader pushDefaultClassLoader() {
+ final Thread t = Thread.currentThread();
+ final ClassLoader old = t.getContextClassLoader();
+ if (defaultClassLoader != null)
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ t.setContextClassLoader(defaultClassLoader);
+ return null;
+ }
+ });
+ return old;
+ }
+
+ private void popDefaultClassLoader(final ClassLoader old) {
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ public Void run() {
+ Thread.currentThread().setContextClassLoader(old);
+ return null;
+ }
+ });
+ }
+
+ //--------------------------------------------------------------------
+ // Private variables
+ //--------------------------------------------------------------------
+ /**
+ * @serial The RMIServer stub of the RMI JMX Connector server to
+ * which this client connector is (or will be) connected. This
+ * field can be null when <var>jmxServiceURL</var> is not
+ * null. This includes the case where <var>jmxServiceURL</var>
+ * contains a serialized RMIServer stub. If both
+ * <var>rmiServer</var> and <var>jmxServiceURL</var> are null then
+ * serialization will fail.
+ *
+ * @see #RMIConnector(RMIServer,Map)
+ **/
+ private final RMIServer rmiServer;
+
+ /**
+ * @serial The JMXServiceURL of the RMI JMX Connector server to
+ * which this client connector will be connected. This field can
+ * be null when <var>rmiServer</var> is not null. If both
+ * <var>rmiServer</var> and <var>jmxServiceURL</var> are null then
+ * serialization will fail.
+ *
+ * @see #RMIConnector(JMXServiceURL,Map)
+ **/
+ private final JMXServiceURL jmxServiceURL;
+
+ // ---------------------------------------------------------
+ // WARNING - WARNING - WARNING - WARNING - WARNING - WARNING
+ // ---------------------------------------------------------
+ // Any transient variable which needs to be initialized should
+ // be initialized in the method initTransient()
+ private transient Map<String, Object> env;
+ private transient ClassLoader defaultClassLoader;
+ private transient RMIConnection connection;
+ private transient String connectionId;
+
+ private transient long clientNotifSeqNo = 0;
+
+ private transient WeakHashMap<Subject, WeakReference<MBeanServerConnection>> rmbscMap;
+ private transient WeakReference<MBeanServerConnection> nullSubjectConnRef = null;
+
+ private transient RMINotifClient rmiNotifClient;
+ // = new RMINotifClient(new Integer(0));
+
+ private transient long clientNotifCounter = 0;
+
+ private transient boolean connected;
+ // = false;
+ private transient boolean terminated;
+ // = false;
+
+ private transient Exception closeException;
+
+ private transient NotificationBroadcasterSupport connectionBroadcaster;
+
+ private transient ClientCommunicatorAdmin communicatorAdmin;
+
+ /**
+ * A static WeakReference to an {@link org.omg.CORBA.ORB ORB} to
+ * connect unconnected stubs.
+ **/
+ private static volatile WeakReference<Object> orb = null;
+
+ // TRACES & DEBUG
+ //---------------
+ private static String objects(final Object[] objs) {
+ if (objs == null)
+ return "null";
+ else
+ return Arrays.asList(objs).toString();
+ }
+
+ private static String strings(final String[] strs) {
+ return objects(strs);
+ }
+
+ static String getAttributesNames(AttributeList attributes) {
+ return attributes != null ?
+ attributes.asList().stream()
+ .map(Attribute::getName)
+ .collect(Collectors.joining(", ", "[", "]"))
+ : "[]";
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectorServer.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,819 @@
+/*
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.management.remote.rmi;
+
+
+import com.sun.jmx.remote.security.MBeanServerFileAccessController;
+import com.sun.jmx.remote.util.ClassLogger;
+import com.sun.jmx.remote.util.EnvHelp;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.net.MalformedURLException;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.InstanceNotFoundException;
+import javax.management.MBeanServer;
+import javax.management.remote.JMXAuthenticator;
+
+import javax.management.remote.JMXConnectionNotification;
+import javax.management.remote.JMXConnector;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.MBeanServerForwarder;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+
+/**
+ * <p>A JMX API connector server that creates RMI-based connections
+ * from remote clients. Usually, such connector servers are made
+ * using {@link javax.management.remote.JMXConnectorServerFactory
+ * JMXConnectorServerFactory}. However, specialized applications can
+ * use this class directly, for example with an {@link RMIServerImpl}
+ * object.</p>
+ *
+ * @since 1.5
+ */
+public class RMIConnectorServer extends JMXConnectorServer {
+ /**
+ * <p>Name of the attribute that specifies whether the {@link
+ * RMIServer} stub that represents an RMI connector server should
+ * override an existing stub at the same address. The value
+ * associated with this attribute, if any, should be a string that
+ * is equal, ignoring case, to <code>"true"</code> or
+ * <code>"false"</code>. The default value is false.</p>
+ */
+ public static final String JNDI_REBIND_ATTRIBUTE =
+ "jmx.remote.jndi.rebind";
+
+ /**
+ * <p>Name of the attribute that specifies the {@link
+ * RMIClientSocketFactory} for the RMI objects created in
+ * conjunction with this connector. The value associated with this
+ * attribute must be of type <code>RMIClientSocketFactory</code> and can
+ * only be specified in the <code>Map</code> argument supplied when
+ * creating a connector server.</p>
+ */
+ public static final String RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE =
+ "jmx.remote.rmi.client.socket.factory";
+
+ /**
+ * <p>Name of the attribute that specifies the {@link
+ * RMIServerSocketFactory} for the RMI objects created in
+ * conjunction with this connector. The value associated with this
+ * attribute must be of type <code>RMIServerSocketFactory</code> and can
+ * only be specified in the <code>Map</code> argument supplied when
+ * creating a connector server.</p>
+ */
+ public static final String RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE =
+ "jmx.remote.rmi.server.socket.factory";
+
+ /**
+ * Name of the attribute that specifies a list of class names acceptable
+ * as parameters to the {@link RMIServer#newClient(java.lang.Object) RMIServer.newClient()}
+ * remote method call.
+ * <p>
+ * This list of classes should correspond to the transitive closure of the
+ * credentials class (or classes) used by the installed {@linkplain JMXAuthenticator}
+ * associated with the {@linkplain RMIServer} implementation.
+ * <p>
+ * If the attribute is not set, or is null, then any class is
+ * deemed acceptable.
+ */
+ public static final String CREDENTIAL_TYPES =
+ "jmx.remote.rmi.server.credential.types";
+
+ /**
+ * <p>Makes an <code>RMIConnectorServer</code>.
+ * This is equivalent to calling {@link #RMIConnectorServer(
+ * JMXServiceURL,Map,RMIServerImpl,MBeanServer)
+ * RMIConnectorServer(directoryURL,environment,null,null)}</p>
+ *
+ * @param url the URL defining how to create the connector server.
+ * Cannot be null.
+ *
+ * @param environment attributes governing the creation and
+ * storing of the RMI object. Can be null, which is equivalent to
+ * an empty Map.
+ *
+ * @exception IllegalArgumentException if <code>url</code> is null.
+ *
+ * @exception MalformedURLException if <code>url</code> does not
+ * conform to the syntax for an RMI connector, or if its protocol
+ * is not recognized by this implementation. Only "rmi" is valid when
+ * this constructor is used.
+ *
+ * @exception IOException if the connector server cannot be created
+ * for some reason or if it is inevitable that its {@link #start()
+ * start} method will fail.
+ */
+ public RMIConnectorServer(JMXServiceURL url, Map<String,?> environment)
+ throws IOException {
+ this(url, environment, (MBeanServer) null);
+ }
+
+ /**
+ * <p>Makes an <code>RMIConnectorServer</code> for the given MBean
+ * server.
+ * This is equivalent to calling {@link #RMIConnectorServer(
+ * JMXServiceURL,Map,RMIServerImpl,MBeanServer)
+ * RMIConnectorServer(directoryURL,environment,null,mbeanServer)}</p>
+ *
+ * @param url the URL defining how to create the connector server.
+ * Cannot be null.
+ *
+ * @param environment attributes governing the creation and
+ * storing of the RMI object. Can be null, which is equivalent to
+ * an empty Map.
+ *
+ * @param mbeanServer the MBean server to which the new connector
+ * server is attached, or null if it will be attached by being
+ * registered as an MBean in the MBean server.
+ *
+ * @exception IllegalArgumentException if <code>url</code> is null.
+ *
+ * @exception MalformedURLException if <code>url</code> does not
+ * conform to the syntax for an RMI connector, or if its protocol
+ * is not recognized by this implementation. Only "rmi" is valid
+ * when this constructor is used.
+ *
+ * @exception IOException if the connector server cannot be created
+ * for some reason or if it is inevitable that its {@link #start()
+ * start} method will fail.
+ */
+ public RMIConnectorServer(JMXServiceURL url, Map<String,?> environment,
+ MBeanServer mbeanServer)
+ throws IOException {
+ this(url, environment, (RMIServerImpl) null, mbeanServer);
+ }
+
+ /**
+ * <p>Makes an <code>RMIConnectorServer</code> for the given MBean
+ * server.</p>
+ *
+ * @param url the URL defining how to create the connector server.
+ * Cannot be null.
+ *
+ * @param environment attributes governing the creation and
+ * storing of the RMI object. Can be null, which is equivalent to
+ * an empty Map.
+ *
+ * @param rmiServerImpl An implementation of the RMIServer interface,
+ * consistent with the protocol type specified in <var>url</var>.
+ * If this parameter is non null, the protocol type specified by
+ * <var>url</var> is not constrained, and is assumed to be valid.
+ * Otherwise, only "rmi" will be recognized.
+ *
+ * @param mbeanServer the MBean server to which the new connector
+ * server is attached, or null if it will be attached by being
+ * registered as an MBean in the MBean server.
+ *
+ * @exception IllegalArgumentException if <code>url</code> is null.
+ *
+ * @exception MalformedURLException if <code>url</code> does not
+ * conform to the syntax for an RMI connector, or if its protocol
+ * is not recognized by this implementation. Only "rmi" is recognized
+ * when <var>rmiServerImpl</var> is null.
+ *
+ * @exception IOException if the connector server cannot be created
+ * for some reason or if it is inevitable that its {@link #start()
+ * start} method will fail.
+ *
+ * @see #start
+ */
+ public RMIConnectorServer(JMXServiceURL url, Map<String,?> environment,
+ RMIServerImpl rmiServerImpl,
+ MBeanServer mbeanServer)
+ throws IOException {
+ super(mbeanServer);
+
+ if (url == null) throw new
+ IllegalArgumentException("Null JMXServiceURL");
+ if (rmiServerImpl == null) {
+ final String prt = url.getProtocol();
+ if (prt == null || !(prt.equals("rmi"))) {
+ final String msg = "Invalid protocol type: " + prt;
+ throw new MalformedURLException(msg);
+ }
+ final String urlPath = url.getURLPath();
+ if (!urlPath.equals("")
+ && !urlPath.equals("/")
+ && !urlPath.startsWith("/jndi/")) {
+ final String msg = "URL path must be empty or start with " +
+ "/jndi/";
+ throw new MalformedURLException(msg);
+ }
+ }
+
+ if (environment == null)
+ this.attributes = Collections.emptyMap();
+ else {
+ EnvHelp.checkAttributes(environment);
+ this.attributes = Collections.unmodifiableMap(environment);
+ }
+
+ this.address = url;
+ this.rmiServerImpl = rmiServerImpl;
+ }
+
+ /**
+ * <p>Returns a client stub for this connector server. A client
+ * stub is a serializable object whose {@link
+ * JMXConnector#connect(Map) connect} method can be used to make
+ * one new connection to this connector server.</p>
+ *
+ * @param env client connection parameters of the same sort that
+ * could be provided to {@link JMXConnector#connect(Map)
+ * JMXConnector.connect(Map)}. Can be null, which is equivalent
+ * to an empty map.
+ *
+ * @return a client stub that can be used to make a new connection
+ * to this connector server.
+ *
+ * @exception UnsupportedOperationException if this connector
+ * server does not support the generation of client stubs.
+ *
+ * @exception IllegalStateException if the JMXConnectorServer is
+ * not started (see {@link #isActive()}).
+ *
+ * @exception IOException if a communications problem means that a
+ * stub cannot be created.
+ **/
+ public JMXConnector toJMXConnector(Map<String,?> env) throws IOException {
+ // The serialized for of rmiServerImpl is automatically
+ // a RMI server stub.
+ if (!isActive()) throw new
+ IllegalStateException("Connector is not active");
+
+ // Merge maps
+ Map<String, Object> usemap = new HashMap<String, Object>(
+ (this.attributes==null)?Collections.<String, Object>emptyMap():
+ this.attributes);
+
+ if (env != null) {
+ EnvHelp.checkAttributes(env);
+ usemap.putAll(env);
+ }
+
+ usemap = EnvHelp.filterAttributes(usemap);
+
+ final RMIServer stub=(RMIServer)rmiServerImpl.toStub();
+
+ return new RMIConnector(stub, usemap);
+ }
+
+ /**
+ * <p>Activates the connector server, that is starts listening for
+ * client connections. Calling this method when the connector
+ * server is already active has no effect. Calling this method
+ * when the connector server has been stopped will generate an
+ * <code>IOException</code>.</p>
+ *
+ * <p>The behavior of this method when called for the first time
+ * depends on the parameters that were supplied at construction,
+ * as described below.</p>
+ *
+ * <p>First, an object of a subclass of {@link RMIServerImpl} is
+ * required, to export the connector server through RMI:</p>
+ *
+ * <ul>
+ *
+ * <li>If an <code>RMIServerImpl</code> was supplied to the
+ * constructor, it is used.
+ *
+ * <li>Otherwise, if the <code>JMXServiceURL</code>
+ * was null, or its protocol part was <code>rmi</code>, an object
+ * of type {@link RMIJRMPServerImpl} is created.
+ *
+ * <li>Otherwise, the implementation can create an
+ * implementation-specific {@link RMIServerImpl} or it can throw
+ * {@link MalformedURLException}.
+ *
+ * </ul>
+ *
+ * <p>If the given address includes a JNDI directory URL as
+ * specified in the package documentation for {@link
+ * javax.management.remote.rmi}, then this
+ * <code>RMIConnectorServer</code> will bootstrap by binding the
+ * <code>RMIServerImpl</code> to the given address.</p>
+ *
+ * <p>If the URL path part of the <code>JMXServiceURL</code> was
+ * empty or a single slash (<code>/</code>), then the RMI object
+ * will not be bound to a directory. Instead, a reference to it
+ * will be encoded in the URL path of the RMIConnectorServer
+ * address (returned by {@link #getAddress()}). The encodings for
+ * <code>rmi</code> are described in the package documentation for
+ * {@link javax.management.remote.rmi}.</p>
+ *
+ * <p>The behavior when the URL path is neither empty nor a JNDI
+ * directory URL, or when the protocol is not <code>rmi</code>,
+ * is implementation defined, and may include throwing
+ * {@link MalformedURLException} when the connector server is created
+ * or when it is started.</p>
+ *
+ * @exception IllegalStateException if the connector server has
+ * not been attached to an MBean server.
+ * @exception IOException if the connector server cannot be
+ * started.
+ */
+ public synchronized void start() throws IOException {
+ final boolean tracing = logger.traceOn();
+
+ if (state == STARTED) {
+ if (tracing) logger.trace("start", "already started");
+ return;
+ } else if (state == STOPPED) {
+ if (tracing) logger.trace("start", "already stopped");
+ throw new IOException("The server has been stopped.");
+ }
+
+ if (getMBeanServer() == null)
+ throw new IllegalStateException("This connector server is not " +
+ "attached to an MBean server");
+
+ // Check the internal access file property to see
+ // if an MBeanServerForwarder is to be provided
+ //
+ if (attributes != null) {
+ // Check if access file property is specified
+ //
+ String accessFile =
+ (String) attributes.get("jmx.remote.x.access.file");
+ if (accessFile != null) {
+ // Access file property specified, create an instance
+ // of the MBeanServerFileAccessController class
+ //
+ MBeanServerForwarder mbsf;
+ try {
+ mbsf = new MBeanServerFileAccessController(accessFile);
+ } catch (IOException e) {
+ throw EnvHelp.initCause(
+ new IllegalArgumentException(e.getMessage()), e);
+ }
+ // Set the MBeanServerForwarder
+ //
+ setMBeanServerForwarder(mbsf);
+ }
+ }
+
+ try {
+ if (tracing) logger.trace("start", "setting default class loader");
+ defaultClassLoader = EnvHelp.resolveServerClassLoader(
+ attributes, getMBeanServer());
+ } catch (InstanceNotFoundException infc) {
+ IllegalArgumentException x = new
+ IllegalArgumentException("ClassLoader not found: "+infc);
+ throw EnvHelp.initCause(x,infc);
+ }
+
+ if (tracing) logger.trace("start", "setting RMIServer object");
+ final RMIServerImpl rmiServer;
+
+ if (rmiServerImpl != null)
+ rmiServer = rmiServerImpl;
+ else
+ rmiServer = newServer();
+
+ rmiServer.setMBeanServer(getMBeanServer());
+ rmiServer.setDefaultClassLoader(defaultClassLoader);
+ rmiServer.setRMIConnectorServer(this);
+ rmiServer.export();
+
+ try {
+ if (tracing) logger.trace("start", "getting RMIServer object to export");
+ final RMIServer objref = objectToBind(rmiServer, attributes);
+
+ if (address != null && address.getURLPath().startsWith("/jndi/")) {
+ final String jndiUrl = address.getURLPath().substring(6);
+
+ if (tracing)
+ logger.trace("start", "Using external directory: " + jndiUrl);
+
+ String stringBoolean = (String) attributes.get(JNDI_REBIND_ATTRIBUTE);
+ final boolean rebind = EnvHelp.computeBooleanFromString( stringBoolean );
+
+ if (tracing)
+ logger.trace("start", JNDI_REBIND_ATTRIBUTE + "=" + rebind);
+
+ try {
+ if (tracing) logger.trace("start", "binding to " + jndiUrl);
+
+ final Hashtable<?, ?> usemap = EnvHelp.mapToHashtable(attributes);
+
+ bind(jndiUrl, usemap, objref, rebind);
+
+ boundJndiUrl = jndiUrl;
+ } catch (NamingException e) {
+ // fit e in the nested exception if we are on 1.4
+ throw newIOException("Cannot bind to URL ["+jndiUrl+"]: "
+ + e, e);
+ }
+ } else {
+ // if jndiURL is null, we must encode the stub into the URL.
+ if (tracing) logger.trace("start", "Encoding URL");
+
+ encodeStubInAddress(objref, attributes);
+
+ if (tracing) logger.trace("start", "Encoded URL: " + this.address);
+ }
+ } catch (Exception e) {
+ try {
+ rmiServer.close();
+ } catch (Exception x) {
+ // OK: we are already throwing another exception
+ }
+ if (e instanceof RuntimeException)
+ throw (RuntimeException) e;
+ else if (e instanceof IOException)
+ throw (IOException) e;
+ else
+ throw newIOException("Got unexpected exception while " +
+ "starting the connector server: "
+ + e, e);
+ }
+
+ rmiServerImpl = rmiServer;
+
+ synchronized(openedServers) {
+ openedServers.add(this);
+ }
+
+ state = STARTED;
+
+ if (tracing) {
+ logger.trace("start", "Connector Server Address = " + address);
+ logger.trace("start", "started.");
+ }
+ }
+
+ /**
+ * <p>Deactivates the connector server, that is, stops listening for
+ * client connections. Calling this method will also close all
+ * client connections that were made by this server. After this
+ * method returns, whether normally or with an exception, the
+ * connector server will not create any new client
+ * connections.</p>
+ *
+ * <p>Once a connector server has been stopped, it cannot be started
+ * again.</p>
+ *
+ * <p>Calling this method when the connector server has already
+ * been stopped has no effect. Calling this method when the
+ * connector server has not yet been started will disable the
+ * connector server object permanently.</p>
+ *
+ * <p>If closing a client connection produces an exception, that
+ * exception is not thrown from this method. A {@link
+ * JMXConnectionNotification} is emitted from this MBean with the
+ * connection ID of the connection that could not be closed.</p>
+ *
+ * <p>Closing a connector server is a potentially slow operation.
+ * For example, if a client machine with an open connection has
+ * crashed, the close operation might have to wait for a network
+ * protocol timeout. Callers that do not want to block in a close
+ * operation should do it in a separate thread.</p>
+ *
+ * <p>This method calls the method {@link RMIServerImpl#close()
+ * close} on the connector server's <code>RMIServerImpl</code>
+ * object.</p>
+ *
+ * <p>If the <code>RMIServerImpl</code> was bound to a JNDI
+ * directory by the {@link #start() start} method, it is unbound
+ * from the directory by this method.</p>
+ *
+ * @exception IOException if the server cannot be closed cleanly,
+ * or if the <code>RMIServerImpl</code> cannot be unbound from the
+ * directory. When this exception is thrown, the server has
+ * already attempted to close all client connections, if
+ * appropriate; to call {@link RMIServerImpl#close()}; and to
+ * unbind the <code>RMIServerImpl</code> from its directory, if
+ * appropriate. All client connections are closed except possibly
+ * those that generated exceptions when the server attempted to
+ * close them.
+ */
+ public void stop() throws IOException {
+ final boolean tracing = logger.traceOn();
+
+ synchronized (this) {
+ if (state == STOPPED) {
+ if (tracing) logger.trace("stop","already stopped.");
+ return;
+ } else if (state == CREATED) {
+ if (tracing) logger.trace("stop","not started yet.");
+ }
+
+ if (tracing) logger.trace("stop", "stopping.");
+ state = STOPPED;
+ }
+
+ synchronized(openedServers) {
+ openedServers.remove(this);
+ }
+
+ IOException exception = null;
+
+ // rmiServerImpl can be null if stop() called without start()
+ if (rmiServerImpl != null) {
+ try {
+ if (tracing) logger.trace("stop", "closing RMI server.");
+ rmiServerImpl.close();
+ } catch (IOException e) {
+ if (tracing) logger.trace("stop", "failed to close RMI server: " + e);
+ if (logger.debugOn()) logger.debug("stop",e);
+ exception = e;
+ }
+ }
+
+ if (boundJndiUrl != null) {
+ try {
+ if (tracing)
+ logger.trace("stop",
+ "unbind from external directory: " + boundJndiUrl);
+
+ final Hashtable<?, ?> usemap = EnvHelp.mapToHashtable(attributes);
+
+ InitialContext ctx =
+ new InitialContext(usemap);
+
+ ctx.unbind(boundJndiUrl);
+
+ ctx.close();
+ } catch (NamingException e) {
+ if (tracing) logger.trace("stop", "failed to unbind RMI server: "+e);
+ if (logger.debugOn()) logger.debug("stop",e);
+ // fit e in as the nested exception if we are on 1.4
+ if (exception == null)
+ exception = newIOException("Cannot bind to URL: " + e, e);
+ }
+ }
+
+ if (exception != null) throw exception;
+
+ if (tracing) logger.trace("stop", "stopped");
+ }
+
+ public synchronized boolean isActive() {
+ return (state == STARTED);
+ }
+
+ public JMXServiceURL getAddress() {
+ if (!isActive())
+ return null;
+ return address;
+ }
+
+ public Map<String,?> getAttributes() {
+ Map<String, ?> map = EnvHelp.filterAttributes(attributes);
+ return Collections.unmodifiableMap(map);
+ }
+
+ @Override
+ public synchronized
+ void setMBeanServerForwarder(MBeanServerForwarder mbsf) {
+ super.setMBeanServerForwarder(mbsf);
+ if (rmiServerImpl != null)
+ rmiServerImpl.setMBeanServer(getMBeanServer());
+ }
+
+ /* We repeat the definitions of connection{Opened,Closed,Failed}
+ here so that they are accessible to other classes in this package
+ even though they have protected access. */
+
+ @Override
+ protected void connectionOpened(String connectionId, String message,
+ Object userData) {
+ super.connectionOpened(connectionId, message, userData);
+ }
+
+ @Override
+ protected void connectionClosed(String connectionId, String message,
+ Object userData) {
+ super.connectionClosed(connectionId, message, userData);
+ }
+
+ @Override
+ protected void connectionFailed(String connectionId, String message,
+ Object userData) {
+ super.connectionFailed(connectionId, message, userData);
+ }
+
+ /**
+ * Bind a stub to a registry.
+ * @param jndiUrl URL of the stub in the registry, extracted
+ * from the <code>JMXServiceURL</code>.
+ * @param attributes A Hashtable containing environment parameters,
+ * built from the Map specified at this object creation.
+ * @param rmiServer The object to bind in the registry
+ * @param rebind true if the object must be rebound.
+ **/
+ void bind(String jndiUrl, Hashtable<?, ?> attributes,
+ RMIServer rmiServer, boolean rebind)
+ throws NamingException, MalformedURLException {
+ // if jndiURL is not null, we nust bind the stub to a
+ // directory.
+ InitialContext ctx =
+ new InitialContext(attributes);
+
+ if (rebind)
+ ctx.rebind(jndiUrl, rmiServer);
+ else
+ ctx.bind(jndiUrl, rmiServer);
+ ctx.close();
+ }
+
+ /**
+ * Creates a new RMIServerImpl.
+ **/
+ RMIServerImpl newServer() throws IOException {
+ final int port;
+ if (address == null)
+ port = 0;
+ else
+ port = address.getPort();
+
+ return newJRMPServer(attributes, port);
+ }
+
+ /**
+ * Encode a stub into the JMXServiceURL.
+ * @param rmiServer The stub object to encode in the URL
+ * @param attributes A Map containing environment parameters,
+ * built from the Map specified at this object creation.
+ **/
+ private void encodeStubInAddress(
+ RMIServer rmiServer, Map<String, ?> attributes)
+ throws IOException {
+
+ final String protocol, host;
+ final int port;
+
+ if (address == null) {
+ protocol = "rmi";
+ host = null; // will default to local host name
+ port = 0;
+ } else {
+ protocol = address.getProtocol();
+ host = (address.getHost().equals("")) ? null : address.getHost();
+ port = address.getPort();
+ }
+
+ final String urlPath = encodeStub(rmiServer, attributes);
+
+ address = new JMXServiceURL(protocol, host, port, urlPath);
+ }
+
+ /**
+ * Returns the IOR of the given rmiServer.
+ **/
+ static String encodeStub(
+ RMIServer rmiServer, Map<String, ?> env) throws IOException {
+ return "/stub/" + encodeJRMPStub(rmiServer, env);
+ }
+
+ static String encodeJRMPStub(
+ RMIServer rmiServer, Map<String, ?> env)
+ throws IOException {
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ ObjectOutputStream oout = new ObjectOutputStream(bout);
+ oout.writeObject(rmiServer);
+ oout.close();
+ byte[] bytes = bout.toByteArray();
+ return byteArrayToBase64(bytes);
+ }
+
+ /**
+ * Object that we will bind to the registry.
+ * This object is a stub connected to our RMIServerImpl.
+ **/
+ private static RMIServer objectToBind(
+ RMIServerImpl rmiServer, Map<String, ?> env)
+ throws IOException {
+ return (RMIServer)rmiServer.toStub();
+ }
+
+ private static RMIServerImpl newJRMPServer(Map<String, ?> env, int port)
+ throws IOException {
+ RMIClientSocketFactory csf = (RMIClientSocketFactory)
+ env.get(RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE);
+ RMIServerSocketFactory ssf = (RMIServerSocketFactory)
+ env.get(RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE);
+ return new RMIJRMPServerImpl(port, csf, ssf, env);
+ }
+
+ private static String byteArrayToBase64(byte[] a) {
+ int aLen = a.length;
+ int numFullGroups = aLen/3;
+ int numBytesInPartialGroup = aLen - 3*numFullGroups;
+ int resultLen = 4*((aLen + 2)/3);
+ final StringBuilder result = new StringBuilder(resultLen);
+
+ // Translate all full groups from byte array elements to Base64
+ int inCursor = 0;
+ for (int i=0; i<numFullGroups; i++) {
+ int byte0 = a[inCursor++] & 0xff;
+ int byte1 = a[inCursor++] & 0xff;
+ int byte2 = a[inCursor++] & 0xff;
+ result.append(intToAlpha[byte0 >> 2]);
+ result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
+ result.append(intToAlpha[(byte1 << 2)&0x3f | (byte2 >> 6)]);
+ result.append(intToAlpha[byte2 & 0x3f]);
+ }
+
+ // Translate partial group if present
+ if (numBytesInPartialGroup != 0) {
+ int byte0 = a[inCursor++] & 0xff;
+ result.append(intToAlpha[byte0 >> 2]);
+ if (numBytesInPartialGroup == 1) {
+ result.append(intToAlpha[(byte0 << 4) & 0x3f]);
+ result.append("==");
+ } else {
+ // assert numBytesInPartialGroup == 2;
+ int byte1 = a[inCursor++] & 0xff;
+ result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
+ result.append(intToAlpha[(byte1 << 2)&0x3f]);
+ result.append('=');
+ }
+ }
+ // assert inCursor == a.length;
+ // assert result.length() == resultLen;
+ return result.toString();
+ }
+
+ /**
+ * This array is a lookup table that translates 6-bit positive integer
+ * index values into their "Base64 Alphabet" equivalents as specified
+ * in Table 1 of RFC 2045.
+ */
+ private static final char intToAlpha[] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
+ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
+ };
+
+ /**
+ * Construct a new IOException with a nested exception.
+ * The nested exception is set only if JDK {@literal >= 1.4}
+ */
+ private static IOException newIOException(String message,
+ Throwable cause) {
+ final IOException x = new IOException(message);
+ return EnvHelp.initCause(x,cause);
+ }
+
+
+ // Private variables
+ // -----------------
+
+ private static ClassLogger logger =
+ new ClassLogger("javax.management.remote.rmi", "RMIConnectorServer");
+
+ private JMXServiceURL address;
+ private RMIServerImpl rmiServerImpl;
+ private final Map<String, ?> attributes;
+ private ClassLoader defaultClassLoader = null;
+
+ private String boundJndiUrl;
+
+ // state
+ private static final int CREATED = 0;
+ private static final int STARTED = 1;
+ private static final int STOPPED = 2;
+
+ private int state = CREATED;
+ private final static Set<RMIConnectorServer> openedServers =
+ new HashSet<RMIConnectorServer>();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIIIOPServerImpl.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,96 @@
+/*
+ * 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 javax.management.remote.rmi;
+
+import java.io.IOException;
+import java.rmi.Remote;
+import java.util.Map;
+import javax.security.auth.Subject;
+
+/**
+ * <p>An {@link RMIServerImpl} that is exported through IIOP and that
+ * creates client connections as RMI objects exported through IIOP.
+ * User code does not usually reference this class directly.</p>
+ *
+ * @see RMIServerImpl
+ *
+ * @since 1.5
+ * @deprecated This transport is no longer supported.
+ */
+@Deprecated
+public class RMIIIOPServerImpl extends RMIServerImpl {
+ /**
+ * Throws {@linkplain UnsupportedOperationException}
+ *
+ * @param env the environment containing attributes for the new
+ * <code>RMIServerImpl</code>. Can be null, which is equivalent
+ * to an empty Map.
+ *
+ * @throws IOException if the RMI object cannot be created.
+ */
+ public RMIIIOPServerImpl(Map<String,?> env)
+ throws IOException {
+ super(env);
+
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void export() throws IOException {
+ throw new UnsupportedOperationException("Method not supported. JMX RMI-IIOP is deprecated");
+ }
+
+ @Override
+ protected String getProtocol() {
+ return "iiop";
+ }
+
+ @Override
+ public Remote toStub() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected RMIConnection makeClient(String connectionId, Subject subject)
+ throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void closeClient(RMIConnection client) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ protected void closeServer() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ RMIConnection doNewClient(final Object credentials) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.management.remote.rmi;
+
+import java.io.IOException;
+import java.rmi.NoSuchObjectException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+import java.rmi.server.UnicastRemoteObject;
+import java.rmi.server.RemoteObject;
+import java.util.Map;
+import java.util.Collections;
+import javax.security.auth.Subject;
+
+import com.sun.jmx.remote.internal.rmi.RMIExporter;
+import com.sun.jmx.remote.util.EnvHelp;
+import java.io.ObjectStreamClass;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import sun.reflect.misc.ReflectUtil;
+import sun.rmi.server.DeserializationChecker;
+import sun.rmi.server.UnicastServerRef;
+import sun.rmi.server.UnicastServerRef2;
+
+/**
+ * <p>An {@link RMIServer} object that is exported through JRMP and that
+ * creates client connections as RMI objects exported through JRMP.
+ * User code does not usually reference this class directly.</p>
+ *
+ * @see RMIServerImpl
+ *
+ * @since 1.5
+ */
+public class RMIJRMPServerImpl extends RMIServerImpl {
+
+ private final ExportedWrapper exportedWrapper;
+
+ /**
+ * <p>Creates a new {@link RMIServer} object that will be exported
+ * on the given port using the given socket factories.</p>
+ *
+ * @param port the port on which this object and the {@link
+ * RMIConnectionImpl} objects it creates will be exported. Can be
+ * zero, to indicate any available port.
+ *
+ * @param csf the client socket factory for the created RMI
+ * objects. Can be null.
+ *
+ * @param ssf the server socket factory for the created RMI
+ * objects. Can be null.
+ *
+ * @param env the environment map. Can be null.
+ *
+ * @exception IOException if the {@link RMIServer} object
+ * cannot be created.
+ *
+ * @exception IllegalArgumentException if <code>port</code> is
+ * negative.
+ */
+ public RMIJRMPServerImpl(int port,
+ RMIClientSocketFactory csf,
+ RMIServerSocketFactory ssf,
+ Map<String,?> env)
+ throws IOException {
+
+ super(env);
+
+ if (port < 0)
+ throw new IllegalArgumentException("Negative port: " + port);
+
+ this.port = port;
+ this.csf = csf;
+ this.ssf = ssf;
+ this.env = (env == null) ? Collections.<String, Object>emptyMap() : env;
+
+ String[] credentialsTypes
+ = (String[]) this.env.get(RMIConnectorServer.CREDENTIAL_TYPES);
+ List<String> types = null;
+ if (credentialsTypes != null) {
+ types = new ArrayList<>();
+ for (String type : credentialsTypes) {
+ if (type == null) {
+ throw new IllegalArgumentException("A credential type is null.");
+ }
+ ReflectUtil.checkPackageAccess(type);
+ types.add(type);
+ }
+ }
+ exportedWrapper = types != null ?
+ new ExportedWrapper(this, types) :
+ null;
+ }
+
+ protected void export() throws IOException {
+ if (exportedWrapper != null) {
+ export(exportedWrapper);
+ } else {
+ export(this);
+ }
+ }
+
+ private void export(Remote obj) throws RemoteException {
+ final RMIExporter exporter =
+ (RMIExporter) env.get(RMIExporter.EXPORTER_ATTRIBUTE);
+ final boolean daemon = EnvHelp.isServerDaemon(env);
+
+ if (daemon && exporter != null) {
+ throw new IllegalArgumentException("If "+EnvHelp.JMX_SERVER_DAEMON+
+ " is specified as true, "+RMIExporter.EXPORTER_ATTRIBUTE+
+ " cannot be used to specify an exporter!");
+ }
+
+ if (daemon) {
+ if (csf == null && ssf == null) {
+ new UnicastServerRef(port).exportObject(obj, null, true);
+ } else {
+ new UnicastServerRef2(port, csf, ssf).exportObject(obj, null, true);
+ }
+ } else if (exporter != null) {
+ exporter.exportObject(obj, port, csf, ssf);
+ } else {
+ UnicastRemoteObject.exportObject(obj, port, csf, ssf);
+ }
+ }
+
+ private void unexport(Remote obj, boolean force)
+ throws NoSuchObjectException {
+ RMIExporter exporter =
+ (RMIExporter) env.get(RMIExporter.EXPORTER_ATTRIBUTE);
+ if (exporter == null)
+ UnicastRemoteObject.unexportObject(obj, force);
+ else
+ exporter.unexportObject(obj, force);
+ }
+
+ protected String getProtocol() {
+ return "rmi";
+ }
+
+ /**
+ * <p>Returns a serializable stub for this {@link RMIServer} object.</p>
+ *
+ * @return a serializable stub.
+ *
+ * @exception IOException if the stub cannot be obtained - e.g the
+ * RMIJRMPServerImpl has not been exported yet.
+ */
+ public Remote toStub() throws IOException {
+ if (exportedWrapper != null) {
+ return RemoteObject.toStub(exportedWrapper);
+ } else {
+ return RemoteObject.toStub(this);
+ }
+ }
+
+ /**
+ * <p>Creates a new client connection as an RMI object exported
+ * through JRMP. The port and socket factories for the new
+ * {@link RMIConnection} object are the ones supplied
+ * to the <code>RMIJRMPServerImpl</code> constructor.</p>
+ *
+ * @param connectionId the ID of the new connection. Every
+ * connection opened by this connector server will have a
+ * different id. The behavior is unspecified if this parameter is
+ * null.
+ *
+ * @param subject the authenticated subject. Can be null.
+ *
+ * @return the newly-created <code>RMIConnection</code>.
+ *
+ * @exception IOException if the new {@link RMIConnection}
+ * object cannot be created or exported.
+ */
+ protected RMIConnection makeClient(String connectionId, Subject subject)
+ throws IOException {
+
+ if (connectionId == null)
+ throw new NullPointerException("Null connectionId");
+
+ RMIConnection client =
+ new RMIConnectionImpl(this, connectionId, getDefaultClassLoader(),
+ subject, env);
+ export(client);
+ return client;
+ }
+
+ protected void closeClient(RMIConnection client) throws IOException {
+ unexport(client, true);
+ }
+
+ /**
+ * <p>Called by {@link #close()} to close the connector server by
+ * unexporting this object. After returning from this method, the
+ * connector server must not accept any new connections.</p>
+ *
+ * @exception IOException if the attempt to close the connector
+ * server failed.
+ */
+ protected void closeServer() throws IOException {
+ if (exportedWrapper != null) {
+ unexport(exportedWrapper, true);
+ } else {
+ unexport(this, true);
+ }
+ }
+
+ private final int port;
+ private final RMIClientSocketFactory csf;
+ private final RMIServerSocketFactory ssf;
+ private final Map<String, ?> env;
+
+ private static class ExportedWrapper implements RMIServer, DeserializationChecker {
+ private final RMIServer impl;
+ private final List<String> allowedTypes;
+
+ private ExportedWrapper(RMIServer impl, List<String> credentialsTypes) {
+ this.impl = impl;
+ allowedTypes = credentialsTypes;
+ }
+
+ @Override
+ public String getVersion() throws RemoteException {
+ return impl.getVersion();
+ }
+
+ @Override
+ public RMIConnection newClient(Object credentials) throws IOException {
+ return impl.newClient(credentials);
+ }
+
+ @Override
+ public void check(Method method, ObjectStreamClass descriptor,
+ int paramIndex, int callID) {
+ String type = descriptor.getName();
+ if (!allowedTypes.contains(type)) {
+ throw new ClassCastException("Unsupported type: " + type);
+ }
+ }
+
+ @Override
+ public void checkProxyClass(Method method, String[] ifaces,
+ int paramIndex, int callID) {
+ if (ifaces != null && ifaces.length > 0) {
+ for (String iface : ifaces) {
+ if (!allowedTypes.contains(iface)) {
+ throw new ClassCastException("Unsupported type: " + iface);
+ }
+ }
+ }
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIServer.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.management.remote.rmi;
+
+import java.io.IOException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
+/**
+ * <p>RMI object used to establish connections to an RMI connector.
+ * There is one Remote object implementing this interface for each RMI
+ * connector.</p>
+ *
+ * <p>User code does not usually refer to this interface. It is
+ * specified as part of the public API so that different
+ * implementations of that API will interoperate.</p>
+ *
+ * @since 1.5
+ */
+public interface RMIServer extends Remote {
+ /**
+ * <p>The version of the RMI Connector Protocol understood by this
+ * connector server. This is a string with the following format:</p>
+ *
+ * <pre>
+ * <em>protocol-version</em> <em>implementation-name</em>
+ * </pre>
+ *
+ * <p>The <code><em>protocol-version</em></code> is a series of
+ * two or more non-negative integers separated by periods
+ * (<code>.</code>). An implementation of the version described
+ * by this documentation must use the string <code>1.0</code>
+ * here.</p>
+ *
+ * <p>After the protocol version there must be a space, followed
+ * by the implementation name. The format of the implementation
+ * name is unspecified. It is recommended that it include an
+ * implementation version number. An implementation can use an
+ * empty string as its implementation name, for example for
+ * security reasons.</p>
+ *
+ * @return a string with the format described here.
+ *
+ * @exception RemoteException if there is a communication
+ * exception during the remote method call.
+ */
+ public String getVersion() throws RemoteException;
+
+ /**
+ * <p>Makes a new connection through this RMI connector. Each
+ * remote client calls this method to obtain a new RMI object
+ * representing its connection.</p>
+ *
+ * @param credentials this object specifies the user-defined credentials
+ * to be passed in to the server in order to authenticate the user before
+ * creating the <code>RMIConnection</code>. Can be null.
+ *
+ * @return the newly-created connection object.
+ *
+ * @exception IOException if the new client object cannot be
+ * created or exported, or if there is a communication exception
+ * during the remote method call.
+ *
+ * @exception SecurityException if the given credentials do not
+ * allow the server to authenticate the caller successfully.
+ */
+ public RMIConnection newClient(Object credentials) throws IOException;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIServerImpl.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,550 @@
+/*
+ * Copyright (c) 2002, 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 javax.management.remote.rmi;
+
+import com.sun.jmx.remote.internal.ArrayNotificationBuffer;
+import com.sun.jmx.remote.internal.NotificationBuffer;
+import com.sun.jmx.remote.security.JMXPluggableAuthenticator;
+import com.sun.jmx.remote.util.ClassLogger;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.rmi.Remote;
+import java.rmi.server.RemoteServer;
+import java.rmi.server.ServerNotActiveException;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.management.MBeanServer;
+import javax.management.remote.JMXAuthenticator;
+import javax.management.remote.JMXConnectorServer;
+import javax.security.auth.Subject;
+
+/**
+ * <p>An RMI object representing a connector server. Remote clients
+ * can make connections using the {@link #newClient(Object)} method. This
+ * method returns an RMI object representing the connection.</p>
+ *
+ * <p>User code does not usually reference this class directly.
+ * RMI connection servers are usually created with the class {@link
+ * RMIConnectorServer}. Remote clients usually create connections
+ * either with {@link javax.management.remote.JMXConnectorFactory}
+ * or by instantiating {@link RMIConnector}.</p>
+ *
+ * <p>This is an abstract class. Concrete subclasses define the
+ * details of the client connection objects.</p>
+ *
+ * @since 1.5
+ */
+public abstract class RMIServerImpl implements Closeable, RMIServer {
+ /**
+ * <p>Constructs a new <code>RMIServerImpl</code>.</p>
+ *
+ * @param env the environment containing attributes for the new
+ * <code>RMIServerImpl</code>. Can be null, which is equivalent
+ * to an empty Map.
+ */
+ public RMIServerImpl(Map<String,?> env) {
+ this.env = (env == null) ? Collections.<String,Object>emptyMap() : env;
+ }
+
+ void setRMIConnectorServer(RMIConnectorServer connServer)
+ throws IOException {
+ this.connServer = connServer;
+ }
+
+ /**
+ * <p>Exports this RMI object.</p>
+ *
+ * @exception IOException if this RMI object cannot be exported.
+ */
+ protected abstract void export() throws IOException;
+
+ /**
+ * Returns a remotable stub for this server object.
+ * @return a remotable stub.
+ * @exception IOException if the stub cannot be obtained - e.g the
+ * RMIServerImpl has not been exported yet.
+ **/
+ public abstract Remote toStub() throws IOException;
+
+ /**
+ * <p>Sets the default <code>ClassLoader</code> for this connector
+ * server. New client connections will use this classloader.
+ * Existing client connections are unaffected.</p>
+ *
+ * @param cl the new <code>ClassLoader</code> to be used by this
+ * connector server.
+ *
+ * @see #getDefaultClassLoader
+ */
+ public synchronized void setDefaultClassLoader(ClassLoader cl) {
+ this.cl = cl;
+ }
+
+ /**
+ * <p>Gets the default <code>ClassLoader</code> used by this connector
+ * server.</p>
+ *
+ * @return the default <code>ClassLoader</code> used by this
+ * connector server.
+ *
+ * @see #setDefaultClassLoader
+ */
+ public synchronized ClassLoader getDefaultClassLoader() {
+ return cl;
+ }
+
+ /**
+ * <p>Sets the <code>MBeanServer</code> to which this connector
+ * server is attached. New client connections will interact
+ * with this <code>MBeanServer</code>. Existing client connections are
+ * unaffected.</p>
+ *
+ * @param mbs the new <code>MBeanServer</code>. Can be null, but
+ * new client connections will be refused as long as it is.
+ *
+ * @see #getMBeanServer
+ */
+ public synchronized void setMBeanServer(MBeanServer mbs) {
+ this.mbeanServer = mbs;
+ }
+
+ /**
+ * <p>The <code>MBeanServer</code> to which this connector server
+ * is attached. This is the last value passed to {@link
+ * #setMBeanServer} on this object, or null if that method has
+ * never been called.</p>
+ *
+ * @return the <code>MBeanServer</code> to which this connector
+ * is attached.
+ *
+ * @see #setMBeanServer
+ */
+ public synchronized MBeanServer getMBeanServer() {
+ return mbeanServer;
+ }
+
+ public String getVersion() {
+ // Expected format is: "protocol-version implementation-name"
+ try {
+ return "1.0 java_runtime_" +
+ System.getProperty("java.runtime.version");
+ } catch (SecurityException e) {
+ return "1.0 ";
+ }
+ }
+
+ /**
+ * <p>Creates a new client connection. This method calls {@link
+ * #makeClient makeClient} and adds the returned client connection
+ * object to an internal list. When this
+ * <code>RMIServerImpl</code> is shut down via its {@link
+ * #close()} method, the {@link RMIConnection#close() close()}
+ * method of each object remaining in the list is called.</p>
+ *
+ * <p>The fact that a client connection object is in this internal
+ * list does not prevent it from being garbage collected.</p>
+ *
+ * @param credentials this object specifies the user-defined
+ * credentials to be passed in to the server in order to
+ * authenticate the caller before creating the
+ * <code>RMIConnection</code>. Can be null.
+ *
+ * @return the newly-created <code>RMIConnection</code>. This is
+ * usually the object created by <code>makeClient</code>, though
+ * an implementation may choose to wrap that object in another
+ * object implementing <code>RMIConnection</code>.
+ *
+ * @exception IOException if the new client object cannot be
+ * created or exported.
+ *
+ * @exception SecurityException if the given credentials do not allow
+ * the server to authenticate the user successfully.
+ *
+ * @exception IllegalStateException if {@link #getMBeanServer()}
+ * is null.
+ */
+ public RMIConnection newClient(Object credentials) throws IOException {
+ return doNewClient(credentials);
+ }
+
+ /**
+ * This method could be overridden by subclasses defined in this package
+ * to perform additional operations specific to the underlying transport
+ * before creating the new client connection.
+ */
+ RMIConnection doNewClient(Object credentials) throws IOException {
+ final boolean tracing = logger.traceOn();
+
+ if (tracing) logger.trace("newClient","making new client");
+
+ if (getMBeanServer() == null)
+ throw new IllegalStateException("Not attached to an MBean server");
+
+ Subject subject = null;
+ JMXAuthenticator authenticator =
+ (JMXAuthenticator) env.get(JMXConnectorServer.AUTHENTICATOR);
+ if (authenticator == null) {
+ /*
+ * Create the JAAS-based authenticator only if authentication
+ * has been enabled
+ */
+ if (env.get("jmx.remote.x.password.file") != null ||
+ env.get("jmx.remote.x.login.config") != null) {
+ authenticator = new JMXPluggableAuthenticator(env);
+ }
+ }
+ if (authenticator != null) {
+ if (tracing) logger.trace("newClient","got authenticator: " +
+ authenticator.getClass().getName());
+ try {
+ subject = authenticator.authenticate(credentials);
+ } catch (SecurityException e) {
+ logger.trace("newClient", "Authentication failed: " + e);
+ throw e;
+ }
+ }
+
+ if (tracing) {
+ if (subject != null)
+ logger.trace("newClient","subject is not null");
+ else logger.trace("newClient","no subject");
+ }
+
+ final String connectionId = makeConnectionId(getProtocol(), subject);
+
+ if (tracing)
+ logger.trace("newClient","making new connection: " + connectionId);
+
+ RMIConnection client = makeClient(connectionId, subject);
+
+ dropDeadReferences();
+ WeakReference<RMIConnection> wr = new WeakReference<RMIConnection>(client);
+ synchronized (clientList) {
+ clientList.add(wr);
+ }
+
+ connServer.connectionOpened(connectionId, "Connection opened", null);
+
+ synchronized (clientList) {
+ if (!clientList.contains(wr)) {
+ // can be removed only by a JMXConnectionNotification listener
+ throw new IOException("The connection is refused.");
+ }
+ }
+
+ if (tracing)
+ logger.trace("newClient","new connection done: " + connectionId );
+
+ return client;
+ }
+
+ /**
+ * <p>Creates a new client connection. This method is called by
+ * the public method {@link #newClient(Object)}.</p>
+ *
+ * @param connectionId the ID of the new connection. Every
+ * connection opened by this connector server will have a
+ * different ID. The behavior is unspecified if this parameter is
+ * null.
+ *
+ * @param subject the authenticated subject. Can be null.
+ *
+ * @return the newly-created <code>RMIConnection</code>.
+ *
+ * @exception IOException if the new client object cannot be
+ * created or exported.
+ */
+ protected abstract RMIConnection makeClient(String connectionId,
+ Subject subject)
+ throws IOException;
+
+ /**
+ * <p>Closes a client connection made by {@link #makeClient makeClient}.
+ *
+ * @param client a connection previously returned by
+ * <code>makeClient</code> on which the <code>closeClient</code>
+ * method has not previously been called. The behavior is
+ * unspecified if these conditions are violated, including the
+ * case where <code>client</code> is null.
+ *
+ * @exception IOException if the client connection cannot be
+ * closed.
+ */
+ protected abstract void closeClient(RMIConnection client)
+ throws IOException;
+
+ /**
+ * <p>Returns the protocol string for this object. The string is
+ * <code>rmi</code> for RMI/JRMP.
+ *
+ * @return the protocol string for this object.
+ */
+ protected abstract String getProtocol();
+
+ /**
+ * <p>Method called when a client connection created by {@link
+ * #makeClient makeClient} is closed. A subclass that defines
+ * <code>makeClient</code> must arrange for this method to be
+ * called when the resultant object's {@link RMIConnection#close()
+ * close} method is called. This enables it to be removed from
+ * the <code>RMIServerImpl</code>'s list of connections. It is
+ * not an error for <code>client</code> not to be in that
+ * list.</p>
+ *
+ * <p>After removing <code>client</code> from the list of
+ * connections, this method calls {@link #closeClient
+ * closeClient(client)}.</p>
+ *
+ * @param client the client connection that has been closed.
+ *
+ * @exception IOException if {@link #closeClient} throws this
+ * exception.
+ *
+ * @exception NullPointerException if <code>client</code> is null.
+ */
+ protected void clientClosed(RMIConnection client) throws IOException {
+ final boolean debug = logger.debugOn();
+
+ if (debug) logger.trace("clientClosed","client="+client);
+
+ if (client == null)
+ throw new NullPointerException("Null client");
+
+ synchronized (clientList) {
+ dropDeadReferences();
+ for (Iterator<WeakReference<RMIConnection>> it = clientList.iterator();
+ it.hasNext(); ) {
+ WeakReference<RMIConnection> wr = it.next();
+ if (wr.get() == client) {
+ it.remove();
+ break;
+ }
+ }
+ /* It is not a bug for this loop not to find the client. In
+ our close() method, we remove a client from the list before
+ calling its close() method. */
+ }
+
+ if (debug) logger.trace("clientClosed", "closing client.");
+ closeClient(client);
+
+ if (debug) logger.trace("clientClosed", "sending notif");
+ connServer.connectionClosed(client.getConnectionId(),
+ "Client connection closed", null);
+
+ if (debug) logger.trace("clientClosed","done");
+ }
+
+ /**
+ * <p>Closes this connection server. This method first calls the
+ * {@link #closeServer()} method so that no new client connections
+ * will be accepted. Then, for each remaining {@link
+ * RMIConnection} object returned by {@link #makeClient
+ * makeClient}, its {@link RMIConnection#close() close} method is
+ * called.</p>
+ *
+ * <p>The behavior when this method is called more than once is
+ * unspecified.</p>
+ *
+ * <p>If {@link #closeServer()} throws an
+ * <code>IOException</code>, the individual connections are
+ * nevertheless closed, and then the <code>IOException</code> is
+ * thrown from this method.</p>
+ *
+ * <p>If {@link #closeServer()} returns normally but one or more
+ * of the individual connections throws an
+ * <code>IOException</code>, then, after closing all the
+ * connections, one of those <code>IOException</code>s is thrown
+ * from this method. If more than one connection throws an
+ * <code>IOException</code>, it is unspecified which one is thrown
+ * from this method.</p>
+ *
+ * @exception IOException if {@link #closeServer()} or one of the
+ * {@link RMIConnection#close()} calls threw
+ * <code>IOException</code>.
+ */
+ public synchronized void close() throws IOException {
+ final boolean tracing = logger.traceOn();
+ final boolean debug = logger.debugOn();
+
+ if (tracing) logger.trace("close","closing");
+
+ IOException ioException = null;
+ try {
+ if (debug) logger.debug("close","closing Server");
+ closeServer();
+ } catch (IOException e) {
+ if (tracing) logger.trace("close","Failed to close server: " + e);
+ if (debug) logger.debug("close",e);
+ ioException = e;
+ }
+
+ if (debug) logger.debug("close","closing Clients");
+ // Loop to close all clients
+ while (true) {
+ synchronized (clientList) {
+ if (debug) logger.debug("close","droping dead references");
+ dropDeadReferences();
+
+ if (debug) logger.debug("close","client count: "+clientList.size());
+ if (clientList.size() == 0)
+ break;
+ /* Loop until we find a non-null client. Because we called
+ dropDeadReferences(), this will usually be the first
+ element of the list, but a garbage collection could have
+ happened in between. */
+ for (Iterator<WeakReference<RMIConnection>> it = clientList.iterator();
+ it.hasNext(); ) {
+ WeakReference<RMIConnection> wr = it.next();
+ RMIConnection client = wr.get();
+ it.remove();
+ if (client != null) {
+ try {
+ client.close();
+ } catch (IOException e) {
+ if (tracing)
+ logger.trace("close","Failed to close client: " + e);
+ if (debug) logger.debug("close",e);
+ if (ioException == null)
+ ioException = e;
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ if(notifBuffer != null)
+ notifBuffer.dispose();
+
+ if (ioException != null) {
+ if (tracing) logger.trace("close","close failed.");
+ throw ioException;
+ }
+
+ if (tracing) logger.trace("close","closed.");
+ }
+
+ /**
+ * <p>Called by {@link #close()} to close the connector server.
+ * After returning from this method, the connector server must
+ * not accept any new connections.</p>
+ *
+ * @exception IOException if the attempt to close the connector
+ * server failed.
+ */
+ protected abstract void closeServer() throws IOException;
+
+ private static synchronized String makeConnectionId(String protocol,
+ Subject subject) {
+ connectionIdNumber++;
+
+ String clientHost = "";
+ try {
+ clientHost = RemoteServer.getClientHost();
+ /*
+ * According to the rules specified in the javax.management.remote
+ * package description, a numeric IPv6 address (detected by the
+ * presence of otherwise forbidden ":" character) forming a part
+ * of the connection id must be enclosed in square brackets.
+ */
+ if (clientHost.contains(":")) {
+ clientHost = "[" + clientHost + "]";
+ }
+ } catch (ServerNotActiveException e) {
+ logger.trace("makeConnectionId", "getClientHost", e);
+ }
+
+ final StringBuilder buf = new StringBuilder();
+ buf.append(protocol).append(":");
+ if (clientHost.length() > 0)
+ buf.append("//").append(clientHost);
+ buf.append(" ");
+ if (subject != null) {
+ Set<Principal> principals = subject.getPrincipals();
+ String sep = "";
+ for (Iterator<Principal> it = principals.iterator(); it.hasNext(); ) {
+ Principal p = it.next();
+ String name = p.getName().replace(' ', '_').replace(';', ':');
+ buf.append(sep).append(name);
+ sep = ";";
+ }
+ }
+ buf.append(" ").append(connectionIdNumber);
+ if (logger.traceOn())
+ logger.trace("newConnectionId","connectionId="+buf);
+ return buf.toString();
+ }
+
+ private void dropDeadReferences() {
+ synchronized (clientList) {
+ for (Iterator<WeakReference<RMIConnection>> it = clientList.iterator();
+ it.hasNext(); ) {
+ WeakReference<RMIConnection> wr = it.next();
+ if (wr.get() == null)
+ it.remove();
+ }
+ }
+ }
+
+ synchronized NotificationBuffer getNotifBuffer() {
+ //Notification buffer is lazily created when the first client connects
+ if(notifBuffer == null)
+ notifBuffer =
+ ArrayNotificationBuffer.getNotificationBuffer(mbeanServer,
+ env);
+ return notifBuffer;
+ }
+
+ private static final ClassLogger logger =
+ new ClassLogger("javax.management.remote.rmi", "RMIServerImpl");
+
+ /** List of WeakReference values. Each one references an
+ RMIConnection created by this object, or null if the
+ RMIConnection has been garbage-collected. */
+ private final List<WeakReference<RMIConnection>> clientList =
+ new ArrayList<WeakReference<RMIConnection>>();
+
+ private ClassLoader cl;
+
+ private MBeanServer mbeanServer;
+
+ private final Map<String, ?> env;
+
+ private RMIConnectorServer connServer;
+
+ private static int connectionIdNumber;
+
+ private NotificationBuffer notifBuffer;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/package.html Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,340 @@
+<html>
+<head>
+ <title>RMI connector</title>
+<!--
+Copyright (c) 2002, 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.
+-->
+</head>
+<body bgcolor="white">
+ <p>The RMI connector is a connector for the JMX Remote API that
+ uses RMI to transmit client requests to a remote MBean server.
+ This package defines the classes that the user of an RMI
+ connector needs to reference directly, for both the client and
+ server sides. It also defines certain classes that the user
+ will not usually reference directly, but that must be defined so
+ that different implementations of the RMI connector can
+ interoperate.</p>
+
+ <p>The RMI connector supports the JRMP transport for RMI.</p>
+
+ <p>Like most connectors in the JMX Remote API, an RMI connector
+ usually has an address, which
+ is a {@link javax.management.remote.JMXServiceURL
+ JMXServiceURL}. The protocol part of this address is
+ <code>rmi</code> for a connector that uses the default RMI
+ transport (JRMP).</p>
+
+ <p>There are two forms for RMI connector addresses:</p>
+
+ <ul>
+ <li>
+ In the <em>JNDI form</em>, the URL indicates <em>where to find
+ an RMI stub for the connector</em>. This RMI stub is a Java
+ object of type {@link javax.management.remote.rmi.RMIServer
+ RMIServer} that gives remote access to the connector server.
+ With this address form, the RMI stub is obtained from an
+ external directory entry included in the URL. An external
+ directory is any directory recognized by {@link javax.naming
+ JNDI}, typically the RMI registry, LDAP, or COS Naming.
+
+ <li>
+ In the <em>encoded form</em>, the URL directly includes the
+ information needed to connect to the connector server. When
+ using RMI/JRMP, the encoded form is the serialized RMI stub
+ for the server object, encoded using BASE64 without embedded
+ newlines.
+ </ul>
+
+ <p>Addresses are covered in more detail below.</p>
+
+
+ <h3>Creating an RMI connector server</h3>
+
+ <p>The usual way to create an RMI connector server is to supply an
+ RMI connector address to the method {@link
+ javax.management.remote.JMXConnectorServerFactory#newJMXConnectorServer
+ JMXConnectorServerFactory.newJMXConnectorServer}. The MBean
+ server to which the connector server is attached can be
+ specified as a parameter to that method. Alternatively, the
+ connector server can be registered as an MBean in that MBean
+ server.</p>
+
+ <p>An RMI connector server can also be created by constructing an
+ instance of {@link
+ javax.management.remote.rmi.RMIConnectorServer
+ RMIConnectorServer}, explicitly or through the MBean server's
+ <code>createMBean</code> method.</p>
+
+ <h4>Choosing the RMI transport</h4>
+
+ <p>You can choose the RMI transport by specifying
+ <code>rmi</code> in the <code><em>protocol</em></code> part of the
+ <code>serviceURL</code> when creating the connector server. You
+ can also create specialized connector servers by instantiating
+ an appropriate subclass of {@link
+ javax.management.remote.rmi.RMIServerImpl RMIServerImpl} and
+ supplying it to the <code>RMIConnectorServer</code>
+ constructor.</p>
+
+
+ <h4><a name="servergen">Connector addresses generated by the
+ server</a></h4>
+
+ <p>If the <code>serviceURL</code> you specify has an empty URL
+ path (after the optional host and port), or if you do not
+ specify a <code>serviceURL</code>, then the connector server
+ will fabricate a new <code>JMXServiceURL</code> that clients can
+ use to connect:</p>
+
+ <ul>
+
+ <li><p>If the <code>serviceURL</code> looks like:</p>
+
+ <pre>
+ <code>service:jmx:rmi://<em>host</em>:<em>port</em></code>
+ </pre>
+
+ <p>then the connector server will generate an {@link
+ javax.management.remote.rmi.RMIJRMPServerImpl
+ RMIJRMPServerImpl} and the returned <code>JMXServiceURL</code>
+ looks like:</p>
+
+ <pre>
+ <code>service:jmx:rmi://<em>host</em>:<em>port</em>/stub/<em>XXXX</em></code>
+ </pre>
+
+ <p>where <code><em>XXXX</em></code> is the serialized form of the
+ stub for the generated object, encoded in BASE64 without
+ newlines.</p>
+
+ <li><p>If there is no <code>serviceURL</code>, there must be a
+ user-provided <code>RMIServerImpl</code>. The connector server
+ will generate a <code>JMXServiceURL</code> using the <code>rmi</code>
+ form.</p>
+
+ </ul>
+
+ <p>The <code><em>host</em></code> in a user-provided
+ <code>serviceURL</code> is optional. If present, it is copied
+ into the generated <code>JMXServiceURL</code> but otherwise
+ ignored. If absent, the generated <code>JXMServiceURL</code>
+ will have the local host name.</p>
+
+ <p>The <code><em>port</em></code> in a user-provided
+ <code>serviceURL</code> is also optional. If present, it is
+ also copied into the generated <code>JMXServiceURL</code>;
+ otherwise, the generated <code>JMXServiceURL</code> has no port.
+ For an <code>serviceURL</code> using the <code>rmi</code>
+ protocol, the <code><em>port</em></code>, if present, indicates
+ what port the generated remote object should be exported on. It
+ has no other effect.</p>
+
+ <p>If the user provides an <code>RMIServerImpl</code> rather than a
+ <code>JMXServiceURL</code>, then the generated
+ <code>JMXServiceURL</code> will have the local host name in its
+ <code><em>host</em></code> part and no
+ <code><em>port</em></code>.</p>
+
+
+ <h4><a name="directory">Connector addresses based on directory
+ entries</a></h4>
+
+ <p>As an alternative to the generated addresses just described,
+ the <code>serviceURL</code> address supplied when creating a
+ connector server can specify a <em>directory address</em> in
+ which to store the provided or generated <code>RMIServer</code>
+ stub. This directory address is then used by both client and
+ server.</p>
+
+ <p>In this case, the <code>serviceURL</code> has the following form:</p>
+
+ <pre>
+ <code>service:jmx:rmi://<em>host</em>:<em>port</em>/jndi/<em>jndi-name</em></code>
+ </pre>
+
+ <p>Here, <code><em>jndi-name</em></code> is a string that can be
+ supplied to {@link javax.naming.InitialContext#bind
+ javax.naming.InitialContext.bind}.</p>
+
+ <p>As usual, the <code><em>host</em></code> and
+ <code>:<em>port</em></code> can be omitted.</p>
+
+ <p>The connector server will generate an
+ <code>RMIServerImpl</code> based on the protocol
+ (<code>rmi</code>) and the <code><em>port</em></code> if any. When
+ the connector server is started, it will derive a stub from this
+ object using its {@link
+ javax.management.remote.rmi.RMIServerImpl#toStub toStub} method
+ and store the object using the given
+ <code><em>jndi-name</em></code>. The properties defined by the
+ JNDI API are consulted as usual.</p>
+
+ <p>For example, if the <code>JMXServiceURL</code> is:
+
+ <pre>
+ <code>service:jmx:rmi://ignoredhost/jndi/rmi://myhost/myname</code>
+ </pre>
+
+ then the connector server will generate an
+ <code>RMIJRMPServerImpl</code> and store its stub using the JNDI
+ name
+
+ <pre>
+ <code>rmi://myhost/myname</code>
+ </pre>
+
+ which means entry <code>myname</code> in the RMI registry
+ running on the default port of host <code>myhost</code>. Note
+ that the RMI registry only allows registration from the local
+ host. So, in this case, <code>myhost</code> must be the name
+ (or a name) of the host that the connector server is running
+ on.
+
+ <p>In this <code>JMXServiceURL</code>, the first <code>rmi:</code>
+ specifies the RMI
+ connector, while the second <code>rmi:</code> specifies the RMI
+ registry.
+
+ <p>As another example, if the <code>JMXServiceURL</code> is:
+
+ <pre>
+ <code>service:jmx:rmi://ignoredhost/jndi/ldap://dirhost:9999/cn=this,ou=that</code>
+ </pre>
+
+ then the connector server will generate an
+ <code>RMIJRMPServerImpl</code> and store its stub using the JNDI
+ name
+
+ <pre>
+ <code>ldap://dirhost:9999/cn=this,ou=that</code>
+ </pre>
+
+ which means entry <code>cn=this,ou=that</code> in the LDAP
+ directory running on port 9999 of host <code>dirhost</code>.
+
+ <p>If the <code>JMXServiceURL</code> is:
+
+ <pre>
+ <code>service:jmx:rmi://ignoredhost/jndi/cn=this,ou=that</code>
+ </pre>
+
+ then the connector server will generate an
+ <code>RMIJRMPServerImpl</code> and store its stub using the JNDI
+ name
+
+ <pre>
+ <code>cn=this,ou=that</code>
+ </pre>
+
+ For this case to work, the JNDI API must have been configured
+ appropriately to supply the information about what directory to
+ use.
+
+ <p>In these examples, the host name <code>ignoredhost</code> is
+ not used by the connector server or its clients. It can be
+ omitted, for example:</p>
+
+ <pre>
+ <code>service:jmx:rmi:///jndi/cn=this,ou=that</code>
+ </pre>
+
+ <p>However, it is good practice to use the name of the host
+ where the connector server is running. This is often different
+ from the name of the directory host.</p>
+
+
+ <h4>Connector server attributes</h4>
+
+ <p>When using the default JRMP transport, RMI socket factories can
+ be specified using the attributes
+ <code>jmx.remote.rmi.client.socket.factory</code> and
+ <code>jmx.remote.rmi.server.socket.factory</code> in the
+ <code>environment</code> given to the
+ <code>RMIConnectorServer</code> constructor. The values of these
+ attributes must be of type {@link
+ java.rmi.server.RMIClientSocketFactory} and {@link
+ java.rmi.server.RMIServerSocketFactory}, respectively. These
+ factories are used when creating the RMI objects associated with
+ the connector.</p>
+
+ <h3>Creating an RMI connector client</h3>
+
+ <p>An RMI connector client is usually constructed using {@link
+ javax.management.remote.JMXConnectorFactory}, with a
+ <code>JMXServiceURL</code> that has <code>rmi</code> as its protocol.</p>
+
+ <p>If the <code>JMXServiceURL</code> was generated by the server,
+ as described above under <a href="#servergen">"connector
+ addresses generated by the server"</a>, then the client will
+ need to obtain it directly or indirectly from the server.
+ Typically, the server makes the <code>JMXServiceURL</code>
+ available by storing it in a file or a lookup service.</p>
+
+ <p>If the <code>JMXServiceURL</code> uses the directory syntax, as
+ described above under <a href="#directory">"connector addresses
+ based on directory entries"</a>, then the client may obtain it
+ as just explained, or client and server may both know the
+ appropriate directory entry to use. For example, if the
+ connector server for the Whatsit agent uses the entry
+ <code>whatsit-agent-connector</code> in the RMI registry on host
+ <code>myhost</code>, then client and server can both know
+ that the appropriate <code>JMXServiceURL</code> is:</p>
+
+ <pre>
+ <code>service:jmx:rmi:///jndi/rmi://myhost/whatsit-agent-connector</code>
+ </pre>
+
+ <p>If you have an RMI stub of type {@link
+ javax.management.remote.rmi.RMIServer RMIServer}, you can
+ construct an RMI connection directly by using the appropriate
+ constructor of {@link javax.management.remote.rmi.RMIConnector
+ RMIConnector}.</p>
+
+ <h3>Dynamic code downloading</h3>
+
+ <p>If an RMI connector client or server receives from its peer an
+ instance of a class that it does not know, and if dynamic code
+ downloading is active for the RMI connection, then the class can
+ be downloaded from a codebase specified by the peer. The
+ article <a
+ href="{@docRoot}/../technotes/guides/rmi/codebase.html"><em>Dynamic
+ code downloading using Java RMI</em></a> explains this in more
+ detail.</p>
+
+
+ @see <a href="{@docRoot}/../technotes/guides/rmi/index.html">
+ Java™ Remote Method
+ Invocation (RMI)</a>
+
+ @see <a href="{@docRoot}/../technotes/guides/jndi/index.html">
+ Java Naming and Directory Interface™ (JNDI)</a>
+
+ @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045,
+ section 6.8, "Base64 Content-Transfer-Encoding"</a>
+
+
+ @since 1.5
+
+ </body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.management.rmi/share/classes/module-info.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+/**
+ * Defines the RMI Connector for the Java Management Extensions (JMX) Remote API.
+ * <P>
+ * The {@linkplain javax.management.remote.rmi RMI connector} is a connector
+ * for the JMX Remote API that uses RMI to transmit client requests to a remote
+ * MBean server.
+ *
+ * @provides javax.management.remote.JMXConnectorProvider
+ * A provider of {@code JMXConnector} for the RMI protocol.<br>
+ * Instances of {@code JMXConnector} using the RMI protocol
+ * are usually created by the {@link
+ * javax.management.remote.JMXConnectorFactory} which will locate
+ * and load the appropriate {@code JMXConnectorProvider} service
+ * implementation for the given protocol.
+ *
+ * @provides javax.management.remote.JMXConnectorServerProvider
+ * A provider of {@code JMXConnectorServer} for the RMI protocol.<br>
+ * Instances of {@code JMXConnectorServer} using the RMI protocol
+ * are usually created by the {@link
+ * javax.management.remote.JMXConnectorServerFactory} which will locate
+ * and load the appropriate {@code JMXConnectorServerProvider} service
+ * implementation for the given protocol.
+ *
+ */
+module java.management.rmi {
+
+ requires transitive java.management;
+ requires transitive java.rmi;
+ requires java.naming;
+
+ exports javax.management.remote.rmi;
+
+ // The qualified export below is required to preserve backward
+ // compatibility for the legacy case where an ordered list
+ // of package prefixes can be specified to the factory.
+ exports com.sun.jmx.remote.protocol.rmi to java.management;
+
+ // jdk.management.agent needs to create an RMIExporter instance.
+ exports com.sun.jmx.remote.internal.rmi to jdk.management.agent;
+
+ // The java.management.rmi module provides implementations
+ // of the JMXConnectorProvider and JMXConnectorServerProvider
+ // services supporting the RMI protocol.
+ provides javax.management.remote.JMXConnectorProvider
+ with com.sun.jmx.remote.protocol.rmi.ClientProvider;
+ provides javax.management.remote.JMXConnectorServerProvider
+ with com.sun.jmx.remote.protocol.rmi.ServerProvider;
+
+}
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ClientNotifForwarder.java Thu Feb 02 21:55:34 2017 +0000
@@ -52,7 +52,6 @@
import com.sun.jmx.remote.util.ClassLogger;
import com.sun.jmx.remote.util.EnvHelp;
import java.lang.reflect.UndeclaredThrowableException;
-import java.rmi.UnmarshalException;
import java.util.concurrent.RejectedExecutionException;
@@ -633,7 +632,7 @@
}
return nr;
- } catch (ClassNotFoundException | NotSerializableException | UnmarshalException e) {
+ } catch (ClassNotFoundException | NotSerializableException e) {
logger.trace("NotifFetcher.fetchNotifs", e);
return fetchOneNotif();
} catch (IOException ioe) {
@@ -705,7 +704,7 @@
try {
// 1 notif to skip possible missing class
result = cnf.fetchNotifs(startSequenceNumber, 1, 0L);
- } catch (ClassNotFoundException | NotSerializableException | UnmarshalException e) {
+ } catch (ClassNotFoundException | NotSerializableException e) {
logger.warning("NotifFetcher.fetchOneNotif",
"Failed to deserialize a notification: "+e.toString());
if (logger.traceOn()) {
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/ProxyRef.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.jmx.remote.internal;
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.lang.reflect.Method;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.server.RemoteObject;
-import java.rmi.server.RemoteRef;
-
-
-@SuppressWarnings("deprecation")
-public class ProxyRef implements RemoteRef {
- private static final long serialVersionUID = -6503061366316814723L;
-
- public ProxyRef(RemoteRef ref) {
- this.ref = ref;
- }
-
- public void readExternal(ObjectInput in)
- throws IOException, ClassNotFoundException {
- ref.readExternal(in);
- }
-
- public void writeExternal(ObjectOutput out) throws IOException {
- ref.writeExternal(out);
- }
-
- /**
- * @deprecated
- */
- @Deprecated
- public void invoke(java.rmi.server.RemoteCall call) throws Exception {
- ref.invoke(call);
- }
-
- public Object invoke(Remote obj, Method method, Object[] params,
- long opnum) throws Exception {
- return ref.invoke(obj, method, params, opnum);
- }
-
- /**
- * @deprecated
- */
- @Deprecated
- public void done(java.rmi.server.RemoteCall call) throws RemoteException {
- ref.done(call);
- }
-
- public String getRefClass(ObjectOutput out) {
- return ref.getRefClass(out);
- }
-
- /**
- * @deprecated
- */
- @Deprecated
- public java.rmi.server.RemoteCall newCall(RemoteObject obj,
- java.rmi.server.Operation[] op, int opnum,
- long hash) throws RemoteException {
- return ref.newCall(obj, op, opnum, hash);
- }
-
- public boolean remoteEquals(RemoteRef obj) {
- return ref.remoteEquals(obj);
- }
-
- public int remoteHashCode() {
- return ref.remoteHashCode();
- }
-
- public String remoteToString() {
- return ref.remoteToString();
- }
-
- protected RemoteRef ref;
-}
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/RMIExporter.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2003, 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.jmx.remote.internal;
-
-import java.rmi.NoSuchObjectException;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.server.RMIClientSocketFactory;
-import java.rmi.server.RMIServerSocketFactory;
-import java.rmi.server.UnicastRemoteObject;
-
-/**
- * <p>Unpublished interface controlling how the RMI Connector Server
- * exports objects. The RMIServerImpl object and each
- * RMIConnectionImpl object are exported using the exporter. The
- * default exporter calls {@link
- * UnicastRemoteObject#exportObject(Remote, int,
- * RMIClientSocketFactory, RMIServerSocketFactory)} to export objects
- * and {@link UnicastRemoteObject#unexportObject(Remote, boolean)} to
- * unexport them. A replacement exporter can be specified via the
- * {@link #EXPORTER_ATTRIBUTE} property in the environment Map passed
- * to the RMI connector server.</p>
- */
-public interface RMIExporter {
- public static final String EXPORTER_ATTRIBUTE =
- "com.sun.jmx.remote.rmi.exporter";
-
- public Remote exportObject(Remote obj,
- int port,
- RMIClientSocketFactory csf,
- RMIServerSocketFactory ssf)
- throws RemoteException;
-
- public boolean unexportObject(Remote obj, boolean force)
- throws NoSuchObjectException;
-}
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/Unmarshal.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.jmx.remote.internal;
-
-import java.io.IOException;
-import java.rmi.MarshalledObject;
-
-public interface Unmarshal {
- public Object get(MarshalledObject<?> mo)
- throws IOException, ClassNotFoundException;
-}
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/protocol/rmi/ClientProvider.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2002, 2004, 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.jmx.remote.protocol.rmi;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.util.Map;
-
-import javax.management.remote.JMXConnectorProvider;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.rmi.RMIConnector;
-
-public class ClientProvider implements JMXConnectorProvider {
-
- public JMXConnector newJMXConnector(JMXServiceURL serviceURL,
- Map<String,?> environment)
- throws IOException {
- if (!serviceURL.getProtocol().equals("rmi")) {
- throw new MalformedURLException("Protocol not rmi: " +
- serviceURL.getProtocol());
- }
- return new RMIConnector(serviceURL, environment);
- }
-}
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/protocol/rmi/ServerProvider.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2003, 2004, 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.jmx.remote.protocol.rmi;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.util.Map;
-
-import javax.management.MBeanServer;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerProvider;
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.rmi.RMIConnectorServer;
-
-public class ServerProvider implements JMXConnectorServerProvider {
-
- public JMXConnectorServer newJMXConnectorServer(JMXServiceURL serviceURL,
- Map<String,?> environment,
- MBeanServer mbeanServer)
- throws IOException {
- if (!serviceURL.getProtocol().equals("rmi")) {
- throw new MalformedURLException("Protocol not rmi: " +
- serviceURL.getProtocol());
- }
- return new RMIConnectorServer(serviceURL, environment, mbeanServer);
- }
-
-}
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/security/FileLoginModule.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/security/FileLoginModule.java Thu Feb 02 21:55:34 2017 +0000
@@ -47,7 +47,6 @@
import com.sun.jmx.remote.util.ClassLogger;
import com.sun.jmx.remote.util.EnvHelp;
-import sun.management.jmxremote.ConnectorBootstrap;
/**
* This {@link LoginModule} performs file-based authentication.
@@ -110,12 +109,14 @@
*/
public class FileLoginModule implements LoginModule {
+ private static final String PASSWORD_FILE_NAME = "jmxremote.password";
+
// Location of the default password file
private static final String DEFAULT_PASSWORD_FILE_NAME =
AccessController.doPrivileged(new GetPropertyAction("java.home")) +
File.separatorChar + "conf" +
File.separatorChar + "management" + File.separatorChar +
- ConnectorBootstrap.DefaultValues.PASSWORD_FILE_NAME;
+ PASSWORD_FILE_NAME;
// Key to retrieve the stored username
private static final String USERNAME_KEY =
@@ -200,8 +201,7 @@
passwordFileDisplayName = passwordFile;
} catch (SecurityException e) {
hasJavaHomePermission = false;
- passwordFileDisplayName =
- ConnectorBootstrap.DefaultValues.PASSWORD_FILE_NAME;
+ passwordFileDisplayName = PASSWORD_FILE_NAME;
}
}
}
--- a/jdk/src/java.management/share/classes/javax/management/remote/JMXConnectorFactory.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.management/share/classes/javax/management/remote/JMXConnectorFactory.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,13 +27,17 @@
import com.sun.jmx.mbeanserver.Util;
import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.lang.reflect.Module;
import java.net.MalformedURLException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
-import java.util.Iterator;
import java.util.ServiceLoader;
+import java.util.ServiceLoader.Provider;
import java.util.StringTokenizer;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -332,25 +336,32 @@
IOException exception = null;
if (provider == null) {
+ Predicate<Provider<?>> systemProvider =
+ JMXConnectorFactory::isSystemProvider;
// Loader is null when context class loader is set to null
// and no loader has been provided in map.
// com.sun.jmx.remote.util.Service class extracted from j2se
// provider search algorithm doesn't handle well null classloader.
+ JMXConnector connection = null;
if (loader != null) {
try {
- JMXConnector connection =
- getConnectorAsService(loader, providerURL, envcopy);
- if (connection != null)
- return connection;
+ connection = getConnectorAsService(loader,
+ providerURL,
+ envcopy,
+ systemProvider.negate());
+ if (connection != null) return connection;
} catch (JMXProviderException e) {
throw e;
} catch (IOException e) {
exception = e;
}
}
- provider = getProvider(protocol, PROTOCOL_PROVIDER_DEFAULT_PACKAGE,
- JMXConnectorFactory.class.getClassLoader(),
- providerClassName, targetInterface);
+ connection = getConnectorAsService(
+ JMXConnectorFactory.class.getClassLoader(),
+ providerURL,
+ Collections.unmodifiableMap(envcopy),
+ systemProvider);
+ if (connection != null) return connection;
}
if (provider == null) {
@@ -437,13 +448,6 @@
return instance;
}
- static <T> Iterator<T> getProviderIterator(final Class<T> providerClass,
- final ClassLoader loader) {
- ServiceLoader<T> serviceLoader =
- ServiceLoader.load(providerClass, loader);
- return serviceLoader.iterator();
- }
-
private static ClassLoader wrap(final ClassLoader parent) {
return parent != null ? AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
@Override
@@ -459,44 +463,265 @@
}) : null;
}
+ /**
+ * Checks whether the given provider is our system provider for
+ * the RMI connector.
+ * If providers for additional protocols are added in the future
+ * then the name of their modules may need to be added here.
+ * System providers will be loaded only if no other provider is found.
+ * @param provider the provider to test.
+ * @return true if this provider is a default system provider.
+ */
+ static boolean isSystemProvider(Provider<?> provider) {
+ Module providerModule = provider.type().getModule();
+ return providerModule.isNamed()
+ && providerModule.getName().equals("java.management.rmi");
+ }
+
+ /**
+ * Creates a JMXConnector from the first JMXConnectorProvider service
+ * supporting the given url that can be loaded from the given loader.
+ * <p>
+ * Parses the list of JMXConnectorProvider services that can be loaded
+ * from the given loader, only retaining those that satisfy the given filter.
+ * Then for each provider, attempts to create a new JMXConnector.
+ * The first JMXConnector successfully created is returned.
+ * <p>
+ * The filter predicate is usually used to either exclude system providers
+ * or only retain system providers (see isSystemProvider(...) above).
+ *
+ * @param loader The ClassLoader to use when looking up an implementation
+ * of the service. If null, then only installed services will be
+ * considered.
+ *
+ * @param url The JMXServiceURL of the connector for which a provider is
+ * requested.
+ *
+ * @param filter A filter used to exclude or return provider
+ * implementations. Typically the filter will either exclude
+ * system services (system default implementations) or only
+ * retain those.
+ * This can allow to first look for custom implementations (e.g.
+ * deployed on the CLASSPATH with META-INF/services) and
+ * then only default to system implementations.
+ *
+ * @throws IOException if no connector could not be instantiated, and
+ * at least one provider threw an exception that wasn't a
+ * {@code MalformedURLException} or a {@code JMProviderException}.
+ *
+ * @throws JMXProviderException if a provider for the protocol in
+ * <code>url</code> was found, but couldn't create the connector
+ * some reason.
+ *
+ * @return an instance of JMXConnector if a provider was found from
+ * which one could be instantiated, {@code null} otherwise.
+ */
private static JMXConnector getConnectorAsService(ClassLoader loader,
JMXServiceURL url,
- Map<String, ?> map)
+ Map<String, ?> map,
+ Predicate<Provider<?>> filter)
throws IOException {
- Iterator<JMXConnectorProvider> providers =
- getProviderIterator(JMXConnectorProvider.class, loader);
- JMXConnector connection;
- IOException exception = null;
- while (providers.hasNext()) {
- JMXConnectorProvider provider = providers.next();
- try {
- connection = provider.newJMXConnector(url, map);
- return connection;
- } catch (JMXProviderException e) {
- throw e;
- } catch (Exception e) {
- if (logger.traceOn())
- logger.trace("getConnectorAsService",
- "URL[" + url +
- "] Service provider exception: " + e);
- if (!(e instanceof MalformedURLException)) {
- if (exception == null) {
- if (e instanceof IOException) {
- exception = (IOException) e;
- } else {
- exception = EnvHelp.initCause(
- new IOException(e.getMessage()), e);
+ final ConnectorFactory<JMXConnectorProvider, JMXConnector> factory =
+ (p) -> p.newJMXConnector(url, map);
+ return getConnectorAsService(JMXConnectorProvider.class, loader, url,
+ filter, factory);
+ }
+
+
+ /**
+ * A factory function that can create a connector from a provider.
+ * The pair (P,C) will be either one of:
+ * a. (JMXConnectorProvider, JMXConnector) or
+ * b. (JMXConnectorServerProvider, JMXConnectorServer)
+ */
+ @FunctionalInterface
+ static interface ConnectorFactory<P,C> {
+ public C apply(P provider) throws Exception;
+ }
+
+ /**
+ * An instance of ProviderFinder is used to traverse a
+ * {@code Stream<Provider<P>>} and find the first implementation of P
+ * that supports creating a connector C from the given JMXServiceURL.
+ * <p>
+ * The pair (P,C) will be either one of: <br>
+ * a. (JMXConnectorProvider, JMXConnector) or <br>
+ * b. (JMXConnectorServerProvider, JMXConnectorServer)
+ * <p>
+ * The first connector successfully created while traversing the stream
+ * is stored in the ProviderFinder instance. After that, the
+ * ProviderFinder::test method, if called, will always return false, skipping
+ * the remaining providers.
+ * <p>
+ * An instance of ProviderFinder is always expected to be used in conjunction
+ * with Stream::findFirst, so that the stream traversal is stopped as soon
+ * as a matching provider is found.
+ * <p>
+ * At the end of the stream traversal, the ProviderFinder::get method can be
+ * used to obtain the connector instance (an instance of C) that was created.
+ * If no connector could be created, and an exception was encountered while
+ * traversing the stream and attempting to create the connector, then that
+ * exception will be thrown by ProviderFinder::get, wrapped, if needed,
+ * inside an IOException.
+ * <p>
+ * If any JMXProviderException is encountered while traversing the stream and
+ * attempting to create the connector, that exception will be wrapped in an
+ * UncheckedIOException and thrown immediately within the stream, thus
+ * interrupting the traversal.
+ * <p>
+ * If no matching provider was found (no provider found or attempting
+ * factory.apply always returned null or threw a MalformedURLException,
+ * indicating the provider didn't support the protocol asked for by
+ * the JMXServiceURL), then ProviderFinder::get will simply return null.
+ */
+ private static final class ProviderFinder<P,C> implements Predicate<Provider<P>> {
+
+ final ConnectorFactory<P,C> factory;
+ final JMXServiceURL url;
+ private IOException exception = null;
+ private C connection = null;
+
+ ProviderFinder(ConnectorFactory<P,C> factory, JMXServiceURL url) {
+ this.factory = factory;
+ this.url = url;
+ }
+
+ /**
+ * Returns {@code true} for the first provider {@code sp} that can
+ * be used to obtain an instance of {@code C} from the given
+ * {@code factory}.
+ *
+ * @param sp a candidate provider for instantiating {@code C}.
+ *
+ * @throws UncheckedIOException if {@code sp} throws a
+ * JMXProviderException. The JMXProviderException is set as the
+ * root cause.
+ *
+ * @return {@code true} for the first provider {@code sp} for which
+ * {@code C} could be instantiated, {@code false} otherwise.
+ */
+ public boolean test(Provider<P> sp) {
+ if (connection == null) {
+ P provider = sp.get();
+ try {
+ connection = factory.apply(provider);
+ return connection != null;
+ } catch (JMXProviderException e) {
+ throw new UncheckedIOException(e);
+ } catch (Exception e) {
+ if (logger.traceOn())
+ logger.trace("getConnectorAsService",
+ "URL[" + url +
+ "] Service provider exception: " + e);
+ if (!(e instanceof MalformedURLException)) {
+ if (exception == null) {
+ if (e instanceof IOException) {
+ exception = (IOException) e;
+ } else {
+ exception = EnvHelp.initCause(
+ new IOException(e.getMessage()), e);
+ }
}
}
}
- continue;
+ }
+ return false;
+ }
+
+ /**
+ * Returns an instance of {@code C} if a provider was found from
+ * which {@code C} could be instantiated.
+ *
+ * @throws IOException if {@code C} could not be instantiated, and
+ * at least one provider threw an exception that wasn't a
+ * {@code MalformedURLException} or a {@code JMProviderException}.
+ *
+ * @return an instance of {@code C} if a provider was found from
+ * which {@code C} could be instantiated, {@code null} otherwise.
+ */
+ C get() throws IOException {
+ if (connection != null) return connection;
+ else if (exception != null) throw exception;
+ else return null;
+ }
+ }
+
+ /**
+ * Creates a connector from a provider loaded from the ServiceLoader.
+ * <p>
+ * The pair (P,C) will be either one of: <br>
+ * a. (JMXConnectorProvider, JMXConnector) or <br>
+ * b. (JMXConnectorServerProvider, JMXConnectorServer)
+ *
+ * @param providerClass The service type for which an implementation
+ * should be looked up from the {@code ServiceLoader}. This will
+ * be either {@code JMXConnectorProvider.class} or
+ * {@code JMXConnectorServerProvider.class}
+ *
+ * @param loader The ClassLoader to use when looking up an implementation
+ * of the service. If null, then only installed services will be
+ * considered.
+ *
+ * @param url The JMXServiceURL of the connector for which a provider is
+ * requested.
+ *
+ * @param filter A filter used to exclude or return provider
+ * implementations. Typically the filter will either exclude
+ * system services (system default implementations) or only
+ * retain those.
+ * This can allow to first look for custom implementations (e.g.
+ * deployed on the CLASSPATH with META-INF/services) and
+ * then only default to system implementations.
+ *
+ * @param factory A functional factory that can attempt to create an
+ * instance of connector {@code C} from a provider {@code P}.
+ * Typically, this is a simple wrapper over {@code
+ * JMXConnectorProvider::newJMXConnector} or {@code
+ * JMXConnectorProviderServer::newJMXConnectorServer}.
+ *
+ * @throws IOException if {@code C} could not be instantiated, and
+ * at least one provider {@code P} threw an exception that wasn't a
+ * {@code MalformedURLException} or a {@code JMProviderException}.
+ *
+ * @throws JMXProviderException if a provider {@code P} for the protocol in
+ * <code>url</code> was found, but couldn't create the connector
+ * {@code C} for some reason.
+ *
+ * @return an instance of {@code C} if a provider {@code P} was found from
+ * which one could be instantiated, {@code null} otherwise.
+ */
+ static <P,C> C getConnectorAsService(Class<P> providerClass,
+ ClassLoader loader,
+ JMXServiceURL url,
+ Predicate<Provider<?>> filter,
+ ConnectorFactory<P,C> factory)
+ throws IOException {
+
+ // sanity check
+ if (JMXConnectorProvider.class != providerClass
+ && JMXConnectorServerProvider.class != providerClass) {
+ // should never happen
+ throw new InternalError("Unsupported service interface: "
+ + providerClass.getName());
+ }
+
+ ServiceLoader<P> serviceLoader = loader == null
+ ? ServiceLoader.loadInstalled(providerClass)
+ : ServiceLoader.load(providerClass, loader);
+ Stream<Provider<P>> stream = serviceLoader.stream().filter(filter);
+ ProviderFinder<P,C> finder = new ProviderFinder<>(factory, url);
+
+ try {
+ stream.filter(finder).findFirst();
+ return finder.get();
+ } catch (UncheckedIOException e) {
+ if (e.getCause() instanceof JMXProviderException) {
+ throw (JMXProviderException) e.getCause();
+ } else {
+ throw e;
}
}
- if (exception == null)
- return null;
- else
- throw exception;
}
static <T> T getProvider(String protocol,
--- a/jdk/src/java.management/share/classes/javax/management/remote/JMXConnectorServerFactory.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.management/share/classes/javax/management/remote/JMXConnectorServerFactory.java Thu Feb 02 21:55:34 2017 +0000
@@ -30,13 +30,16 @@
import com.sun.jmx.remote.util.EnvHelp;
import java.io.IOException;
+import java.io.UncheckedIOException;
import java.net.MalformedURLException;
import java.util.Collections;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.Map;
+import java.util.ServiceLoader.Provider;
+import java.util.function.Predicate;
import javax.management.MBeanServer;
+import javax.management.remote.JMXConnectorFactory.ConnectorFactory;
/**
* <p>Factory to create JMX API connector servers. There
@@ -205,43 +208,15 @@
}
private static JMXConnectorServer
- getConnectorServerAsService(ClassLoader loader,
- JMXServiceURL url,
- Map<String, ?> map,
- MBeanServer mbs)
+ getConnectorServerAsService(ClassLoader loader, JMXServiceURL url,
+ Map<String, ?> map, MBeanServer mbs,
+ Predicate<Provider<?>> filter)
throws IOException {
- Iterator<JMXConnectorServerProvider> providers =
- JMXConnectorFactory.
- getProviderIterator(JMXConnectorServerProvider.class, loader);
-
- IOException exception = null;
- while (providers.hasNext()) {
- try {
- return providers.next().newJMXConnectorServer(url, map, mbs);
- } catch (JMXProviderException e) {
- throw e;
- } catch (Exception e) {
- if (logger.traceOn())
- logger.trace("getConnectorAsService",
- "URL[" + url +
- "] Service provider exception: " + e);
- if (!(e instanceof MalformedURLException)) {
- if (exception == null) {
- if (e instanceof IOException) {
- exception = (IOException) e;
- } else {
- exception = EnvHelp.initCause(
- new IOException(e.getMessage()), e);
- }
- }
- }
- continue;
- }
- }
- if (exception == null)
- return null;
- else
- throw exception;
+ final ConnectorFactory<JMXConnectorServerProvider,JMXConnectorServer>
+ factory = (p) -> p.newJMXConnectorServer(url, map, mbs);
+ return JMXConnectorFactory.getConnectorAsService(
+ JMXConnectorServerProvider.class,
+ loader, url, filter, factory);
}
/**
@@ -309,18 +284,22 @@
loader);
IOException exception = null;
+ JMXConnectorServer connection = null;
if (provider == null) {
+ Predicate<Provider<?>> systemProvider =
+ JMXConnectorFactory::isSystemProvider;
// Loader is null when context class loader is set to null
// and no loader has been provided in map.
// com.sun.jmx.remote.util.Service class extracted from j2se
// provider search algorithm doesn't handle well null classloader.
if (loader != null) {
try {
- JMXConnectorServer connection =
+ connection =
getConnectorServerAsService(loader,
serviceURL,
envcopy,
- mbeanServer);
+ mbeanServer,
+ systemProvider.negate());
if (connection != null)
return connection;
} catch (JMXProviderException e) {
@@ -329,13 +308,13 @@
exception = e;
}
}
- provider =
- JMXConnectorFactory.getProvider(
- protocol,
- PROTOCOL_PROVIDER_DEFAULT_PACKAGE,
- JMXConnectorFactory.class.getClassLoader(),
- providerClassName,
- targetInterface);
+ connection = getConnectorServerAsService(
+ JMXConnectorFactory.class.getClassLoader(),
+ serviceURL,
+ Collections.unmodifiableMap(envcopy),
+ mbeanServer,
+ systemProvider);
+ if (connection != null) return connection;
}
if (provider == null) {
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/NoCallStackClassLoader.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,296 +0,0 @@
-/*
- * 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 javax.management.remote.rmi;
-
-import java.security.ProtectionDomain;
-
-/**
- <p>A class loader that only knows how to define a limited number
- of classes, and load a limited number of other classes through
- delegation to another loader. It is used to get around a problem
- with Serialization, in particular as used by RMI. The JMX Remote API
- defines exactly what class loader must be used to deserialize arguments on
- the server, and return values on the client. We communicate this class
- loader to RMI by setting it as the context class loader. RMI uses the
- context class loader to load classes as it deserializes, which is what we
- want. However, before consulting the context class loader, it
- looks up the call stack for a class with a non-null class loader,
- and uses that if it finds one. So, in the standalone version of
- javax.management.remote, if the class you're looking for is known
- to the loader of jmxremote.jar (typically the system class loader)
- then that loader will load it. This contradicts the class-loading
- semantics required.
-
- <p>We get around the problem by ensuring that the search up the
- call stack will find a non-null class loader that doesn't load any
- classes of interest, namely this one. So even though this loader
- is indeed consulted during deserialization, it never finds the
- class being deserialized. RMI then proceeds to use the context
- class loader, as we require.
-
- <p>This loader is constructed with the name and byte-code of one
- or more classes that it defines, and a class-loader to which it
- will delegate certain other classes required by that byte-code.
- We construct the byte-code somewhat painstakingly, by compiling
- the Java code directly, converting into a string, copying that
- string into the class that needs this loader, and using the
- stringToBytes method to convert it into the byte array. We
- compile with -g:none because there's not much point in having
- line-number information and the like in these directly-encoded
- classes.
-
- <p>The referencedClassNames should contain the names of all
- classes that are referenced by the classes defined by this loader.
- It is not necessary to include standard J2SE classes, however.
- Here, a class is referenced if it is the superclass or a
- superinterface of a defined class, or if it is the type of a
- field, parameter, or return value. A class is not referenced if
- it only appears in the throws clause of a method or constructor.
- Of course, referencedClassNames should not contain any classes
- that the user might want to deserialize, because the whole point
- of this loader is that it does not find such classes.
-*/
-
-class NoCallStackClassLoader extends ClassLoader {
- /** Simplified constructor when this loader only defines one class. */
- public NoCallStackClassLoader(String className,
- byte[] byteCode,
- String[] referencedClassNames,
- ClassLoader referencedClassLoader,
- ProtectionDomain protectionDomain) {
- this(new String[] {className}, new byte[][] {byteCode},
- referencedClassNames, referencedClassLoader, protectionDomain);
- }
-
- public NoCallStackClassLoader(String[] classNames,
- byte[][] byteCodes,
- String[] referencedClassNames,
- ClassLoader referencedClassLoader,
- ProtectionDomain protectionDomain) {
- super(null);
-
- /* Validation. */
- if (classNames == null || classNames.length == 0
- || byteCodes == null || classNames.length != byteCodes.length
- || referencedClassNames == null || protectionDomain == null)
- throw new IllegalArgumentException();
- for (int i = 0; i < classNames.length; i++) {
- if (classNames[i] == null || byteCodes[i] == null)
- throw new IllegalArgumentException();
- }
- for (int i = 0; i < referencedClassNames.length; i++) {
- if (referencedClassNames[i] == null)
- throw new IllegalArgumentException();
- }
-
- this.classNames = classNames;
- this.byteCodes = byteCodes;
- this.referencedClassNames = referencedClassNames;
- this.referencedClassLoader = referencedClassLoader;
- this.protectionDomain = protectionDomain;
- }
-
- /* This method is called at most once per name. Define the name
- * if it is one of the classes whose byte code we have, or
- * delegate the load if it is one of the referenced classes.
- */
- @Override
- protected Class<?> findClass(String name) throws ClassNotFoundException {
- // Note: classNames is guaranteed by the constructor to be non-null.
- for (int i = 0; i < classNames.length; i++) {
- if (name.equals(classNames[i])) {
- return defineClass(classNames[i], byteCodes[i], 0,
- byteCodes[i].length, protectionDomain);
- }
- }
-
- /* If the referencedClassLoader is null, it is the bootstrap
- * class loader, and there's no point in delegating to it
- * because it's already our parent class loader.
- */
- if (referencedClassLoader != null) {
- for (int i = 0; i < referencedClassNames.length; i++) {
- if (name.equals(referencedClassNames[i]))
- return referencedClassLoader.loadClass(name);
- }
- }
-
- throw new ClassNotFoundException(name);
- }
-
- private final String[] classNames;
- private final byte[][] byteCodes;
- private final String[] referencedClassNames;
- private final ClassLoader referencedClassLoader;
- private final ProtectionDomain protectionDomain;
-
- /**
- * <p>Construct a <code>byte[]</code> using the characters of the
- * given <code>String</code>. Only the low-order byte of each
- * character is used. This method is useful to reduce the
- * footprint of classes that include big byte arrays (e.g. the
- * byte code of other classes), because a string takes up much
- * less space in a class file than the byte code to initialize a
- * <code>byte[]</code> with the same number of bytes.</p>
- *
- * <p>We use just one byte per character even though characters
- * contain two bytes. The resultant output length is much the
- * same: using one byte per character is shorter because it has
- * more characters in the optimal 1-127 range but longer because
- * it has more zero bytes (which are frequent, and are encoded as
- * two bytes in classfile UTF-8). But one byte per character has
- * two key advantages: (1) you can see the string constants, which
- * is reassuring, (2) you don't need to know whether the class
- * file length is odd.</p>
- *
- * <p>This method differs from {@link String#getBytes()} in that
- * it does not use any encoding. So it is guaranteed that each
- * byte of the result is numerically identical (mod 256) to the
- * corresponding character of the input.
- */
- public static byte[] stringToBytes(String s) {
- final int slen = s.length();
- byte[] bytes = new byte[slen];
- for (int i = 0; i < slen; i++)
- bytes[i] = (byte) s.charAt(i);
- return bytes;
- }
-}
-
-/*
-
-You can use the following Emacs function to convert class files into
-strings to be used by the stringToBytes method above. Select the
-whole (defun...) with the mouse and type M-x eval-region, or save it
-to a file and do M-x load-file. Then visit the *.class file and do
-M-x class-string.
-
-;; class-string.el
-;; visit the *.class file with emacs, then invoke this function
-
-(defun class-string ()
- "Construct a Java string whose bytes are the same as the current
-buffer. The resultant string is put in a buffer called *string*,
-possibly with a numeric suffix like <2>. From there it can be
-insert-buffer'd into a Java program."
- (interactive)
- (let* ((s (buffer-string))
- (slen (length s))
- (i 0)
- (buf (generate-new-buffer "*string*")))
- (set-buffer buf)
- (insert "\"")
- (while (< i slen)
- (if (> (current-column) 61)
- (insert "\"+\n\""))
- (let ((c (aref s i)))
- (insert (cond
- ((> c 126) (format "\\%o" c))
- ((= c ?\") "\\\"")
- ((= c ?\\) "\\\\")
- ((< c 33)
- (let ((nextc (if (< (1+ i) slen)
- (aref s (1+ i))
- ?\0)))
- (cond
- ((and (<= nextc ?7) (>= nextc ?0))
- (format "\\%03o" c))
- (t
- (format "\\%o" c)))))
- (t c))))
- (setq i (1+ i)))
- (insert "\"")
- (switch-to-buffer buf)))
-
-Alternatively, the following class reads a class file and outputs a string
-that can be used by the stringToBytes method above.
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-
-public class BytesToString {
-
- public static void main(String[] args) throws IOException {
- File f = new File(args[0]);
- int len = (int)f.length();
- byte[] classBytes = new byte[len];
-
- FileInputStream in = new FileInputStream(args[0]);
- try {
- int pos = 0;
- for (;;) {
- int n = in.read(classBytes, pos, (len-pos));
- if (n < 0)
- throw new RuntimeException("class file changed??");
- pos += n;
- if (pos >= n)
- break;
- }
- } finally {
- in.close();
- }
-
- int pos = 0;
- boolean lastWasOctal = false;
- for (int i=0; i<len; i++) {
- int value = classBytes[i];
- if (value < 0)
- value += 256;
- String s = null;
- if (value == '\\')
- s = "\\\\";
- else if (value == '\"')
- s = "\\\"";
- else {
- if ((value >= 32 && value < 127) && ((!lastWasOctal ||
- (value < '0' || value > '7')))) {
- s = Character.toString((char)value);
- }
- }
- if (s == null) {
- s = "\\" + Integer.toString(value, 8);
- lastWasOctal = true;
- } else {
- lastWasOctal = false;
- }
- if (pos > 61) {
- System.out.print("\"");
- if (i<len)
- System.out.print("+");
- System.out.println();
- pos = 0;
- }
- if (pos == 0)
- System.out.print(" \"");
- System.out.print(s);
- pos += s.length();
- }
- System.out.println("\"");
- }
-}
-
-*/
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnection.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1092 +0,0 @@
-/*
- * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javax.management.remote.rmi;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.rmi.MarshalledObject;
-import java.rmi.Remote;
-import java.util.Set;
-
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.IntrospectionException;
-import javax.management.InvalidAttributeValueException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServerConnection;
-import javax.management.NotCompliantMBeanException;
-
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.ReflectionException;
-import javax.management.RuntimeMBeanException;
-import javax.management.RuntimeOperationsException;
-import javax.management.remote.NotificationResult;
-import javax.security.auth.Subject;
-
-/**
- * <p>RMI object used to forward an MBeanServer request from a client
- * to its MBeanServer implementation on the server side. There is one
- * Remote object implementing this interface for each remote client
- * connected to an RMI connector.</p>
- *
- * <p>User code does not usually refer to this interface. It is
- * specified as part of the public API so that different
- * implementations of that API will interoperate.</p>
- *
- * <p>To ensure that client parameters will be deserialized at the
- * server side with the correct classloader, client parameters such as
- * parameters used to invoke a method are wrapped in a {@link
- * MarshalledObject}. An implementation of this interface must first
- * get the appropriate class loader for the operation and its target,
- * then deserialize the marshalled parameters with this classloader.
- * Except as noted, a parameter that is a
- * <code>MarshalledObject</code> or <code>MarshalledObject[]</code>
- * must not be null; the behavior is unspecified if it is.</p>
- *
- * <p>Class loading aspects are detailed in the
- * <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
- * JMX Specification, version 1.4</a> PDF document.</p>
- *
- * <p>Most methods in this interface parallel methods in the {@link
- * MBeanServerConnection} interface. Where an aspect of the behavior
- * of a method is not specified here, it is the same as in the
- * corresponding <code>MBeanServerConnection</code> method.
- *
- * @since 1.5
- */
-/*
- * Notice that we omit the type parameter from MarshalledObject everywhere,
- * even though it would add useful information to the documentation. The
- * reason is that it was only added in Mustang (Java SE 6), whereas versions
- * 1.4 and 2.0 of the JMX API must be implementable on Tiger per our
- * commitments for JSR 255. This is also why we suppress rawtypes warnings.
- */
-@SuppressWarnings("rawtypes")
-public interface RMIConnection extends Closeable, Remote {
- /**
- * <p>Returns the connection ID. This string is different for
- * every open connection to a given RMI connector server.</p>
- *
- * @return the connection ID
- *
- * @see RMIConnector#connect RMIConnector.connect
- *
- * @throws IOException if a general communication exception occurred.
- */
- public String getConnectionId() throws IOException;
-
- /**
- * <p>Closes this connection. On return from this method, the RMI
- * object implementing this interface is unexported, so further
- * remote calls to it will fail.</p>
- *
- * @throws IOException if the connection could not be closed,
- * or the Remote object could not be unexported, or there was a
- * communication failure when transmitting the remote close
- * request.
- */
- public void close() throws IOException;
-
- /**
- * Handles the method {@link
- * javax.management.MBeanServerConnection#createMBean(String,
- * ObjectName)}.
- *
- * @param className The class name of the MBean to be instantiated.
- * @param name The object name of the MBean. May be null.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return An <code>ObjectInstance</code>, containing the
- * <code>ObjectName</code> and the Java class name of the newly
- * instantiated MBean. If the contained <code>ObjectName</code>
- * is <code>n</code>, the contained Java class name is
- * <code>{@link #getMBeanInfo getMBeanInfo(n)}.getClassName()</code>.
- *
- * @throws ReflectionException Wraps a
- * <code>java.lang.ClassNotFoundException</code> or a
- * <code>java.lang.Exception</code> that occurred
- * when trying to invoke the MBean's constructor.
- * @throws InstanceAlreadyExistsException The MBean is already
- * under the control of the MBean server.
- * @throws MBeanRegistrationException The
- * <code>preRegister</code> (<code>MBeanRegistration</code>
- * interface) method of the MBean has thrown an exception. The
- * MBean will not be registered.
- * @throws MBeanException The constructor of the MBean has
- * thrown an exception.
- * @throws NotCompliantMBeanException This class is not a JMX
- * compliant MBean.
- * @throws RuntimeOperationsException Wraps a
- * <code>java.lang.IllegalArgumentException</code>: The className
- * passed in parameter is null, the <code>ObjectName</code> passed
- * in parameter contains a pattern or no <code>ObjectName</code>
- * is specified for the MBean.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- */
- public ObjectInstance createMBean(String className,
- ObjectName name,
- Subject delegationSubject)
- throws
- ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- IOException;
-
- /**
- * Handles the method {@link
- * javax.management.MBeanServerConnection#createMBean(String,
- * ObjectName, ObjectName)}.
- *
- * @param className The class name of the MBean to be instantiated.
- * @param name The object name of the MBean. May be null.
- * @param loaderName The object name of the class loader to be used.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return An <code>ObjectInstance</code>, containing the
- * <code>ObjectName</code> and the Java class name of the newly
- * instantiated MBean. If the contained <code>ObjectName</code>
- * is <code>n</code>, the contained Java class name is
- * <code>{@link #getMBeanInfo getMBeanInfo(n)}.getClassName()</code>.
- *
- * @throws ReflectionException Wraps a
- * <code>java.lang.ClassNotFoundException</code> or a
- * <code>java.lang.Exception</code> that occurred when trying to
- * invoke the MBean's constructor.
- * @throws InstanceAlreadyExistsException The MBean is already
- * under the control of the MBean server.
- * @throws MBeanRegistrationException The
- * <code>preRegister</code> (<code>MBeanRegistration</code>
- * interface) method of the MBean has thrown an exception. The
- * MBean will not be registered.
- * @throws MBeanException The constructor of the MBean has
- * thrown an exception.
- * @throws NotCompliantMBeanException This class is not a JMX
- * compliant MBean.
- * @throws InstanceNotFoundException The specified class loader
- * is not registered in the MBean server.
- * @throws RuntimeOperationsException Wraps a
- * <code>java.lang.IllegalArgumentException</code>: The className
- * passed in parameter is null, the <code>ObjectName</code> passed
- * in parameter contains a pattern or no <code>ObjectName</code>
- * is specified for the MBean.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- */
- public ObjectInstance createMBean(String className,
- ObjectName name,
- ObjectName loaderName,
- Subject delegationSubject)
- throws
- ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- InstanceNotFoundException,
- IOException;
-
- /**
- * Handles the method {@link
- * javax.management.MBeanServerConnection#createMBean(String,
- * ObjectName, Object[], String[])}. The <code>Object[]</code>
- * parameter is wrapped in a <code>MarshalledObject</code>.
- *
- * @param className The class name of the MBean to be instantiated.
- * @param name The object name of the MBean. May be null.
- * @param params An array containing the parameters of the
- * constructor to be invoked, encapsulated into a
- * <code>MarshalledObject</code>. The encapsulated array can be
- * null, equivalent to an empty array.
- * @param signature An array containing the signature of the
- * constructor to be invoked. Can be null, equivalent to an empty
- * array.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return An <code>ObjectInstance</code>, containing the
- * <code>ObjectName</code> and the Java class name of the newly
- * instantiated MBean. If the contained <code>ObjectName</code>
- * is <code>n</code>, the contained Java class name is
- * <code>{@link #getMBeanInfo getMBeanInfo(n)}.getClassName()</code>.
- *
- * @throws ReflectionException Wraps a
- * <code>java.lang.ClassNotFoundException</code> or a
- * <code>java.lang.Exception</code> that occurred when trying to
- * invoke the MBean's constructor.
- * @throws InstanceAlreadyExistsException The MBean is already
- * under the control of the MBean server.
- * @throws MBeanRegistrationException The
- * <code>preRegister</code> (<code>MBeanRegistration</code>
- * interface) method of the MBean has thrown an exception. The
- * MBean will not be registered.
- * @throws MBeanException The constructor of the MBean has
- * thrown an exception.
- * @throws NotCompliantMBeanException This class is not a JMX
- * compliant MBean.
- * @throws RuntimeOperationsException Wraps a
- * <code>java.lang.IllegalArgumentException</code>: The className
- * passed in parameter is null, the <code>ObjectName</code> passed
- * in parameter contains a pattern, or no <code>ObjectName</code>
- * is specified for the MBean.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- */
- public ObjectInstance createMBean(String className,
- ObjectName name,
- MarshalledObject params,
- String signature[],
- Subject delegationSubject)
- throws
- ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- IOException;
-
- /**
- * Handles the method {@link
- * javax.management.MBeanServerConnection#createMBean(String,
- * ObjectName, ObjectName, Object[], String[])}. The
- * <code>Object[]</code> parameter is wrapped in a
- * <code>MarshalledObject</code>.
- *
- * @param className The class name of the MBean to be instantiated.
- * @param name The object name of the MBean. May be null.
- * @param loaderName The object name of the class loader to be used.
- * @param params An array containing the parameters of the
- * constructor to be invoked, encapsulated into a
- * <code>MarshalledObject</code>. The encapsulated array can be
- * null, equivalent to an empty array.
- * @param signature An array containing the signature of the
- * constructor to be invoked. Can be null, equivalent to an empty
- * array.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return An <code>ObjectInstance</code>, containing the
- * <code>ObjectName</code> and the Java class name of the newly
- * instantiated MBean. If the contained <code>ObjectName</code>
- * is <code>n</code>, the contained Java class name is
- * <code>{@link #getMBeanInfo getMBeanInfo(n)}.getClassName()</code>.
- *
- * @throws ReflectionException Wraps a
- * <code>java.lang.ClassNotFoundException</code> or a
- * <code>java.lang.Exception</code> that occurred when trying to
- * invoke the MBean's constructor.
- * @throws InstanceAlreadyExistsException The MBean is already
- * under the control of the MBean server.
- * @throws MBeanRegistrationException The
- * <code>preRegister</code> (<code>MBeanRegistration</code>
- * interface) method of the MBean has thrown an exception. The
- * MBean will not be registered.
- * @throws MBeanException The constructor of the MBean has
- * thrown an exception.
- * @throws NotCompliantMBeanException This class is not a JMX
- * compliant MBean.
- * @throws InstanceNotFoundException The specified class loader
- * is not registered in the MBean server.
- * @throws RuntimeOperationsException Wraps a
- * <code>java.lang.IllegalArgumentException</code>: The className
- * passed in parameter is null, the <code>ObjectName</code> passed
- * in parameter contains a pattern, or no <code>ObjectName</code>
- * is specified for the MBean.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- */
- public ObjectInstance createMBean(String className,
- ObjectName name,
- ObjectName loaderName,
- MarshalledObject params,
- String signature[],
- Subject delegationSubject)
- throws
- ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- InstanceNotFoundException,
- IOException;
-
- /**
- * Handles the method
- * {@link javax.management.MBeanServerConnection#unregisterMBean(ObjectName)}.
- *
- * @param name The object name of the MBean to be unregistered.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @throws InstanceNotFoundException The MBean specified is not
- * registered in the MBean server.
- * @throws MBeanRegistrationException The preDeregister
- * ((<code>MBeanRegistration</code> interface) method of the MBean
- * has thrown an exception.
- * @throws RuntimeOperationsException Wraps a
- * <code>java.lang.IllegalArgumentException</code>: The object
- * name in parameter is null or the MBean you are when trying to
- * unregister is the {@link javax.management.MBeanServerDelegate
- * MBeanServerDelegate} MBean.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- */
- public void unregisterMBean(ObjectName name, Subject delegationSubject)
- throws
- InstanceNotFoundException,
- MBeanRegistrationException,
- IOException;
-
- /**
- * Handles the method
- * {@link javax.management.MBeanServerConnection#getObjectInstance(ObjectName)}.
- *
- * @param name The object name of the MBean.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return The <code>ObjectInstance</code> associated with the MBean
- * specified by <var>name</var>. The contained <code>ObjectName</code>
- * is <code>name</code> and the contained class name is
- * <code>{@link #getMBeanInfo getMBeanInfo(name)}.getClassName()</code>.
- *
- * @throws InstanceNotFoundException The MBean specified is not
- * registered in the MBean server.
- * @throws RuntimeOperationsException Wraps a
- * <code>java.lang.IllegalArgumentException</code>: The object
- * name in parameter is null.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- */
- public ObjectInstance getObjectInstance(ObjectName name,
- Subject delegationSubject)
- throws InstanceNotFoundException, IOException;
-
- /**
- * Handles the method {@link
- * javax.management.MBeanServerConnection#queryMBeans(ObjectName,
- * QueryExp)}. The <code>QueryExp</code> is wrapped in a
- * <code>MarshalledObject</code>.
- *
- * @param name The object name pattern identifying the MBeans to
- * be retrieved. If null or no domain and key properties are
- * specified, all the MBeans registered will be retrieved.
- * @param query The query expression to be applied for selecting
- * MBeans, encapsulated into a <code>MarshalledObject</code>. If
- * the <code>MarshalledObject</code> encapsulates a null value no
- * query expression will be applied for selecting MBeans.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return A set containing the <code>ObjectInstance</code>
- * objects for the selected MBeans. If no MBean satisfies the
- * query an empty list is returned.
- *
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- */
- public Set<ObjectInstance>
- queryMBeans(ObjectName name,
- MarshalledObject query,
- Subject delegationSubject)
- throws IOException;
-
- /**
- * Handles the method {@link
- * javax.management.MBeanServerConnection#queryNames(ObjectName,
- * QueryExp)}. The <code>QueryExp</code> is wrapped in a
- * <code>MarshalledObject</code>.
- *
- * @param name The object name pattern identifying the MBean names
- * to be retrieved. If null or no domain and key properties are
- * specified, the name of all registered MBeans will be retrieved.
- * @param query The query expression to be applied for selecting
- * MBeans, encapsulated into a <code>MarshalledObject</code>. If
- * the <code>MarshalledObject</code> encapsulates a null value no
- * query expression will be applied for selecting MBeans.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return A set containing the ObjectNames for the MBeans
- * selected. If no MBean satisfies the query, an empty list is
- * returned.
- *
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- */
- public Set<ObjectName>
- queryNames(ObjectName name,
- MarshalledObject query,
- Subject delegationSubject)
- throws IOException;
-
- /**
- * Handles the method
- * {@link javax.management.MBeanServerConnection#isRegistered(ObjectName)}.
- *
- * @param name The object name of the MBean to be checked.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return True if the MBean is already registered in the MBean
- * server, false otherwise.
- *
- * @throws RuntimeOperationsException Wraps a
- * <code>java.lang.IllegalArgumentException</code>: The object
- * name in parameter is null.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- */
- public boolean isRegistered(ObjectName name, Subject delegationSubject)
- throws IOException;
-
- /**
- * Handles the method
- * {@link javax.management.MBeanServerConnection#getMBeanCount()}.
- *
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return the number of MBeans registered.
- *
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- */
- public Integer getMBeanCount(Subject delegationSubject)
- throws IOException;
-
- /**
- * Handles the method {@link
- * javax.management.MBeanServerConnection#getAttribute(ObjectName,
- * String)}.
- *
- * @param name The object name of the MBean from which the
- * attribute is to be retrieved.
- * @param attribute A String specifying the name of the attribute
- * to be retrieved.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return The value of the retrieved attribute.
- *
- * @throws AttributeNotFoundException The attribute specified
- * is not accessible in the MBean.
- * @throws MBeanException Wraps an exception thrown by the
- * MBean's getter.
- * @throws InstanceNotFoundException The MBean specified is not
- * registered in the MBean server.
- * @throws ReflectionException Wraps a
- * <code>java.lang.Exception</code> thrown when trying to invoke
- * the getter.
- * @throws RuntimeOperationsException Wraps a
- * <code>java.lang.IllegalArgumentException</code>: The object
- * name in parameter is null or the attribute in parameter is
- * null.
- * @throws RuntimeMBeanException Wraps a runtime exception thrown
- * by the MBean's getter.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- *
- * @see #setAttribute
- */
- public Object getAttribute(ObjectName name,
- String attribute,
- Subject delegationSubject)
- throws
- MBeanException,
- AttributeNotFoundException,
- InstanceNotFoundException,
- ReflectionException,
- IOException;
-
- /**
- * Handles the method {@link
- * javax.management.MBeanServerConnection#getAttributes(ObjectName,
- * String[])}.
- *
- * @param name The object name of the MBean from which the
- * attributes are retrieved.
- * @param attributes A list of the attributes to be retrieved.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return The list of the retrieved attributes.
- *
- * @throws InstanceNotFoundException The MBean specified is not
- * registered in the MBean server.
- * @throws ReflectionException An exception occurred when
- * trying to invoke the getAttributes method of a Dynamic MBean.
- * @throws RuntimeOperationsException Wrap a
- * <code>java.lang.IllegalArgumentException</code>: The object
- * name in parameter is null or attributes in parameter is null.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- *
- * @see #setAttributes
- */
- public AttributeList getAttributes(ObjectName name,
- String[] attributes,
- Subject delegationSubject)
- throws
- InstanceNotFoundException,
- ReflectionException,
- IOException;
-
- /**
- * Handles the method {@link
- * javax.management.MBeanServerConnection#setAttribute(ObjectName,
- * Attribute)}. The <code>Attribute</code> parameter is wrapped
- * in a <code>MarshalledObject</code>.
- *
- * @param name The name of the MBean within which the attribute is
- * to be set.
- * @param attribute The identification of the attribute to be set
- * and the value it is to be set to, encapsulated into a
- * <code>MarshalledObject</code>.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @throws InstanceNotFoundException The MBean specified is not
- * registered in the MBean server.
- * @throws AttributeNotFoundException The attribute specified
- * is not accessible in the MBean.
- * @throws InvalidAttributeValueException The value specified
- * for the attribute is not valid.
- * @throws MBeanException Wraps an exception thrown by the
- * MBean's setter.
- * @throws ReflectionException Wraps a
- * <code>java.lang.Exception</code> thrown when trying to invoke
- * the setter.
- * @throws RuntimeOperationsException Wraps a
- * <code>java.lang.IllegalArgumentException</code>: The object
- * name in parameter is null or the attribute in parameter is
- * null.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- *
- * @see #getAttribute
- */
- public void setAttribute(ObjectName name,
- MarshalledObject attribute,
- Subject delegationSubject)
- throws
- InstanceNotFoundException,
- AttributeNotFoundException,
- InvalidAttributeValueException,
- MBeanException,
- ReflectionException,
- IOException;
-
- /**
- * Handles the method {@link
- * javax.management.MBeanServerConnection#setAttributes(ObjectName,
- * AttributeList)}. The <code>AttributeList</code> parameter is
- * wrapped in a <code>MarshalledObject</code>.
- *
- * @param name The object name of the MBean within which the
- * attributes are to be set.
- * @param attributes A list of attributes: The identification of
- * the attributes to be set and the values they are to be set to,
- * encapsulated into a <code>MarshalledObject</code>.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return The list of attributes that were set, with their new
- * values.
- *
- * @throws InstanceNotFoundException The MBean specified is not
- * registered in the MBean server.
- * @throws ReflectionException An exception occurred when
- * trying to invoke the getAttributes method of a Dynamic MBean.
- * @throws RuntimeOperationsException Wraps a
- * <code>java.lang.IllegalArgumentException</code>: The object
- * name in parameter is null or attributes in parameter is null.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- *
- * @see #getAttributes
- */
- public AttributeList setAttributes(ObjectName name,
- MarshalledObject attributes,
- Subject delegationSubject)
- throws
- InstanceNotFoundException,
- ReflectionException,
- IOException;
-
- /**
- * Handles the method {@link
- * javax.management.MBeanServerConnection#invoke(ObjectName,
- * String, Object[], String[])}. The <code>Object[]</code>
- * parameter is wrapped in a <code>MarshalledObject</code>.
- *
- * @param name The object name of the MBean on which the method is
- * to be invoked.
- * @param operationName The name of the operation to be invoked.
- * @param params An array containing the parameters to be set when
- * the operation is invoked, encapsulated into a
- * <code>MarshalledObject</code>. The encapsulated array can be
- * null, equivalent to an empty array.
- * @param signature An array containing the signature of the
- * operation. The class objects will be loaded using the same
- * class loader as the one used for loading the MBean on which the
- * operation was invoked. Can be null, equivalent to an empty
- * array.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return The object returned by the operation, which represents
- * the result of invoking the operation on the MBean specified.
- *
- * @throws InstanceNotFoundException The MBean specified is not
- * registered in the MBean server.
- * @throws MBeanException Wraps an exception thrown by the
- * MBean's invoked method.
- * @throws ReflectionException Wraps a
- * <code>java.lang.Exception</code> thrown while trying to invoke
- * the method.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- * @throws RuntimeOperationsException Wraps an {@link
- * IllegalArgumentException} when <code>name</code> or
- * <code>operationName</code> is null.
- */
- public Object invoke(ObjectName name,
- String operationName,
- MarshalledObject params,
- String signature[],
- Subject delegationSubject)
- throws
- InstanceNotFoundException,
- MBeanException,
- ReflectionException,
- IOException;
-
- /**
- * Handles the method
- * {@link javax.management.MBeanServerConnection#getDefaultDomain()}.
- *
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return the default domain.
- *
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- */
- public String getDefaultDomain(Subject delegationSubject)
- throws IOException;
-
- /**
- * Handles the method
- * {@link javax.management.MBeanServerConnection#getDomains()}.
- *
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return the list of domains.
- *
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- */
- public String[] getDomains(Subject delegationSubject)
- throws IOException;
-
- /**
- * Handles the method
- * {@link javax.management.MBeanServerConnection#getMBeanInfo(ObjectName)}.
- *
- * @param name The name of the MBean to analyze
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return An instance of <code>MBeanInfo</code> allowing the
- * retrieval of all attributes and operations of this MBean.
- *
- * @throws IntrospectionException An exception occurred during
- * introspection.
- * @throws InstanceNotFoundException The MBean specified was
- * not found.
- * @throws ReflectionException An exception occurred when
- * trying to invoke the getMBeanInfo of a Dynamic MBean.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- * @throws RuntimeOperationsException Wraps a
- * <code>java.lang.IllegalArgumentException</code>: The object
- * name in parameter is null.
- */
- public MBeanInfo getMBeanInfo(ObjectName name, Subject delegationSubject)
- throws
- InstanceNotFoundException,
- IntrospectionException,
- ReflectionException,
- IOException;
-
- /**
- * Handles the method {@link
- * javax.management.MBeanServerConnection#isInstanceOf(ObjectName,
- * String)}.
- *
- * @param name The <code>ObjectName</code> of the MBean.
- * @param className The name of the class.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @return true if the MBean specified is an instance of the
- * specified class according to the rules above, false otherwise.
- *
- * @throws InstanceNotFoundException The MBean specified is not
- * registered in the MBean server.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- * @throws RuntimeOperationsException Wraps a
- * <code>java.lang.IllegalArgumentException</code>: The object
- * name in parameter is null.
- */
- public boolean isInstanceOf(ObjectName name,
- String className,
- Subject delegationSubject)
- throws InstanceNotFoundException, IOException;
-
- /**
- * Handles the method {@link
- * javax.management.MBeanServerConnection#addNotificationListener(ObjectName,
- * ObjectName, NotificationFilter, Object)}. The
- * <code>NotificationFilter</code> parameter is wrapped in a
- * <code>MarshalledObject</code>. The <code>Object</code>
- * (handback) parameter is also wrapped in a
- * <code>MarshalledObject</code>.
- *
- * @param name The name of the MBean on which the listener should
- * be added.
- * @param listener The object name of the listener which will
- * handle the notifications emitted by the registered MBean.
- * @param filter The filter object, encapsulated into a
- * <code>MarshalledObject</code>. If filter encapsulated in the
- * <code>MarshalledObject</code> has a null value, no filtering
- * will be performed before handling notifications.
- * @param handback The context to be sent to the listener when a
- * notification is emitted, encapsulated into a
- * <code>MarshalledObject</code>.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @throws InstanceNotFoundException The MBean name of the
- * notification listener or of the notification broadcaster does
- * not match any of the registered MBeans.
- * @throws RuntimeOperationsException Wraps an {@link
- * IllegalArgumentException}. The MBean named by
- * <code>listener</code> exists but does not implement the
- * {@link javax.management.NotificationListener} interface,
- * or <code>name</code> or <code>listener</code> is null.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- *
- * @see #removeNotificationListener(ObjectName, ObjectName, Subject)
- * @see #removeNotificationListener(ObjectName, ObjectName,
- * MarshalledObject, MarshalledObject, Subject)
- */
- public void addNotificationListener(ObjectName name,
- ObjectName listener,
- MarshalledObject filter,
- MarshalledObject handback,
- Subject delegationSubject)
- throws InstanceNotFoundException, IOException;
-
- /**
- * Handles the method {@link
- * javax.management.MBeanServerConnection#removeNotificationListener(ObjectName,
- * ObjectName)}.
- *
- * @param name The name of the MBean on which the listener should
- * be removed.
- * @param listener The object name of the listener to be removed.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @throws InstanceNotFoundException The MBean name provided
- * does not match any of the registered MBeans.
- * @throws ListenerNotFoundException The listener is not
- * registered in the MBean.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- * @throws RuntimeOperationsException Wraps an {@link
- * IllegalArgumentException} when <code>name</code> or
- * <code>listener</code> is null.
- *
- * @see #addNotificationListener
- */
- public void removeNotificationListener(ObjectName name,
- ObjectName listener,
- Subject delegationSubject)
- throws
- InstanceNotFoundException,
- ListenerNotFoundException,
- IOException;
-
- /**
- * Handles the method {@link
- * javax.management.MBeanServerConnection#removeNotificationListener(ObjectName,
- * ObjectName, NotificationFilter, Object)}. The
- * <code>NotificationFilter</code> parameter is wrapped in a
- * <code>MarshalledObject</code>. The <code>Object</code>
- * parameter is also wrapped in a <code>MarshalledObject</code>.
- *
- * @param name The name of the MBean on which the listener should
- * be removed.
- * @param listener A listener that was previously added to this
- * MBean.
- * @param filter The filter that was specified when the listener
- * was added, encapsulated into a <code>MarshalledObject</code>.
- * @param handback The handback that was specified when the
- * listener was added, encapsulated into a <code>MarshalledObject</code>.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @throws InstanceNotFoundException The MBean name provided
- * does not match any of the registered MBeans.
- * @throws ListenerNotFoundException The listener is not
- * registered in the MBean, or it is not registered with the given
- * filter and handback.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to perform this operation.
- * @throws IOException if a general communication exception occurred.
- * @throws RuntimeOperationsException Wraps an {@link
- * IllegalArgumentException} when <code>name</code> or
- * <code>listener</code> is null.
- *
- * @see #addNotificationListener
- */
- public void removeNotificationListener(ObjectName name,
- ObjectName listener,
- MarshalledObject filter,
- MarshalledObject handback,
- Subject delegationSubject)
- throws
- InstanceNotFoundException,
- ListenerNotFoundException,
- IOException;
-
- // Special Handling of Notifications -------------------------------------
-
- /**
- * <p>Handles the method {@link
- * javax.management.MBeanServerConnection#addNotificationListener(ObjectName,
- * NotificationListener, NotificationFilter, Object)}.</p>
- *
- * <p>Register for notifications from the given MBeans that match
- * the given filters. The remote client can subsequently retrieve
- * the notifications using the {@link #fetchNotifications
- * fetchNotifications} method.</p>
- *
- * <p>For each listener, the original
- * <code>NotificationListener</code> and <code>handback</code> are
- * kept on the client side; in order for the client to be able to
- * identify them, the server generates and returns a unique
- * <code>listenerID</code>. This <code>listenerID</code> is
- * forwarded with the <code>Notifications</code> to the remote
- * client.</p>
- *
- * <p>If any one of the given (name, filter) pairs cannot be
- * registered, then the operation fails with an exception, and no
- * names or filters are registered.</p>
- *
- * @param names the <code>ObjectNames</code> identifying the
- * MBeans emitting the Notifications.
- * @param filters an array of marshalled representations of the
- * <code>NotificationFilters</code>. Elements of this array can
- * be null.
- * @param delegationSubjects the <code>Subjects</code> on behalf
- * of which the listeners are being added. Elements of this array
- * can be null. Also, the <code>delegationSubjects</code>
- * parameter itself can be null, which is equivalent to an array
- * of null values with the same size as the <code>names</code> and
- * <code>filters</code> arrays.
- *
- * @return an array of <code>listenerIDs</code> identifying the
- * local listeners. This array has the same number of elements as
- * the parameters.
- *
- * @throws IllegalArgumentException if <code>names</code> or
- * <code>filters</code> is null, or if <code>names</code> contains
- * a null element, or if the three arrays do not all have the same
- * size.
- * @throws ClassCastException if one of the elements of
- * <code>filters</code> unmarshalls as a non-null object that is
- * not a <code>NotificationFilter</code>.
- * @throws InstanceNotFoundException if one of the
- * <code>names</code> does not correspond to any registered MBean.
- * @throws SecurityException if, for one of the MBeans, the
- * client, or the delegated Subject if any, does not have
- * permission to add a listener.
- * @throws IOException if a general communication exception occurred.
- */
- public Integer[] addNotificationListeners(ObjectName[] names,
- MarshalledObject[] filters,
- Subject[] delegationSubjects)
- throws InstanceNotFoundException, IOException;
-
- /**
- * <p>Handles the
- * {@link javax.management.MBeanServerConnection#removeNotificationListener(ObjectName,NotificationListener)
- * removeNotificationListener(ObjectName, NotificationListener)} and
- * {@link javax.management.MBeanServerConnection#removeNotificationListener(ObjectName,NotificationListener,NotificationFilter,Object)
- * removeNotificationListener(ObjectName, NotificationListener, NotificationFilter, Object)} methods.</p>
- *
- * <p>This method removes one or more
- * <code>NotificationListener</code>s from a given MBean in the
- * MBean server.</p>
- *
- * <p>The <code>NotificationListeners</code> are identified by the
- * IDs which were returned by the {@link
- * #addNotificationListeners(ObjectName[], MarshalledObject[],
- * Subject[])} method.</p>
- *
- * @param name the <code>ObjectName</code> identifying the MBean
- * emitting the Notifications.
- * @param listenerIDs the list of the IDs corresponding to the
- * listeners to remove.
- * @param delegationSubject The <code>Subject</code> containing the
- * delegation principals or <code>null</code> if the authentication
- * principal is used instead.
- *
- * @throws InstanceNotFoundException if the given
- * <code>name</code> does not correspond to any registered MBean.
- * @throws ListenerNotFoundException if one of the listeners was
- * not found on the server side. This exception can happen if the
- * MBean discarded a listener for some reason other than a call to
- * <code>MBeanServer.removeNotificationListener</code>.
- * @throws SecurityException if the client, or the delegated Subject
- * if any, does not have permission to remove the listeners.
- * @throws IOException if a general communication exception occurred.
- * @throws IllegalArgumentException if <code>ObjectName</code> or
- * <code>listenerIds</code> is null or if <code>listenerIds</code>
- * contains a null element.
- */
- public void removeNotificationListeners(ObjectName name,
- Integer[] listenerIDs,
- Subject delegationSubject)
- throws
- InstanceNotFoundException,
- ListenerNotFoundException,
- IOException;
-
- /**
- * <p>Retrieves notifications from the connector server. This
- * method can block until there is at least one notification or
- * until the specified timeout is reached. The method can also
- * return at any time with zero notifications.</p>
- *
- * <p>A notification can be included in the result if its sequence
- * number is no less than <code>clientSequenceNumber</code> and
- * this client has registered at least one listener for the MBean
- * generating the notification, with a filter that accepts the
- * notification. Each listener that is interested in the
- * notification is identified by an Integer ID that was returned
- * by {@link #addNotificationListeners(ObjectName[],
- * MarshalledObject[], Subject[])}.</p>
- *
- * @param clientSequenceNumber the first sequence number that the
- * client is interested in. If negative, it is interpreted as
- * meaning the sequence number that the next notification will
- * have.
- *
- * @param maxNotifications the maximum number of different
- * notifications to return. The <code>TargetedNotification</code>
- * array in the returned <code>NotificationResult</code> can have
- * more elements than this if the same notification appears more
- * than once. The behavior is unspecified if this parameter is
- * negative.
- *
- * @param timeout the maximum time in milliseconds to wait for a
- * notification to arrive. This can be 0 to indicate that the
- * method should not wait if there are no notifications, but
- * should return at once. It can be <code>Long.MAX_VALUE</code>
- * to indicate that there is no timeout. The behavior is
- * unspecified if this parameter is negative.
- *
- * @return A <code>NotificationResult</code>.
- *
- * @throws IOException if a general communication exception occurred.
- */
- public NotificationResult fetchNotifications(long clientSequenceNumber,
- int maxNotifications,
- long timeout)
- throws IOException;
-}
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1834 +0,0 @@
-/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javax.management.remote.rmi;
-
-import java.io.IOException;
-import java.rmi.MarshalledObject;
-import java.rmi.UnmarshalException;
-import java.rmi.server.Unreferenced;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.Permission;
-import java.security.Permissions;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.security.ProtectionDomain;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Map;
-import java.util.Set;
-
-import javax.management.*;
-import javax.management.remote.JMXServerErrorException;
-import javax.management.remote.NotificationResult;
-import javax.security.auth.Subject;
-import sun.reflect.misc.ReflectUtil;
-
-import static com.sun.jmx.mbeanserver.Util.cast;
-import com.sun.jmx.remote.internal.ServerCommunicatorAdmin;
-import com.sun.jmx.remote.internal.ServerNotifForwarder;
-import com.sun.jmx.remote.security.JMXSubjectDomainCombiner;
-import com.sun.jmx.remote.security.SubjectDelegator;
-import com.sun.jmx.remote.util.ClassLoaderWithRepository;
-import com.sun.jmx.remote.util.ClassLogger;
-import com.sun.jmx.remote.util.EnvHelp;
-import com.sun.jmx.remote.util.OrderClassLoaders;
-import javax.management.loading.ClassLoaderRepository;
-
-/**
- * <p>Implementation of the {@link RMIConnection} interface. User
- * code will not usually reference this class.</p>
- *
- * @since 1.5
- */
-/*
- * Notice that we omit the type parameter from MarshalledObject everywhere,
- * even though it would add useful information to the documentation. The
- * reason is that it was only added in Mustang (Java SE 6), whereas versions
- * 1.4 and 2.0 of the JMX API must be implementable on Tiger per our
- * commitments for JSR 255.
- */
-public class RMIConnectionImpl implements RMIConnection, Unreferenced {
-
- /**
- * Constructs a new {@link RMIConnection}. This connection can be
- * used with the JRMP transport. This object does
- * not export itself: it is the responsibility of the caller to
- * export it appropriately (see {@link
- * RMIJRMPServerImpl#makeClient(String,Subject)}).
- *
- * @param rmiServer The RMIServerImpl object for which this
- * connection is created. The behavior is unspecified if this
- * parameter is null.
- * @param connectionId The ID for this connection. The behavior
- * is unspecified if this parameter is null.
- * @param defaultClassLoader The default ClassLoader to be used
- * when deserializing marshalled objects. Can be null, to signify
- * the bootstrap class loader.
- * @param subject the authenticated subject to be used for
- * authorization. Can be null, to signify that no subject has
- * been authenticated.
- * @param env the environment containing attributes for the new
- * <code>RMIServerImpl</code>. Can be null, equivalent to an
- * empty map.
- */
- public RMIConnectionImpl(RMIServerImpl rmiServer,
- String connectionId,
- ClassLoader defaultClassLoader,
- Subject subject,
- Map<String,?> env) {
- if (rmiServer == null || connectionId == null)
- throw new NullPointerException("Illegal null argument");
- if (env == null)
- env = Collections.emptyMap();
- this.rmiServer = rmiServer;
- this.connectionId = connectionId;
- this.defaultClassLoader = defaultClassLoader;
-
- this.subjectDelegator = new SubjectDelegator();
- this.subject = subject;
- if (subject == null) {
- this.acc = null;
- this.removeCallerContext = false;
- } else {
- this.removeCallerContext =
- SubjectDelegator.checkRemoveCallerContext(subject);
- if (this.removeCallerContext) {
- this.acc =
- JMXSubjectDomainCombiner.getDomainCombinerContext(subject);
- } else {
- this.acc =
- JMXSubjectDomainCombiner.getContext(subject);
- }
- }
- this.mbeanServer = rmiServer.getMBeanServer();
-
- final ClassLoader dcl = defaultClassLoader;
-
- ClassLoaderRepository repository = AccessController.doPrivileged(
- new PrivilegedAction<ClassLoaderRepository>() {
- public ClassLoaderRepository run() {
- return mbeanServer.getClassLoaderRepository();
- }
- },
- withPermissions(new MBeanPermission("*", "getClassLoaderRepository"))
- );
- this.classLoaderWithRepository = AccessController.doPrivileged(
- new PrivilegedAction<ClassLoaderWithRepository>() {
- public ClassLoaderWithRepository run() {
- return new ClassLoaderWithRepository(
- repository,
- dcl);
- }
- },
- withPermissions(new RuntimePermission("createClassLoader"))
- );
-
- this.defaultContextClassLoader =
- AccessController.doPrivileged(
- new PrivilegedAction<ClassLoader>() {
- @Override
- public ClassLoader run() {
- return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(),
- dcl);
- }
- });
-
- serverCommunicatorAdmin = new
- RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env));
-
- this.env = env;
- }
-
- private static AccessControlContext withPermissions(Permission ... perms){
- Permissions col = new Permissions();
-
- for (Permission thePerm : perms ) {
- col.add(thePerm);
- }
-
- final ProtectionDomain pd = new ProtectionDomain(null, col);
- return new AccessControlContext( new ProtectionDomain[] { pd });
- }
-
- private synchronized ServerNotifForwarder getServerNotifFwd() {
- // Lazily created when first use. Mainly when
- // addNotificationListener is first called.
- if (serverNotifForwarder == null)
- serverNotifForwarder =
- new ServerNotifForwarder(mbeanServer,
- env,
- rmiServer.getNotifBuffer(),
- connectionId);
- return serverNotifForwarder;
- }
-
- public String getConnectionId() throws IOException {
- // We should call reqIncomming() here... shouldn't we?
- return connectionId;
- }
-
- public void close() throws IOException {
- final boolean debug = logger.debugOn();
- final String idstr = (debug?"["+this.toString()+"]":null);
-
- synchronized (this) {
- if (terminated) {
- if (debug) logger.debug("close",idstr + " already terminated.");
- return;
- }
-
- if (debug) logger.debug("close",idstr + " closing.");
-
- terminated = true;
-
- if (serverCommunicatorAdmin != null) {
- serverCommunicatorAdmin.terminate();
- }
-
- if (serverNotifForwarder != null) {
- serverNotifForwarder.terminate();
- }
- }
-
- rmiServer.clientClosed(this);
-
- if (debug) logger.debug("close",idstr + " closed.");
- }
-
- public void unreferenced() {
- logger.debug("unreferenced", "called");
- try {
- close();
- logger.debug("unreferenced", "done");
- } catch (IOException e) {
- logger.fine("unreferenced", e);
- }
- }
-
- //-------------------------------------------------------------------------
- // MBeanServerConnection Wrapper
- //-------------------------------------------------------------------------
-
- public ObjectInstance createMBean(String className,
- ObjectName name,
- Subject delegationSubject)
- throws
- ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- IOException {
- try {
- final Object params[] =
- new Object[] { className, name };
-
- if (logger.debugOn())
- logger.debug("createMBean(String,ObjectName)",
- "connectionId=" + connectionId +", className=" +
- className+", name=" + name);
-
- return (ObjectInstance)
- doPrivilegedOperation(
- CREATE_MBEAN,
- params,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof ReflectionException)
- throw (ReflectionException) e;
- if (e instanceof InstanceAlreadyExistsException)
- throw (InstanceAlreadyExistsException) e;
- if (e instanceof MBeanRegistrationException)
- throw (MBeanRegistrationException) e;
- if (e instanceof MBeanException)
- throw (MBeanException) e;
- if (e instanceof NotCompliantMBeanException)
- throw (NotCompliantMBeanException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- public ObjectInstance createMBean(String className,
- ObjectName name,
- ObjectName loaderName,
- Subject delegationSubject)
- throws
- ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- InstanceNotFoundException,
- IOException {
- try {
- final Object params[] =
- new Object[] { className, name, loaderName };
-
- if (logger.debugOn())
- logger.debug("createMBean(String,ObjectName,ObjectName)",
- "connectionId=" + connectionId
- +", className=" + className
- +", name=" + name
- +", loaderName=" + loaderName);
-
- return (ObjectInstance)
- doPrivilegedOperation(
- CREATE_MBEAN_LOADER,
- params,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof ReflectionException)
- throw (ReflectionException) e;
- if (e instanceof InstanceAlreadyExistsException)
- throw (InstanceAlreadyExistsException) e;
- if (e instanceof MBeanRegistrationException)
- throw (MBeanRegistrationException) e;
- if (e instanceof MBeanException)
- throw (MBeanException) e;
- if (e instanceof NotCompliantMBeanException)
- throw (NotCompliantMBeanException) e;
- if (e instanceof InstanceNotFoundException)
- throw (InstanceNotFoundException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- @SuppressWarnings("rawtypes") // MarshalledObject
- public ObjectInstance createMBean(String className,
- ObjectName name,
- MarshalledObject params,
- String signature[],
- Subject delegationSubject)
- throws
- ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- IOException {
-
- final Object[] values;
- final boolean debug = logger.debugOn();
-
- if (debug) logger.debug(
- "createMBean(String,ObjectName,Object[],String[])",
- "connectionId=" + connectionId
- +", unwrapping parameters using classLoaderWithRepository.");
-
- values =
- nullIsEmpty(unwrap(params, classLoaderWithRepository, Object[].class,delegationSubject));
-
- try {
- final Object params2[] =
- new Object[] { className, name, values,
- nullIsEmpty(signature) };
-
- if (debug)
- logger.debug("createMBean(String,ObjectName,Object[],String[])",
- "connectionId=" + connectionId
- +", className=" + className
- +", name=" + name
- +", signature=" + strings(signature));
-
- return (ObjectInstance)
- doPrivilegedOperation(
- CREATE_MBEAN_PARAMS,
- params2,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof ReflectionException)
- throw (ReflectionException) e;
- if (e instanceof InstanceAlreadyExistsException)
- throw (InstanceAlreadyExistsException) e;
- if (e instanceof MBeanRegistrationException)
- throw (MBeanRegistrationException) e;
- if (e instanceof MBeanException)
- throw (MBeanException) e;
- if (e instanceof NotCompliantMBeanException)
- throw (NotCompliantMBeanException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- @SuppressWarnings("rawtypes") // MarshalledObject
- public ObjectInstance createMBean(String className,
- ObjectName name,
- ObjectName loaderName,
- MarshalledObject params,
- String signature[],
- Subject delegationSubject)
- throws
- ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- InstanceNotFoundException,
- IOException {
-
- final Object[] values;
- final boolean debug = logger.debugOn();
-
- if (debug) logger.debug(
- "createMBean(String,ObjectName,ObjectName,Object[],String[])",
- "connectionId=" + connectionId
- +", unwrapping params with MBean extended ClassLoader.");
-
- values = nullIsEmpty(unwrap(params,
- getClassLoader(loaderName),
- defaultClassLoader,
- Object[].class,delegationSubject));
-
- try {
- final Object params2[] =
- new Object[] { className, name, loaderName, values,
- nullIsEmpty(signature) };
-
- if (debug) logger.debug(
- "createMBean(String,ObjectName,ObjectName,Object[],String[])",
- "connectionId=" + connectionId
- +", className=" + className
- +", name=" + name
- +", loaderName=" + loaderName
- +", signature=" + strings(signature));
-
- return (ObjectInstance)
- doPrivilegedOperation(
- CREATE_MBEAN_LOADER_PARAMS,
- params2,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof ReflectionException)
- throw (ReflectionException) e;
- if (e instanceof InstanceAlreadyExistsException)
- throw (InstanceAlreadyExistsException) e;
- if (e instanceof MBeanRegistrationException)
- throw (MBeanRegistrationException) e;
- if (e instanceof MBeanException)
- throw (MBeanException) e;
- if (e instanceof NotCompliantMBeanException)
- throw (NotCompliantMBeanException) e;
- if (e instanceof InstanceNotFoundException)
- throw (InstanceNotFoundException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- public void unregisterMBean(ObjectName name, Subject delegationSubject)
- throws
- InstanceNotFoundException,
- MBeanRegistrationException,
- IOException {
- try {
- final Object params[] = new Object[] { name };
-
- if (logger.debugOn()) logger.debug("unregisterMBean",
- "connectionId=" + connectionId
- +", name="+name);
-
- doPrivilegedOperation(
- UNREGISTER_MBEAN,
- params,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof InstanceNotFoundException)
- throw (InstanceNotFoundException) e;
- if (e instanceof MBeanRegistrationException)
- throw (MBeanRegistrationException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- public ObjectInstance getObjectInstance(ObjectName name,
- Subject delegationSubject)
- throws
- InstanceNotFoundException,
- IOException {
-
- checkNonNull("ObjectName", name);
-
- try {
- final Object params[] = new Object[] { name };
-
- if (logger.debugOn()) logger.debug("getObjectInstance",
- "connectionId=" + connectionId
- +", name="+name);
-
- return (ObjectInstance)
- doPrivilegedOperation(
- GET_OBJECT_INSTANCE,
- params,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof InstanceNotFoundException)
- throw (InstanceNotFoundException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- @SuppressWarnings("rawtypes") // MarshalledObject
- public Set<ObjectInstance>
- queryMBeans(ObjectName name,
- MarshalledObject query,
- Subject delegationSubject)
- throws IOException {
- final QueryExp queryValue;
- final boolean debug=logger.debugOn();
-
- if (debug) logger.debug("queryMBeans",
- "connectionId=" + connectionId
- +" unwrapping query with defaultClassLoader.");
-
- queryValue = unwrap(query, defaultContextClassLoader, QueryExp.class, delegationSubject);
-
- try {
- final Object params[] = new Object[] { name, queryValue };
-
- if (debug) logger.debug("queryMBeans",
- "connectionId=" + connectionId
- +", name="+name +", query="+query);
-
- return cast(
- doPrivilegedOperation(
- QUERY_MBEANS,
- params,
- delegationSubject));
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- @SuppressWarnings("rawtypes") // MarshalledObject
- public Set<ObjectName>
- queryNames(ObjectName name,
- MarshalledObject query,
- Subject delegationSubject)
- throws IOException {
- final QueryExp queryValue;
- final boolean debug=logger.debugOn();
-
- if (debug) logger.debug("queryNames",
- "connectionId=" + connectionId
- +" unwrapping query with defaultClassLoader.");
-
- queryValue = unwrap(query, defaultContextClassLoader, QueryExp.class, delegationSubject);
-
- try {
- final Object params[] = new Object[] { name, queryValue };
-
- if (debug) logger.debug("queryNames",
- "connectionId=" + connectionId
- +", name="+name +", query="+query);
-
- return cast(
- doPrivilegedOperation(
- QUERY_NAMES,
- params,
- delegationSubject));
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- public boolean isRegistered(ObjectName name,
- Subject delegationSubject) throws IOException {
- try {
- final Object params[] = new Object[] { name };
- return ((Boolean)
- doPrivilegedOperation(
- IS_REGISTERED,
- params,
- delegationSubject)).booleanValue();
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- public Integer getMBeanCount(Subject delegationSubject)
- throws IOException {
- try {
- final Object params[] = new Object[] { };
-
- if (logger.debugOn()) logger.debug("getMBeanCount",
- "connectionId=" + connectionId);
-
- return (Integer)
- doPrivilegedOperation(
- GET_MBEAN_COUNT,
- params,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- public Object getAttribute(ObjectName name,
- String attribute,
- Subject delegationSubject)
- throws
- MBeanException,
- AttributeNotFoundException,
- InstanceNotFoundException,
- ReflectionException,
- IOException {
- try {
- final Object params[] = new Object[] { name, attribute };
- if (logger.debugOn()) logger.debug("getAttribute",
- "connectionId=" + connectionId
- +", name=" + name
- +", attribute="+ attribute);
-
- return
- doPrivilegedOperation(
- GET_ATTRIBUTE,
- params,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof MBeanException)
- throw (MBeanException) e;
- if (e instanceof AttributeNotFoundException)
- throw (AttributeNotFoundException) e;
- if (e instanceof InstanceNotFoundException)
- throw (InstanceNotFoundException) e;
- if (e instanceof ReflectionException)
- throw (ReflectionException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- public AttributeList getAttributes(ObjectName name,
- String[] attributes,
- Subject delegationSubject)
- throws
- InstanceNotFoundException,
- ReflectionException,
- IOException {
- try {
- final Object params[] = new Object[] { name, attributes };
-
- if (logger.debugOn()) logger.debug("getAttributes",
- "connectionId=" + connectionId
- +", name=" + name
- +", attributes="+ strings(attributes));
-
- return (AttributeList)
- doPrivilegedOperation(
- GET_ATTRIBUTES,
- params,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof InstanceNotFoundException)
- throw (InstanceNotFoundException) e;
- if (e instanceof ReflectionException)
- throw (ReflectionException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- @SuppressWarnings("rawtypes") // MarshalledObject
- public void setAttribute(ObjectName name,
- MarshalledObject attribute,
- Subject delegationSubject)
- throws
- InstanceNotFoundException,
- AttributeNotFoundException,
- InvalidAttributeValueException,
- MBeanException,
- ReflectionException,
- IOException {
- final Attribute attr;
- final boolean debug=logger.debugOn();
-
- if (debug) logger.debug("setAttribute",
- "connectionId=" + connectionId
- +" unwrapping attribute with MBean extended ClassLoader.");
-
- attr = unwrap(attribute,
- getClassLoaderFor(name),
- defaultClassLoader,
- Attribute.class, delegationSubject);
-
- try {
- final Object params[] = new Object[] { name, attr };
-
- if (debug) logger.debug("setAttribute",
- "connectionId=" + connectionId
- +", name="+name
- +", attribute name="+attr.getName());
-
- doPrivilegedOperation(
- SET_ATTRIBUTE,
- params,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof InstanceNotFoundException)
- throw (InstanceNotFoundException) e;
- if (e instanceof AttributeNotFoundException)
- throw (AttributeNotFoundException) e;
- if (e instanceof InvalidAttributeValueException)
- throw (InvalidAttributeValueException) e;
- if (e instanceof MBeanException)
- throw (MBeanException) e;
- if (e instanceof ReflectionException)
- throw (ReflectionException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- @SuppressWarnings("rawtypes") // MarshalledObject
- public AttributeList setAttributes(ObjectName name,
- MarshalledObject attributes,
- Subject delegationSubject)
- throws
- InstanceNotFoundException,
- ReflectionException,
- IOException {
- final AttributeList attrlist;
- final boolean debug=logger.debugOn();
-
- if (debug) logger.debug("setAttributes",
- "connectionId=" + connectionId
- +" unwrapping attributes with MBean extended ClassLoader.");
-
- attrlist =
- unwrap(attributes,
- getClassLoaderFor(name),
- defaultClassLoader,
- AttributeList.class, delegationSubject);
-
- try {
- final Object params[] = new Object[] { name, attrlist };
-
- if (debug) logger.debug("setAttributes",
- "connectionId=" + connectionId
- +", name="+name
- +", attribute names="+RMIConnector.getAttributesNames(attrlist));
-
- return (AttributeList)
- doPrivilegedOperation(
- SET_ATTRIBUTES,
- params,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof InstanceNotFoundException)
- throw (InstanceNotFoundException) e;
- if (e instanceof ReflectionException)
- throw (ReflectionException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- @SuppressWarnings("rawtypes") // MarshalledObject
- public Object invoke(ObjectName name,
- String operationName,
- MarshalledObject params,
- String signature[],
- Subject delegationSubject)
- throws
- InstanceNotFoundException,
- MBeanException,
- ReflectionException,
- IOException {
-
- checkNonNull("ObjectName", name);
- checkNonNull("Operation name", operationName);
-
- final Object[] values;
- final boolean debug=logger.debugOn();
-
- if (debug) logger.debug("invoke",
- "connectionId=" + connectionId
- +" unwrapping params with MBean extended ClassLoader.");
-
- values = nullIsEmpty(unwrap(params,
- getClassLoaderFor(name),
- defaultClassLoader,
- Object[].class, delegationSubject));
-
- try {
- final Object params2[] =
- new Object[] { name, operationName, values,
- nullIsEmpty(signature) };
-
- if (debug) logger.debug("invoke",
- "connectionId=" + connectionId
- +", name="+name
- +", operationName="+operationName
- +", signature="+strings(signature));
-
- return
- doPrivilegedOperation(
- INVOKE,
- params2,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof InstanceNotFoundException)
- throw (InstanceNotFoundException) e;
- if (e instanceof MBeanException)
- throw (MBeanException) e;
- if (e instanceof ReflectionException)
- throw (ReflectionException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- public String getDefaultDomain(Subject delegationSubject)
- throws IOException {
- try {
- final Object params[] = new Object[] { };
-
- if (logger.debugOn()) logger.debug("getDefaultDomain",
- "connectionId=" + connectionId);
-
- return (String)
- doPrivilegedOperation(
- GET_DEFAULT_DOMAIN,
- params,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- public String[] getDomains(Subject delegationSubject) throws IOException {
- try {
- final Object params[] = new Object[] { };
-
- if (logger.debugOn()) logger.debug("getDomains",
- "connectionId=" + connectionId);
-
- return (String[])
- doPrivilegedOperation(
- GET_DOMAINS,
- params,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- public MBeanInfo getMBeanInfo(ObjectName name, Subject delegationSubject)
- throws
- InstanceNotFoundException,
- IntrospectionException,
- ReflectionException,
- IOException {
-
- checkNonNull("ObjectName", name);
-
- try {
- final Object params[] = new Object[] { name };
-
- if (logger.debugOn()) logger.debug("getMBeanInfo",
- "connectionId=" + connectionId
- +", name="+name);
-
- return (MBeanInfo)
- doPrivilegedOperation(
- GET_MBEAN_INFO,
- params,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof InstanceNotFoundException)
- throw (InstanceNotFoundException) e;
- if (e instanceof IntrospectionException)
- throw (IntrospectionException) e;
- if (e instanceof ReflectionException)
- throw (ReflectionException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- public boolean isInstanceOf(ObjectName name,
- String className,
- Subject delegationSubject)
- throws InstanceNotFoundException, IOException {
-
- checkNonNull("ObjectName", name);
-
- try {
- final Object params[] = new Object[] { name, className };
-
- if (logger.debugOn()) logger.debug("isInstanceOf",
- "connectionId=" + connectionId
- +", name="+name
- +", className="+className);
-
- return ((Boolean)
- doPrivilegedOperation(
- IS_INSTANCE_OF,
- params,
- delegationSubject)).booleanValue();
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof InstanceNotFoundException)
- throw (InstanceNotFoundException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- @SuppressWarnings("rawtypes") // MarshalledObject
- public Integer[] addNotificationListeners(ObjectName[] names,
- MarshalledObject[] filters,
- Subject[] delegationSubjects)
- throws InstanceNotFoundException, IOException {
-
- if (names == null || filters == null) {
- throw new IllegalArgumentException("Got null arguments.");
- }
-
- Subject[] sbjs = (delegationSubjects != null) ? delegationSubjects :
- new Subject[names.length];
- if (names.length != filters.length || filters.length != sbjs.length) {
- final String msg =
- "The value lengths of 3 parameters are not same.";
- throw new IllegalArgumentException(msg);
- }
-
- for (int i=0; i<names.length; i++) {
- if (names[i] == null) {
- throw new IllegalArgumentException("Null Object name.");
- }
- }
-
- int i=0;
- ClassLoader targetCl;
- NotificationFilter[] filterValues =
- new NotificationFilter[names.length];
- Integer[] ids = new Integer[names.length];
- final boolean debug=logger.debugOn();
-
- try {
- for (; i<names.length; i++) {
- targetCl = getClassLoaderFor(names[i]);
-
- if (debug) logger.debug("addNotificationListener"+
- "(ObjectName,NotificationFilter)",
- "connectionId=" + connectionId +
- " unwrapping filter with target extended ClassLoader.");
-
- filterValues[i] =
- unwrap(filters[i], targetCl, defaultClassLoader,
- NotificationFilter.class, sbjs[i]);
-
- if (debug) logger.debug("addNotificationListener"+
- "(ObjectName,NotificationFilter)",
- "connectionId=" + connectionId
- +", name=" + names[i]
- +", filter=" + filterValues[i]);
-
- ids[i] = (Integer)
- doPrivilegedOperation(ADD_NOTIFICATION_LISTENERS,
- new Object[] { names[i],
- filterValues[i] },
- sbjs[i]);
- }
-
- return ids;
- } catch (Exception e) {
- // remove all registered listeners
- for (int j=0; j<i; j++) {
- try {
- getServerNotifFwd().removeNotificationListener(names[j],
- ids[j]);
- } catch (Exception eee) {
- // strange
- }
- }
-
- if (e instanceof PrivilegedActionException) {
- e = extractException(e);
- }
-
- if (e instanceof ClassCastException) {
- throw (ClassCastException) e;
- } else if (e instanceof IOException) {
- throw (IOException)e;
- } else if (e instanceof InstanceNotFoundException) {
- throw (InstanceNotFoundException) e;
- } else if (e instanceof RuntimeException) {
- throw (RuntimeException) e;
- } else {
- throw newIOException("Got unexpected server exception: "+e,e);
- }
- }
- }
-
- @SuppressWarnings("rawtypes") // MarshalledObject
- public void addNotificationListener(ObjectName name,
- ObjectName listener,
- MarshalledObject filter,
- MarshalledObject handback,
- Subject delegationSubject)
- throws InstanceNotFoundException, IOException {
-
- checkNonNull("Target MBean name", name);
- checkNonNull("Listener MBean name", listener);
-
- final NotificationFilter filterValue;
- final Object handbackValue;
- final boolean debug=logger.debugOn();
-
- final ClassLoader targetCl = getClassLoaderFor(name);
-
- if (debug) logger.debug("addNotificationListener"+
- "(ObjectName,ObjectName,NotificationFilter,Object)",
- "connectionId=" + connectionId
- +" unwrapping filter with target extended ClassLoader.");
-
- filterValue =
- unwrap(filter, targetCl, defaultClassLoader, NotificationFilter.class, delegationSubject);
-
- if (debug) logger.debug("addNotificationListener"+
- "(ObjectName,ObjectName,NotificationFilter,Object)",
- "connectionId=" + connectionId
- +" unwrapping handback with target extended ClassLoader.");
-
- handbackValue =
- unwrap(handback, targetCl, defaultClassLoader, Object.class, delegationSubject);
-
- try {
- final Object params[] =
- new Object[] { name, listener, filterValue, handbackValue };
-
- if (debug) logger.debug("addNotificationListener"+
- "(ObjectName,ObjectName,NotificationFilter,Object)",
- "connectionId=" + connectionId
- +", name=" + name
- +", listenerName=" + listener
- +", filter=" + filterValue
- +", handback=" + handbackValue);
-
- doPrivilegedOperation(
- ADD_NOTIFICATION_LISTENER_OBJECTNAME,
- params,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof InstanceNotFoundException)
- throw (InstanceNotFoundException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- public void removeNotificationListeners(ObjectName name,
- Integer[] listenerIDs,
- Subject delegationSubject)
- throws
- InstanceNotFoundException,
- ListenerNotFoundException,
- IOException {
-
- if (name == null || listenerIDs == null)
- throw new IllegalArgumentException("Illegal null parameter");
-
- for (int i = 0; i < listenerIDs.length; i++) {
- if (listenerIDs[i] == null)
- throw new IllegalArgumentException("Null listener ID");
- }
-
- try {
- final Object params[] = new Object[] { name, listenerIDs };
-
- if (logger.debugOn()) logger.debug("removeNotificationListener"+
- "(ObjectName,Integer[])",
- "connectionId=" + connectionId
- +", name=" + name
- +", listenerIDs=" + objects(listenerIDs));
-
- doPrivilegedOperation(
- REMOVE_NOTIFICATION_LISTENER,
- params,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof InstanceNotFoundException)
- throw (InstanceNotFoundException) e;
- if (e instanceof ListenerNotFoundException)
- throw (ListenerNotFoundException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- public void removeNotificationListener(ObjectName name,
- ObjectName listener,
- Subject delegationSubject)
- throws
- InstanceNotFoundException,
- ListenerNotFoundException,
- IOException {
-
- checkNonNull("Target MBean name", name);
- checkNonNull("Listener MBean name", listener);
-
- try {
- final Object params[] = new Object[] { name, listener };
-
- if (logger.debugOn()) logger.debug("removeNotificationListener"+
- "(ObjectName,ObjectName)",
- "connectionId=" + connectionId
- +", name=" + name
- +", listenerName=" + listener);
-
- doPrivilegedOperation(
- REMOVE_NOTIFICATION_LISTENER_OBJECTNAME,
- params,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof InstanceNotFoundException)
- throw (InstanceNotFoundException) e;
- if (e instanceof ListenerNotFoundException)
- throw (ListenerNotFoundException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- @SuppressWarnings("rawtypes") // MarshalledObject
- public void removeNotificationListener(ObjectName name,
- ObjectName listener,
- MarshalledObject filter,
- MarshalledObject handback,
- Subject delegationSubject)
- throws
- InstanceNotFoundException,
- ListenerNotFoundException,
- IOException {
-
- checkNonNull("Target MBean name", name);
- checkNonNull("Listener MBean name", listener);
-
- final NotificationFilter filterValue;
- final Object handbackValue;
- final boolean debug=logger.debugOn();
-
- final ClassLoader targetCl = getClassLoaderFor(name);
-
- if (debug) logger.debug("removeNotificationListener"+
- "(ObjectName,ObjectName,NotificationFilter,Object)",
- "connectionId=" + connectionId
- +" unwrapping filter with target extended ClassLoader.");
-
- filterValue =
- unwrap(filter, targetCl, defaultClassLoader, NotificationFilter.class, delegationSubject);
-
- if (debug) logger.debug("removeNotificationListener"+
- "(ObjectName,ObjectName,NotificationFilter,Object)",
- "connectionId=" + connectionId
- +" unwrapping handback with target extended ClassLoader.");
-
- handbackValue =
- unwrap(handback, targetCl, defaultClassLoader, Object.class, delegationSubject);
-
- try {
- final Object params[] =
- new Object[] { name, listener, filterValue, handbackValue };
-
- if (debug) logger.debug("removeNotificationListener"+
- "(ObjectName,ObjectName,NotificationFilter,Object)",
- "connectionId=" + connectionId
- +", name=" + name
- +", listenerName=" + listener
- +", filter=" + filterValue
- +", handback=" + handbackValue);
-
- doPrivilegedOperation(
- REMOVE_NOTIFICATION_LISTENER_OBJECTNAME_FILTER_HANDBACK,
- params,
- delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof InstanceNotFoundException)
- throw (InstanceNotFoundException) e;
- if (e instanceof ListenerNotFoundException)
- throw (ListenerNotFoundException) e;
- if (e instanceof IOException)
- throw (IOException) e;
- throw newIOException("Got unexpected server exception: " + e, e);
- }
- }
-
- public NotificationResult fetchNotifications(long clientSequenceNumber,
- int maxNotifications,
- long timeout)
- throws IOException {
-
- if (logger.debugOn()) logger.debug("fetchNotifications",
- "connectionId=" + connectionId
- +", timeout=" + timeout);
-
- if (maxNotifications < 0 || timeout < 0)
- throw new IllegalArgumentException("Illegal negative argument");
-
- final boolean serverTerminated =
- serverCommunicatorAdmin.reqIncoming();
- try {
- if (serverTerminated) {
- // we must not call fetchNotifs() if the server is
- // terminated (timeout elapsed).
- // returns null to force the client to stop fetching
- if (logger.debugOn()) logger.debug("fetchNotifications",
- "The notification server has been closed, "
- + "returns null to force the client to stop fetching");
- return null;
- }
- final long csn = clientSequenceNumber;
- final int mn = maxNotifications;
- final long t = timeout;
- PrivilegedAction<NotificationResult> action =
- new PrivilegedAction<NotificationResult>() {
- public NotificationResult run() {
- return getServerNotifFwd().fetchNotifs(csn, t, mn);
- }
- };
- if (acc == null)
- return action.run();
- else
- return AccessController.doPrivileged(action, acc);
- } finally {
- serverCommunicatorAdmin.rspOutgoing();
- }
- }
-
- /**
- * <p>Returns a string representation of this object. In general,
- * the <code>toString</code> method returns a string that
- * "textually represents" this object. The result should be a
- * concise but informative representation that is easy for a
- * person to read.</p>
- *
- * @return a String representation of this object.
- **/
- @Override
- public String toString() {
- return super.toString() + ": connectionId=" + connectionId;
- }
-
- //------------------------------------------------------------------------
- // private classes
- //------------------------------------------------------------------------
-
- private class PrivilegedOperation
- implements PrivilegedExceptionAction<Object> {
-
- public PrivilegedOperation(int operation, Object[] params) {
- this.operation = operation;
- this.params = params;
- }
-
- public Object run() throws Exception {
- return doOperation(operation, params);
- }
-
- private int operation;
- private Object[] params;
- }
-
- //------------------------------------------------------------------------
- // private classes
- //------------------------------------------------------------------------
- private class RMIServerCommunicatorAdmin extends ServerCommunicatorAdmin {
- public RMIServerCommunicatorAdmin(long timeout) {
- super(timeout);
- }
-
- protected void doStop() {
- try {
- close();
- } catch (IOException ie) {
- logger.warning("RMIServerCommunicatorAdmin-doStop",
- "Failed to close: " + ie);
- logger.debug("RMIServerCommunicatorAdmin-doStop",ie);
- }
- }
-
- }
-
-
- //------------------------------------------------------------------------
- // private methods
- //------------------------------------------------------------------------
-
- private ClassLoader getClassLoader(final ObjectName name)
- throws InstanceNotFoundException {
- try {
- return
- AccessController.doPrivileged(
- new PrivilegedExceptionAction<ClassLoader>() {
- public ClassLoader run() throws InstanceNotFoundException {
- return mbeanServer.getClassLoader(name);
- }
- },
- withPermissions(new MBeanPermission("*", "getClassLoader"))
- );
- } catch (PrivilegedActionException pe) {
- throw (InstanceNotFoundException) extractException(pe);
- }
- }
-
- private ClassLoader getClassLoaderFor(final ObjectName name)
- throws InstanceNotFoundException {
- try {
- return (ClassLoader)
- AccessController.doPrivileged(
- new PrivilegedExceptionAction<Object>() {
- public Object run() throws InstanceNotFoundException {
- return mbeanServer.getClassLoaderFor(name);
- }
- },
- withPermissions(new MBeanPermission("*", "getClassLoaderFor"))
- );
- } catch (PrivilegedActionException pe) {
- throw (InstanceNotFoundException) extractException(pe);
- }
- }
-
- private Object doPrivilegedOperation(final int operation,
- final Object[] params,
- final Subject delegationSubject)
- throws PrivilegedActionException, IOException {
-
- serverCommunicatorAdmin.reqIncoming();
- try {
-
- final AccessControlContext reqACC;
- if (delegationSubject == null)
- reqACC = acc;
- else {
- if (subject == null) {
- final String msg =
- "Subject delegation cannot be enabled unless " +
- "an authenticated subject is put in place";
- throw new SecurityException(msg);
- }
- reqACC = subjectDelegator.delegatedContext(
- acc, delegationSubject, removeCallerContext);
- }
-
- PrivilegedOperation op =
- new PrivilegedOperation(operation, params);
- if (reqACC == null) {
- try {
- return op.run();
- } catch (Exception e) {
- if (e instanceof RuntimeException)
- throw (RuntimeException) e;
- throw new PrivilegedActionException(e);
- }
- } else {
- return AccessController.doPrivileged(op, reqACC);
- }
- } catch (Error e) {
- throw new JMXServerErrorException(e.toString(),e);
- } finally {
- serverCommunicatorAdmin.rspOutgoing();
- }
- }
-
- private Object doOperation(int operation, Object[] params)
- throws Exception {
-
- switch (operation) {
-
- case CREATE_MBEAN:
- return mbeanServer.createMBean((String)params[0],
- (ObjectName)params[1]);
-
- case CREATE_MBEAN_LOADER:
- return mbeanServer.createMBean((String)params[0],
- (ObjectName)params[1],
- (ObjectName)params[2]);
-
- case CREATE_MBEAN_PARAMS:
- return mbeanServer.createMBean((String)params[0],
- (ObjectName)params[1],
- (Object[])params[2],
- (String[])params[3]);
-
- case CREATE_MBEAN_LOADER_PARAMS:
- return mbeanServer.createMBean((String)params[0],
- (ObjectName)params[1],
- (ObjectName)params[2],
- (Object[])params[3],
- (String[])params[4]);
-
- case GET_ATTRIBUTE:
- return mbeanServer.getAttribute((ObjectName)params[0],
- (String)params[1]);
-
- case GET_ATTRIBUTES:
- return mbeanServer.getAttributes((ObjectName)params[0],
- (String[])params[1]);
-
- case GET_DEFAULT_DOMAIN:
- return mbeanServer.getDefaultDomain();
-
- case GET_DOMAINS:
- return mbeanServer.getDomains();
-
- case GET_MBEAN_COUNT:
- return mbeanServer.getMBeanCount();
-
- case GET_MBEAN_INFO:
- return mbeanServer.getMBeanInfo((ObjectName)params[0]);
-
- case GET_OBJECT_INSTANCE:
- return mbeanServer.getObjectInstance((ObjectName)params[0]);
-
- case INVOKE:
- return mbeanServer.invoke((ObjectName)params[0],
- (String)params[1],
- (Object[])params[2],
- (String[])params[3]);
-
- case IS_INSTANCE_OF:
- return mbeanServer.isInstanceOf((ObjectName)params[0],
- (String)params[1])
- ? Boolean.TRUE : Boolean.FALSE;
-
- case IS_REGISTERED:
- return mbeanServer.isRegistered((ObjectName)params[0])
- ? Boolean.TRUE : Boolean.FALSE;
-
- case QUERY_MBEANS:
- return mbeanServer.queryMBeans((ObjectName)params[0],
- (QueryExp)params[1]);
-
- case QUERY_NAMES:
- return mbeanServer.queryNames((ObjectName)params[0],
- (QueryExp)params[1]);
-
- case SET_ATTRIBUTE:
- mbeanServer.setAttribute((ObjectName)params[0],
- (Attribute)params[1]);
- return null;
-
- case SET_ATTRIBUTES:
- return mbeanServer.setAttributes((ObjectName)params[0],
- (AttributeList)params[1]);
-
- case UNREGISTER_MBEAN:
- mbeanServer.unregisterMBean((ObjectName)params[0]);
- return null;
-
- case ADD_NOTIFICATION_LISTENERS:
- return getServerNotifFwd().addNotificationListener(
- (ObjectName)params[0],
- (NotificationFilter)params[1]);
-
- case ADD_NOTIFICATION_LISTENER_OBJECTNAME:
- mbeanServer.addNotificationListener((ObjectName)params[0],
- (ObjectName)params[1],
- (NotificationFilter)params[2],
- params[3]);
- return null;
-
- case REMOVE_NOTIFICATION_LISTENER:
- getServerNotifFwd().removeNotificationListener(
- (ObjectName)params[0],
- (Integer[])params[1]);
- return null;
-
- case REMOVE_NOTIFICATION_LISTENER_OBJECTNAME:
- mbeanServer.removeNotificationListener((ObjectName)params[0],
- (ObjectName)params[1]);
- return null;
-
- case REMOVE_NOTIFICATION_LISTENER_OBJECTNAME_FILTER_HANDBACK:
- mbeanServer.removeNotificationListener(
- (ObjectName)params[0],
- (ObjectName)params[1],
- (NotificationFilter)params[2],
- params[3]);
- return null;
-
- default:
- throw new IllegalArgumentException("Invalid operation");
- }
- }
-
- private static class SetCcl implements PrivilegedExceptionAction<ClassLoader> {
- private final ClassLoader classLoader;
-
- SetCcl(ClassLoader classLoader) {
- this.classLoader = classLoader;
- }
-
- public ClassLoader run() {
- Thread currentThread = Thread.currentThread();
- ClassLoader old = currentThread.getContextClassLoader();
- currentThread.setContextClassLoader(classLoader);
- return old;
- }
- }
-
- private <T> T unwrap(final MarshalledObject<?> mo,
- final ClassLoader cl,
- final Class<T> wrappedClass,
- Subject delegationSubject)
- throws IOException {
- if (mo == null) {
- return null;
- }
- try {
- final ClassLoader old = AccessController.doPrivileged(new SetCcl(cl));
- try{
- final AccessControlContext reqACC;
- if (delegationSubject == null)
- reqACC = acc;
- else {
- if (subject == null) {
- final String msg =
- "Subject delegation cannot be enabled unless " +
- "an authenticated subject is put in place";
- throw new SecurityException(msg);
- }
- reqACC = subjectDelegator.delegatedContext(
- acc, delegationSubject, removeCallerContext);
- }
- if(reqACC != null){
- return AccessController.doPrivileged(
- (PrivilegedExceptionAction<T>) () ->
- wrappedClass.cast(mo.get()), reqACC);
- }else{
- return wrappedClass.cast(mo.get());
- }
- }finally{
- AccessController.doPrivileged(new SetCcl(old));
- }
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof IOException) {
- throw (IOException) e;
- }
- if (e instanceof ClassNotFoundException) {
- throw new UnmarshalException(e.toString(), e);
- }
- logger.warning("unwrap", "Failed to unmarshall object: " + e);
- logger.debug("unwrap", e);
- }catch (ClassNotFoundException ex) {
- logger.warning("unwrap", "Failed to unmarshall object: " + ex);
- logger.debug("unwrap", ex);
- throw new UnmarshalException(ex.toString(), ex);
- }
- return null;
- }
-
- private <T> T unwrap(final MarshalledObject<?> mo,
- final ClassLoader cl1,
- final ClassLoader cl2,
- final Class<T> wrappedClass,
- Subject delegationSubject)
- throws IOException {
- if (mo == null) {
- return null;
- }
- try {
- ClassLoader orderCL = AccessController.doPrivileged(
- new PrivilegedExceptionAction<ClassLoader>() {
- public ClassLoader run() throws Exception {
- return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(),
- new OrderClassLoaders(cl1, cl2));
- }
- }
- );
- return unwrap(mo, orderCL, wrappedClass,delegationSubject);
- } catch (PrivilegedActionException pe) {
- Exception e = extractException(pe);
- if (e instanceof IOException) {
- throw (IOException) e;
- }
- if (e instanceof ClassNotFoundException) {
- throw new UnmarshalException(e.toString(), e);
- }
- logger.warning("unwrap", "Failed to unmarshall object: " + e);
- logger.debug("unwrap", e);
- }
- return null;
- }
-
- /**
- * Construct a new IOException with a nested exception.
- * The nested exception is set only if JDK {@literal >= 1.4}
- */
- private static IOException newIOException(String message,
- Throwable cause) {
- final IOException x = new IOException(message);
- return EnvHelp.initCause(x,cause);
- }
-
- /**
- * Iterate until we extract the real exception
- * from a stack of PrivilegedActionExceptions.
- */
- private static Exception extractException(Exception e) {
- while (e instanceof PrivilegedActionException) {
- e = ((PrivilegedActionException)e).getException();
- }
- return e;
- }
-
- private static final Object[] NO_OBJECTS = new Object[0];
- private static final String[] NO_STRINGS = new String[0];
-
- /*
- * The JMX spec doesn't explicitly say that a null Object[] or
- * String[] in e.g. MBeanServer.invoke is equivalent to an empty
- * array, but the RI behaves that way. In the interests of
- * maximal interoperability, we make it so even when we're
- * connected to some other JMX implementation that might not do
- * that. This should be clarified in the next version of JMX.
- */
- private static Object[] nullIsEmpty(Object[] array) {
- return (array == null) ? NO_OBJECTS : array;
- }
-
- private static String[] nullIsEmpty(String[] array) {
- return (array == null) ? NO_STRINGS : array;
- }
-
- /*
- * Similarly, the JMX spec says for some but not all methods in
- * MBeanServer that take an ObjectName target, that if it's null
- * you get this exception. We specify it for all of them, and
- * make it so for the ones where it's not specified in JMX even if
- * the JMX implementation doesn't do so.
- */
- private static void checkNonNull(String what, Object x) {
- if (x == null) {
- RuntimeException wrapped =
- new IllegalArgumentException(what + " must not be null");
- throw new RuntimeOperationsException(wrapped);
- }
- }
-
- //------------------------------------------------------------------------
- // private variables
- //------------------------------------------------------------------------
-
- private final Subject subject;
-
- private final SubjectDelegator subjectDelegator;
-
- private final boolean removeCallerContext;
-
- private final AccessControlContext acc;
-
- private final RMIServerImpl rmiServer;
-
- private final MBeanServer mbeanServer;
-
- private final ClassLoader defaultClassLoader;
-
- private final ClassLoader defaultContextClassLoader;
-
- private final ClassLoaderWithRepository classLoaderWithRepository;
-
- private boolean terminated = false;
-
- private final String connectionId;
-
- private final ServerCommunicatorAdmin serverCommunicatorAdmin;
-
- // Method IDs for doOperation
- //---------------------------
-
- private final static int
- ADD_NOTIFICATION_LISTENERS = 1;
- private final static int
- ADD_NOTIFICATION_LISTENER_OBJECTNAME = 2;
- private final static int
- CREATE_MBEAN = 3;
- private final static int
- CREATE_MBEAN_PARAMS = 4;
- private final static int
- CREATE_MBEAN_LOADER = 5;
- private final static int
- CREATE_MBEAN_LOADER_PARAMS = 6;
- private final static int
- GET_ATTRIBUTE = 7;
- private final static int
- GET_ATTRIBUTES = 8;
- private final static int
- GET_DEFAULT_DOMAIN = 9;
- private final static int
- GET_DOMAINS = 10;
- private final static int
- GET_MBEAN_COUNT = 11;
- private final static int
- GET_MBEAN_INFO = 12;
- private final static int
- GET_OBJECT_INSTANCE = 13;
- private final static int
- INVOKE = 14;
- private final static int
- IS_INSTANCE_OF = 15;
- private final static int
- IS_REGISTERED = 16;
- private final static int
- QUERY_MBEANS = 17;
- private final static int
- QUERY_NAMES = 18;
- private final static int
- REMOVE_NOTIFICATION_LISTENER = 19;
- private final static int
- REMOVE_NOTIFICATION_LISTENER_OBJECTNAME = 20;
- private final static int
- REMOVE_NOTIFICATION_LISTENER_OBJECTNAME_FILTER_HANDBACK = 21;
- private final static int
- SET_ATTRIBUTE = 22;
- private final static int
- SET_ATTRIBUTES = 23;
- private final static int
- UNREGISTER_MBEAN = 24;
-
- // SERVER NOTIFICATION
- //--------------------
-
- private ServerNotifForwarder serverNotifForwarder;
- private Map<String, ?> env;
-
- // TRACES & DEBUG
- //---------------
-
- private static String objects(final Object[] objs) {
- if (objs == null)
- return "null";
- else
- return Arrays.asList(objs).toString();
- }
-
- private static String strings(final String[] strs) {
- return objects(strs);
- }
-
- private static final ClassLogger logger =
- new ClassLogger("javax.management.remote.rmi", "RMIConnectionImpl");
-
- private static final class CombinedClassLoader extends ClassLoader {
-
- private final static class ClassLoaderWrapper extends ClassLoader {
- ClassLoaderWrapper(ClassLoader cl) {
- super(cl);
- }
-
- @Override
- protected Class<?> loadClass(String name, boolean resolve)
- throws ClassNotFoundException {
- return super.loadClass(name, resolve);
- }
- };
-
- final ClassLoaderWrapper defaultCL;
-
- private CombinedClassLoader(ClassLoader parent, ClassLoader defaultCL) {
- super(parent);
- this.defaultCL = new ClassLoaderWrapper(defaultCL);
- }
-
- @Override
- protected Class<?> loadClass(String name, boolean resolve)
- throws ClassNotFoundException {
- ReflectUtil.checkPackageAccess(name);
- try {
- super.loadClass(name, resolve);
- } catch(Exception e) {
- for(Throwable t = e; t != null; t = t.getCause()) {
- if(t instanceof SecurityException) {
- throw t==e?(SecurityException)t:new SecurityException(t.getMessage(), e);
- }
- }
- }
- final Class<?> cl = defaultCL.loadClass(name, resolve);
- return cl;
- }
-
- }
-}
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnector.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,2289 +0,0 @@
-/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javax.management.remote.rmi;
-
-import com.sun.jmx.mbeanserver.Util;
-import com.sun.jmx.remote.internal.ClientCommunicatorAdmin;
-import com.sun.jmx.remote.internal.ClientListenerInfo;
-import com.sun.jmx.remote.internal.ClientNotifForwarder;
-import com.sun.jmx.remote.internal.ProxyRef;
-import com.sun.jmx.remote.util.ClassLogger;
-import com.sun.jmx.remote.util.EnvHelp;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InvalidObjectException;
-import java.io.ObjectInputStream;
-import java.io.ObjectStreamClass;
-import java.io.Serializable;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Module;
-import java.lang.reflect.Proxy;
-import java.net.MalformedURLException;
-import java.rmi.MarshalledObject;
-import java.rmi.NoSuchObjectException;
-import java.rmi.Remote;
-import java.rmi.ServerException;
-import java.rmi.UnmarshalException;
-import java.rmi.server.RMIClientSocketFactory;
-import java.rmi.server.RemoteObject;
-import java.rmi.server.RemoteObjectInvocationHandler;
-import java.rmi.server.RemoteRef;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedExceptionAction;
-import java.security.ProtectionDomain;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.WeakHashMap;
-import java.util.stream.Collectors;
-import javax.management.Attribute;
-import javax.management.AttributeList;
-import javax.management.AttributeNotFoundException;
-import javax.management.InstanceAlreadyExistsException;
-import javax.management.InstanceNotFoundException;
-import javax.management.IntrospectionException;
-import javax.management.InvalidAttributeValueException;
-import javax.management.ListenerNotFoundException;
-import javax.management.MBeanException;
-import javax.management.MBeanInfo;
-import javax.management.MBeanRegistrationException;
-import javax.management.MBeanServerConnection;
-import javax.management.MBeanServerDelegate;
-import javax.management.MBeanServerNotification;
-import javax.management.NotCompliantMBeanException;
-import javax.management.Notification;
-import javax.management.NotificationBroadcasterSupport;
-import javax.management.NotificationFilter;
-import javax.management.NotificationFilterSupport;
-import javax.management.NotificationListener;
-import javax.management.ObjectInstance;
-import javax.management.ObjectName;
-import javax.management.QueryExp;
-import javax.management.ReflectionException;
-import javax.management.remote.JMXConnectionNotification;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.NotificationResult;
-import javax.management.remote.JMXAddressable;
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-import javax.rmi.ssl.SslRMIClientSocketFactory;
-import javax.security.auth.Subject;
-import jdk.internal.module.Modules;
-import sun.reflect.misc.ReflectUtil;
-import sun.rmi.server.UnicastRef2;
-import sun.rmi.transport.LiveRef;
-
-/**
- * <p>A connection to a remote RMI connector. Usually, such
- * connections are made using {@link
- * javax.management.remote.JMXConnectorFactory JMXConnectorFactory}.
- * However, specialized applications can use this class directly, for
- * example with an {@link RMIServer} stub obtained without going
- * through JNDI.</p>
- *
- * @since 1.5
- */
-public class RMIConnector implements JMXConnector, Serializable, JMXAddressable {
-
- private static final ClassLogger logger =
- new ClassLogger("javax.management.remote.rmi", "RMIConnector");
-
- private static final long serialVersionUID = 817323035842634473L;
-
- private RMIConnector(RMIServer rmiServer, JMXServiceURL address,
- Map<String, ?> environment) {
- if (rmiServer == null && address == null) throw new
- IllegalArgumentException("rmiServer and jmxServiceURL both null");
- initTransients();
-
- this.rmiServer = rmiServer;
- this.jmxServiceURL = address;
- if (environment == null) {
- this.env = Collections.emptyMap();
- } else {
- EnvHelp.checkAttributes(environment);
- this.env = Collections.unmodifiableMap(environment);
- }
- }
-
- /**
- * <p>Constructs an {@code RMIConnector} that will connect
- * the RMI connector server with the given address.</p>
- *
- * <p>The address can refer directly to the connector server,
- * using the following syntax:</p>
- *
- * <pre>
- * service:jmx:rmi://<em>[host[:port]]</em>/stub/<em>encoded-stub</em>
- * </pre>
- *
- * <p>(Here, the square brackets {@code []} are not part of the
- * address but indicate that the host and port are optional.)</p>
- *
- * <p>The address can instead indicate where to find an RMI stub
- * through JNDI, using the following syntax:</p>
- *
- * <pre>
- * service:jmx:rmi://<em>[host[:port]]</em>/jndi/<em>jndi-name</em>
- * </pre>
- *
- * <p>An implementation may also recognize additional address
- * syntaxes, for example:</p>
- *
- * <pre>
- * service:jmx:iiop://<em>[host[:port]]</em>/stub/<em>encoded-stub</em>
- * </pre>
- *
- * @param url the address of the RMI connector server.
- *
- * @param environment additional attributes specifying how to make
- * the connection. For JNDI-based addresses, these attributes can
- * usefully include JNDI attributes recognized by {@link
- * InitialContext#InitialContext(Hashtable) InitialContext}. This
- * parameter can be null, which is equivalent to an empty Map.
- *
- * @exception IllegalArgumentException if {@code url}
- * is null.
- */
- public RMIConnector(JMXServiceURL url, Map<String,?> environment) {
- this(null, url, environment);
- }
-
- /**
- * <p>Constructs an {@code RMIConnector} using the given RMI stub.
- *
- * @param rmiServer an RMI stub representing the RMI connector server.
- * @param environment additional attributes specifying how to make
- * the connection. This parameter can be null, which is
- * equivalent to an empty Map.
- *
- * @exception IllegalArgumentException if {@code rmiServer}
- * is null.
- */
- public RMIConnector(RMIServer rmiServer, Map<String,?> environment) {
- this(rmiServer, null, environment);
- }
-
- /**
- * <p>Returns a string representation of this object. In general,
- * the {@code toString} method returns a string that
- * "textually represents" this object. The result should be a
- * concise but informative representation that is easy for a
- * person to read.</p>
- *
- * @return a String representation of this object.
- **/
- @Override
- public String toString() {
- final StringBuilder b = new StringBuilder(this.getClass().getName());
- b.append(":");
- if (rmiServer != null) {
- b.append(" rmiServer=").append(rmiServer.toString());
- }
- if (jmxServiceURL != null) {
- if (rmiServer!=null) b.append(",");
- b.append(" jmxServiceURL=").append(jmxServiceURL.toString());
- }
- return b.toString();
- }
-
- /**
- * <p>The address of this connector.</p>
- *
- * @return the address of this connector, or null if it
- * does not have one.
- *
- * @since 1.6
- */
- public JMXServiceURL getAddress() {
- return jmxServiceURL;
- }
-
- //--------------------------------------------------------------------
- // implements JMXConnector interface
- //--------------------------------------------------------------------
-
- /**
- * @throws IOException if the connection could not be made because of a
- * communication problem
- */
- public void connect() throws IOException {
- connect(null);
- }
-
- /**
- * @throws IOException if the connection could not be made because of a
- * communication problem
- */
- public synchronized void connect(Map<String,?> environment)
- throws IOException {
- final boolean tracing = logger.traceOn();
- String idstr = (tracing?"["+this.toString()+"]":null);
-
- if (terminated) {
- logger.trace("connect",idstr + " already closed.");
- throw new IOException("Connector closed");
- }
- if (connected) {
- logger.trace("connect",idstr + " already connected.");
- return;
- }
-
- try {
- if (tracing) logger.trace("connect",idstr + " connecting...");
-
- final Map<String, Object> usemap =
- new HashMap<String, Object>((this.env==null) ?
- Collections.<String, Object>emptyMap() : this.env);
-
-
- if (environment != null) {
- EnvHelp.checkAttributes(environment);
- usemap.putAll(environment);
- }
-
- // Get RMIServer stub from directory or URL encoding if needed.
- if (tracing) logger.trace("connect",idstr + " finding stub...");
- RMIServer stub = (rmiServer!=null)?rmiServer:
- findRMIServer(jmxServiceURL, usemap);
-
- // Check for secure RMIServer stub if the corresponding
- // client-side environment property is set to "true".
- //
- String stringBoolean = (String) usemap.get("jmx.remote.x.check.stub");
- boolean checkStub = EnvHelp.computeBooleanFromString(stringBoolean);
-
- if (checkStub) checkStub(stub, rmiServerImplStubClass);
-
- if (tracing) logger.trace("connect",idstr + " connecting stub...");
- idstr = (tracing?"["+this.toString()+"]":null);
-
- // Calling newClient on the RMIServer stub.
- if (tracing)
- logger.trace("connect",idstr + " getting connection...");
- Object credentials = usemap.get(CREDENTIALS);
-
- try {
- connection = getConnection(stub, credentials, checkStub);
- } catch (java.rmi.RemoteException re) {
- throw re;
- }
-
- // Always use one of:
- // ClassLoader provided in Map at connect time,
- // or contextClassLoader at connect time.
- if (tracing)
- logger.trace("connect",idstr + " getting class loader...");
- defaultClassLoader = EnvHelp.resolveClientClassLoader(usemap);
-
- usemap.put(JMXConnectorFactory.DEFAULT_CLASS_LOADER,
- defaultClassLoader);
-
- rmiNotifClient = new RMINotifClient(defaultClassLoader, usemap);
-
- env = usemap;
- final long checkPeriod = EnvHelp.getConnectionCheckPeriod(usemap);
- communicatorAdmin = new RMIClientCommunicatorAdmin(checkPeriod);
-
- connected = true;
-
- // The connectionId variable is used in doStart(), when
- // reconnecting, to identify the "old" connection.
- //
- connectionId = getConnectionId();
-
- Notification connectedNotif =
- new JMXConnectionNotification(JMXConnectionNotification.OPENED,
- this,
- connectionId,
- clientNotifSeqNo++,
- "Successful connection",
- null);
- sendNotification(connectedNotif);
-
- if (tracing) logger.trace("connect",idstr + " done...");
- } catch (IOException e) {
- if (tracing)
- logger.trace("connect",idstr + " failed to connect: " + e);
- throw e;
- } catch (RuntimeException e) {
- if (tracing)
- logger.trace("connect",idstr + " failed to connect: " + e);
- throw e;
- } catch (NamingException e) {
- final String msg = "Failed to retrieve RMIServer stub: " + e;
- if (tracing) logger.trace("connect",idstr + " " + msg);
- throw EnvHelp.initCause(new IOException(msg),e);
- }
- }
-
- public synchronized String getConnectionId() throws IOException {
- if (terminated || !connected) {
- if (logger.traceOn())
- logger.trace("getConnectionId","["+this.toString()+
- "] not connected.");
-
- throw new IOException("Not connected");
- }
-
- // we do a remote call to have an IOException if the connection is broken.
- // see the bug 4939578
- return connection.getConnectionId();
- }
-
- public synchronized MBeanServerConnection getMBeanServerConnection()
- throws IOException {
- return getMBeanServerConnection(null);
- }
-
- public synchronized MBeanServerConnection
- getMBeanServerConnection(Subject delegationSubject)
- throws IOException {
-
- if (terminated) {
- if (logger.traceOn())
- logger.trace("getMBeanServerConnection","[" + this.toString() +
- "] already closed.");
- throw new IOException("Connection closed");
- } else if (!connected) {
- if (logger.traceOn())
- logger.trace("getMBeanServerConnection","[" + this.toString() +
- "] is not connected.");
- throw new IOException("Not connected");
- }
-
- return getConnectionWithSubject(delegationSubject);
- }
-
- public void
- addConnectionNotificationListener(NotificationListener listener,
- NotificationFilter filter,
- Object handback) {
- if (listener == null)
- throw new NullPointerException("listener");
- connectionBroadcaster.addNotificationListener(listener, filter,
- handback);
- }
-
- public void
- removeConnectionNotificationListener(NotificationListener listener)
- throws ListenerNotFoundException {
- if (listener == null)
- throw new NullPointerException("listener");
- connectionBroadcaster.removeNotificationListener(listener);
- }
-
- public void
- removeConnectionNotificationListener(NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws ListenerNotFoundException {
- if (listener == null)
- throw new NullPointerException("listener");
- connectionBroadcaster.removeNotificationListener(listener, filter,
- handback);
- }
-
- private void sendNotification(Notification n) {
- connectionBroadcaster.sendNotification(n);
- }
-
- public synchronized void close() throws IOException {
- close(false);
- }
-
- // allows to do close after setting the flag "terminated" to true.
- // It is necessary to avoid a deadlock, see 6296324
- private synchronized void close(boolean intern) throws IOException {
- final boolean tracing = logger.traceOn();
- final boolean debug = logger.debugOn();
- final String idstr = (tracing?"["+this.toString()+"]":null);
-
- if (!intern) {
- // Return if already cleanly closed.
- //
- if (terminated) {
- if (closeException == null) {
- if (tracing) logger.trace("close",idstr + " already closed.");
- return;
- }
- } else {
- terminated = true;
- }
- }
-
- if (closeException != null && tracing) {
- // Already closed, but not cleanly. Attempt again.
- //
- if (tracing) {
- logger.trace("close",idstr + " had failed: " + closeException);
- logger.trace("close",idstr + " attempting to close again.");
- }
- }
-
- String savedConnectionId = null;
- if (connected) {
- savedConnectionId = connectionId;
- }
-
- closeException = null;
-
- if (tracing) logger.trace("close",idstr + " closing.");
-
- if (communicatorAdmin != null) {
- communicatorAdmin.terminate();
- }
-
- if (rmiNotifClient != null) {
- try {
- rmiNotifClient.terminate();
- if (tracing) logger.trace("close",idstr +
- " RMI Notification client terminated.");
- } catch (RuntimeException x) {
- closeException = x;
- if (tracing) logger.trace("close",idstr +
- " Failed to terminate RMI Notification client: " + x);
- if (debug) logger.debug("close",x);
- }
- }
-
- if (connection != null) {
- try {
- connection.close();
- if (tracing) logger.trace("close",idstr + " closed.");
- } catch (NoSuchObjectException nse) {
- // OK, the server maybe closed itself.
- } catch (IOException e) {
- closeException = e;
- if (tracing) logger.trace("close",idstr +
- " Failed to close RMIServer: " + e);
- if (debug) logger.debug("close",e);
- }
- }
-
- // Clean up MBeanServerConnection table
- //
- rmbscMap.clear();
-
- /* Send notification of closure. We don't do this if the user
- * never called connect() on the connector, because there's no
- * connection id in that case. */
-
- if (savedConnectionId != null) {
- Notification closedNotif =
- new JMXConnectionNotification(JMXConnectionNotification.CLOSED,
- this,
- savedConnectionId,
- clientNotifSeqNo++,
- "Client has been closed",
- null);
- sendNotification(closedNotif);
- }
-
- // throw exception if needed
- //
- if (closeException != null) {
- if (tracing) logger.trace("close",idstr + " failed to close: " +
- closeException);
- if (closeException instanceof IOException)
- throw (IOException) closeException;
- if (closeException instanceof RuntimeException)
- throw (RuntimeException) closeException;
- final IOException x =
- new IOException("Failed to close: " + closeException);
- throw EnvHelp.initCause(x,closeException);
- }
- }
-
- // added for re-connection
- private Integer addListenerWithSubject(ObjectName name,
- MarshalledObject<NotificationFilter> filter,
- Subject delegationSubject,
- boolean reconnect)
- throws InstanceNotFoundException, IOException {
-
- final boolean debug = logger.debugOn();
- if (debug)
- logger.debug("addListenerWithSubject",
- "(ObjectName,MarshalledObject,Subject)");
-
- final ObjectName[] names = new ObjectName[] {name};
- final MarshalledObject<NotificationFilter>[] filters =
- Util.cast(new MarshalledObject<?>[] {filter});
- final Subject[] delegationSubjects = new Subject[] {
- delegationSubject
- };
-
- final Integer[] listenerIDs =
- addListenersWithSubjects(names,filters,delegationSubjects,
- reconnect);
-
- if (debug) logger.debug("addListenerWithSubject","listenerID="
- + listenerIDs[0]);
- return listenerIDs[0];
- }
-
- // added for re-connection
- private Integer[] addListenersWithSubjects(ObjectName[] names,
- MarshalledObject<NotificationFilter>[] filters,
- Subject[] delegationSubjects,
- boolean reconnect)
- throws InstanceNotFoundException, IOException {
-
- final boolean debug = logger.debugOn();
- if (debug)
- logger.debug("addListenersWithSubjects",
- "(ObjectName[],MarshalledObject[],Subject[])");
-
- final ClassLoader old = pushDefaultClassLoader();
- Integer[] listenerIDs = null;
-
- try {
- listenerIDs = connection.addNotificationListeners(names,
- filters,
- delegationSubjects);
- } catch (NoSuchObjectException noe) {
- // maybe reconnect
- if (reconnect) {
- communicatorAdmin.gotIOException(noe);
-
- listenerIDs = connection.addNotificationListeners(names,
- filters,
- delegationSubjects);
- } else {
- throw noe;
- }
- } catch (IOException ioe) {
- // send a failed notif if necessary
- communicatorAdmin.gotIOException(ioe);
- } finally {
- popDefaultClassLoader(old);
- }
-
- if (debug) logger.debug("addListenersWithSubjects","registered "
- + ((listenerIDs==null)?0:listenerIDs.length)
- + " listener(s)");
- return listenerIDs;
- }
-
- //--------------------------------------------------------------------
- // Implementation of MBeanServerConnection
- //--------------------------------------------------------------------
- private class RemoteMBeanServerConnection implements MBeanServerConnection {
- private Subject delegationSubject;
-
- public RemoteMBeanServerConnection() {
- this(null);
- }
-
- public RemoteMBeanServerConnection(Subject delegationSubject) {
- this.delegationSubject = delegationSubject;
- }
-
- public ObjectInstance createMBean(String className,
- ObjectName name)
- throws ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- IOException {
- if (logger.debugOn())
- logger.debug("createMBean(String,ObjectName)",
- "className=" + className + ", name=" +
- name);
-
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.createMBean(className,
- name,
- delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.createMBean(className,
- name,
- delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public ObjectInstance createMBean(String className,
- ObjectName name,
- ObjectName loaderName)
- throws ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- InstanceNotFoundException,
- IOException {
-
- if (logger.debugOn())
- logger.debug("createMBean(String,ObjectName,ObjectName)",
- "className=" + className + ", name="
- + name + ", loaderName="
- + loaderName + ")");
-
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.createMBean(className,
- name,
- loaderName,
- delegationSubject);
-
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.createMBean(className,
- name,
- loaderName,
- delegationSubject);
-
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public ObjectInstance createMBean(String className,
- ObjectName name,
- Object params[],
- String signature[])
- throws ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- IOException {
- if (logger.debugOn())
- logger.debug("createMBean(String,ObjectName,Object[],String[])",
- "className=" + className + ", name="
- + name + ", signature=" + strings(signature));
-
- final MarshalledObject<Object[]> sParams =
- new MarshalledObject<Object[]>(params);
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.createMBean(className,
- name,
- sParams,
- signature,
- delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.createMBean(className,
- name,
- sParams,
- signature,
- delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public ObjectInstance createMBean(String className,
- ObjectName name,
- ObjectName loaderName,
- Object params[],
- String signature[])
- throws ReflectionException,
- InstanceAlreadyExistsException,
- MBeanRegistrationException,
- MBeanException,
- NotCompliantMBeanException,
- InstanceNotFoundException,
- IOException {
- if (logger.debugOn()) logger.debug(
- "createMBean(String,ObjectName,ObjectName,Object[],String[])",
- "className=" + className + ", name=" + name + ", loaderName="
- + loaderName + ", signature=" + strings(signature));
-
- final MarshalledObject<Object[]> sParams =
- new MarshalledObject<Object[]>(params);
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.createMBean(className,
- name,
- loaderName,
- sParams,
- signature,
- delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.createMBean(className,
- name,
- loaderName,
- sParams,
- signature,
- delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public void unregisterMBean(ObjectName name)
- throws InstanceNotFoundException,
- MBeanRegistrationException,
- IOException {
- if (logger.debugOn())
- logger.debug("unregisterMBean", "name=" + name);
-
- final ClassLoader old = pushDefaultClassLoader();
- try {
- connection.unregisterMBean(name, delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- connection.unregisterMBean(name, delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public ObjectInstance getObjectInstance(ObjectName name)
- throws InstanceNotFoundException,
- IOException {
- if (logger.debugOn())
- logger.debug("getObjectInstance", "name=" + name);
-
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.getObjectInstance(name, delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.getObjectInstance(name, delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public Set<ObjectInstance> queryMBeans(ObjectName name,
- QueryExp query)
- throws IOException {
- if (logger.debugOn()) logger.debug("queryMBeans",
- "name=" + name + ", query=" + query);
-
- final MarshalledObject<QueryExp> sQuery =
- new MarshalledObject<QueryExp>(query);
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.queryMBeans(name, sQuery, delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.queryMBeans(name, sQuery, delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public Set<ObjectName> queryNames(ObjectName name,
- QueryExp query)
- throws IOException {
- if (logger.debugOn()) logger.debug("queryNames",
- "name=" + name + ", query=" + query);
-
- final MarshalledObject<QueryExp> sQuery =
- new MarshalledObject<QueryExp>(query);
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.queryNames(name, sQuery, delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.queryNames(name, sQuery, delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public boolean isRegistered(ObjectName name)
- throws IOException {
- if (logger.debugOn())
- logger.debug("isRegistered", "name=" + name);
-
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.isRegistered(name, delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.isRegistered(name, delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public Integer getMBeanCount()
- throws IOException {
- if (logger.debugOn()) logger.debug("getMBeanCount", "");
-
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.getMBeanCount(delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.getMBeanCount(delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public Object getAttribute(ObjectName name,
- String attribute)
- throws MBeanException,
- AttributeNotFoundException,
- InstanceNotFoundException,
- ReflectionException,
- IOException {
- if (logger.debugOn()) logger.debug("getAttribute",
- "name=" + name + ", attribute="
- + attribute);
-
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.getAttribute(name,
- attribute,
- delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.getAttribute(name,
- attribute,
- delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public AttributeList getAttributes(ObjectName name,
- String[] attributes)
- throws InstanceNotFoundException,
- ReflectionException,
- IOException {
- if (logger.debugOn()) logger.debug("getAttributes",
- "name=" + name + ", attributes="
- + strings(attributes));
-
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.getAttributes(name,
- attributes,
- delegationSubject);
-
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.getAttributes(name,
- attributes,
- delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
-
- public void setAttribute(ObjectName name,
- Attribute attribute)
- throws InstanceNotFoundException,
- AttributeNotFoundException,
- InvalidAttributeValueException,
- MBeanException,
- ReflectionException,
- IOException {
-
- if (logger.debugOn()) logger.debug("setAttribute",
- "name=" + name + ", attribute name="
- + attribute.getName());
-
- final MarshalledObject<Attribute> sAttribute =
- new MarshalledObject<Attribute>(attribute);
- final ClassLoader old = pushDefaultClassLoader();
- try {
- connection.setAttribute(name, sAttribute, delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- connection.setAttribute(name, sAttribute, delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public AttributeList setAttributes(ObjectName name,
- AttributeList attributes)
- throws InstanceNotFoundException,
- ReflectionException,
- IOException {
-
- if (logger.debugOn()) {
- logger.debug("setAttributes",
- "name=" + name + ", attribute names="
- + getAttributesNames(attributes));
- }
-
- final MarshalledObject<AttributeList> sAttributes =
- new MarshalledObject<AttributeList>(attributes);
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.setAttributes(name,
- sAttributes,
- delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.setAttributes(name,
- sAttributes,
- delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
-
- public Object invoke(ObjectName name,
- String operationName,
- Object params[],
- String signature[])
- throws InstanceNotFoundException,
- MBeanException,
- ReflectionException,
- IOException {
-
- if (logger.debugOn()) logger.debug("invoke",
- "name=" + name
- + ", operationName=" + operationName
- + ", signature=" + strings(signature));
-
- final MarshalledObject<Object[]> sParams =
- new MarshalledObject<Object[]>(params);
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.invoke(name,
- operationName,
- sParams,
- signature,
- delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.invoke(name,
- operationName,
- sParams,
- signature,
- delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
-
- public String getDefaultDomain()
- throws IOException {
- if (logger.debugOn()) logger.debug("getDefaultDomain", "");
-
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.getDefaultDomain(delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.getDefaultDomain(delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public String[] getDomains() throws IOException {
- if (logger.debugOn()) logger.debug("getDomains", "");
-
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.getDomains(delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.getDomains(delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public MBeanInfo getMBeanInfo(ObjectName name)
- throws InstanceNotFoundException,
- IntrospectionException,
- ReflectionException,
- IOException {
-
- if (logger.debugOn()) logger.debug("getMBeanInfo", "name=" + name);
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.getMBeanInfo(name, delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.getMBeanInfo(name, delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
-
- public boolean isInstanceOf(ObjectName name,
- String className)
- throws InstanceNotFoundException,
- IOException {
- if (logger.debugOn())
- logger.debug("isInstanceOf", "name=" + name +
- ", className=" + className);
-
- final ClassLoader old = pushDefaultClassLoader();
- try {
- return connection.isInstanceOf(name,
- className,
- delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- return connection.isInstanceOf(name,
- className,
- delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public void addNotificationListener(ObjectName name,
- ObjectName listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException,
- IOException {
-
- if (logger.debugOn())
- logger.debug("addNotificationListener" +
- "(ObjectName,ObjectName,NotificationFilter,Object)",
- "name=" + name + ", listener=" + listener
- + ", filter=" + filter + ", handback=" + handback);
-
- final MarshalledObject<NotificationFilter> sFilter =
- new MarshalledObject<NotificationFilter>(filter);
- final MarshalledObject<Object> sHandback =
- new MarshalledObject<Object>(handback);
- final ClassLoader old = pushDefaultClassLoader();
- try {
- connection.addNotificationListener(name,
- listener,
- sFilter,
- sHandback,
- delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- connection.addNotificationListener(name,
- listener,
- sFilter,
- sHandback,
- delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public void removeNotificationListener(ObjectName name,
- ObjectName listener)
- throws InstanceNotFoundException,
- ListenerNotFoundException,
- IOException {
-
- if (logger.debugOn()) logger.debug("removeNotificationListener" +
- "(ObjectName,ObjectName)",
- "name=" + name
- + ", listener=" + listener);
-
- final ClassLoader old = pushDefaultClassLoader();
- try {
- connection.removeNotificationListener(name,
- listener,
- delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- connection.removeNotificationListener(name,
- listener,
- delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- public void removeNotificationListener(ObjectName name,
- ObjectName listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException,
- ListenerNotFoundException,
- IOException {
- if (logger.debugOn())
- logger.debug("removeNotificationListener" +
- "(ObjectName,ObjectName,NotificationFilter,Object)",
- "name=" + name
- + ", listener=" + listener
- + ", filter=" + filter
- + ", handback=" + handback);
-
- final MarshalledObject<NotificationFilter> sFilter =
- new MarshalledObject<NotificationFilter>(filter);
- final MarshalledObject<Object> sHandback =
- new MarshalledObject<Object>(handback);
- final ClassLoader old = pushDefaultClassLoader();
- try {
- connection.removeNotificationListener(name,
- listener,
- sFilter,
- sHandback,
- delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- connection.removeNotificationListener(name,
- listener,
- sFilter,
- sHandback,
- delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
- }
-
- // Specific Notification Handle ----------------------------------
-
- public void addNotificationListener(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException,
- IOException {
-
- final boolean debug = logger.debugOn();
-
- if (debug)
- logger.debug("addNotificationListener" +
- "(ObjectName,NotificationListener,"+
- "NotificationFilter,Object)",
- "name=" + name
- + ", listener=" + listener
- + ", filter=" + filter
- + ", handback=" + handback);
-
- final Integer listenerID =
- addListenerWithSubject(name,
- new MarshalledObject<NotificationFilter>(filter),
- delegationSubject,true);
- rmiNotifClient.addNotificationListener(listenerID, name, listener,
- filter, handback,
- delegationSubject);
- }
-
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener)
- throws InstanceNotFoundException,
- ListenerNotFoundException,
- IOException {
-
- final boolean debug = logger.debugOn();
-
- if (debug) logger.debug("removeNotificationListener"+
- "(ObjectName,NotificationListener)",
- "name=" + name
- + ", listener=" + listener);
-
- final Integer[] ret =
- rmiNotifClient.removeNotificationListener(name, listener);
-
- if (debug) logger.debug("removeNotificationListener",
- "listenerIDs=" + objects(ret));
-
- final ClassLoader old = pushDefaultClassLoader();
-
- try {
- connection.removeNotificationListeners(name,
- ret,
- delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- connection.removeNotificationListeners(name,
- ret,
- delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
-
- }
-
- public void removeNotificationListener(ObjectName name,
- NotificationListener listener,
- NotificationFilter filter,
- Object handback)
- throws InstanceNotFoundException,
- ListenerNotFoundException,
- IOException {
- final boolean debug = logger.debugOn();
-
- if (debug)
- logger.debug("removeNotificationListener"+
- "(ObjectName,NotificationListener,"+
- "NotificationFilter,Object)",
- "name=" + name
- + ", listener=" + listener
- + ", filter=" + filter
- + ", handback=" + handback);
-
- final Integer ret =
- rmiNotifClient.removeNotificationListener(name, listener,
- filter, handback);
-
- if (debug) logger.debug("removeNotificationListener",
- "listenerID=" + ret);
-
- final ClassLoader old = pushDefaultClassLoader();
- try {
- connection.removeNotificationListeners(name,
- new Integer[] {ret},
- delegationSubject);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- connection.removeNotificationListeners(name,
- new Integer[] {ret},
- delegationSubject);
- } finally {
- popDefaultClassLoader(old);
- }
-
- }
- }
-
- //--------------------------------------------------------------------
- private class RMINotifClient extends ClientNotifForwarder {
- public RMINotifClient(ClassLoader cl, Map<String, ?> env) {
- super(cl, env);
- }
-
- protected NotificationResult fetchNotifs(long clientSequenceNumber,
- int maxNotifications,
- long timeout)
- throws IOException, ClassNotFoundException {
-
- boolean retried = false;
- while (true) { // used for a successful re-connection
- // or a transient network problem
- try {
- return connection.fetchNotifications(clientSequenceNumber,
- maxNotifications,
- timeout); // return normally
- } catch (IOException ioe) {
- // Examine the chain of exceptions to determine whether this
- // is a deserialization issue. If so - we propagate the
- // appropriate exception to the caller, who will then
- // proceed with fetching notifications one by one
- rethrowDeserializationException(ioe);
-
- try {
- communicatorAdmin.gotIOException(ioe);
- // reconnection OK, back to "while" to do again
- } catch (IOException ee) {
- boolean toClose = false;
-
- synchronized (this) {
- if (terminated) {
- // the connection is closed.
- throw ioe;
- } else if (retried) {
- toClose = true;
- }
- }
-
- if (toClose) {
- // JDK-8049303
- // We received an IOException - but the communicatorAdmin
- // did not close the connection - possibly because
- // the original exception was raised by a transient network
- // problem?
- // We already know that this exception is not due to a deserialization
- // issue as we already took care of that before involving the
- // communicatorAdmin. Moreover - we already made one retry attempt
- // at fetching the same batch of notifications - and the
- // problem persisted.
- // Since trying again doesn't seem to solve the issue, we will now
- // close the connection. Doing otherwise might cause the
- // NotifFetcher thread to die silently.
- final Notification failedNotif =
- new JMXConnectionNotification(
- JMXConnectionNotification.FAILED,
- this,
- connectionId,
- clientNotifSeqNo++,
- "Failed to communicate with the server: " + ioe.toString(),
- ioe);
-
- sendNotification(failedNotif);
-
- try {
- close(true);
- } catch (Exception e) {
- // OK.
- // We are closing
- }
- throw ioe; // the connection is closed here.
- } else {
- // JDK-8049303 possible transient network problem,
- // let's try one more time
- retried = true;
- }
- }
- }
- }
- }
-
- private void rethrowDeserializationException(IOException ioe)
- throws ClassNotFoundException, IOException {
- // specially treating for an UnmarshalException
- if (ioe instanceof UnmarshalException) {
- throw ioe; // the fix of 6937053 made ClientNotifForwarder.fetchNotifs
- // fetch one by one with UnmarshalException
- }
-
- // Not serialization problem, return.
- }
-
- protected Integer addListenerForMBeanRemovedNotif()
- throws IOException, InstanceNotFoundException {
- NotificationFilterSupport clientFilter =
- new NotificationFilterSupport();
- clientFilter.enableType(
- MBeanServerNotification.UNREGISTRATION_NOTIFICATION);
- MarshalledObject<NotificationFilter> sFilter =
- new MarshalledObject<NotificationFilter>(clientFilter);
-
- Integer[] listenerIDs;
- final ObjectName[] names =
- new ObjectName[] {MBeanServerDelegate.DELEGATE_NAME};
- final MarshalledObject<NotificationFilter>[] filters =
- Util.cast(new MarshalledObject<?>[] {sFilter});
- final Subject[] subjects = new Subject[] {null};
- try {
- listenerIDs =
- connection.addNotificationListeners(names,
- filters,
- subjects);
-
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- listenerIDs =
- connection.addNotificationListeners(names,
- filters,
- subjects);
- }
- return listenerIDs[0];
- }
-
- protected void removeListenerForMBeanRemovedNotif(Integer id)
- throws IOException, InstanceNotFoundException,
- ListenerNotFoundException {
- try {
- connection.removeNotificationListeners(
- MBeanServerDelegate.DELEGATE_NAME,
- new Integer[] {id},
- null);
- } catch (IOException ioe) {
- communicatorAdmin.gotIOException(ioe);
-
- connection.removeNotificationListeners(
- MBeanServerDelegate.DELEGATE_NAME,
- new Integer[] {id},
- null);
- }
-
- }
-
- protected void lostNotifs(String message, long number) {
- final String notifType = JMXConnectionNotification.NOTIFS_LOST;
-
- final JMXConnectionNotification n =
- new JMXConnectionNotification(notifType,
- RMIConnector.this,
- connectionId,
- clientNotifCounter++,
- message,
- Long.valueOf(number));
- sendNotification(n);
- }
- }
-
- private class RMIClientCommunicatorAdmin extends ClientCommunicatorAdmin {
- public RMIClientCommunicatorAdmin(long period) {
- super(period);
- }
-
- @Override
- public void gotIOException(IOException ioe) throws IOException {
- if (ioe instanceof NoSuchObjectException) {
- // need to restart
- super.gotIOException(ioe);
-
- return;
- }
-
- // check if the connection is broken
- try {
- connection.getDefaultDomain(null);
- } catch (IOException ioexc) {
- boolean toClose = false;
-
- synchronized(this) {
- if (!terminated) {
- terminated = true;
-
- toClose = true;
- }
- }
-
- if (toClose) {
- // we should close the connection,
- // but send a failed notif at first
- final Notification failedNotif =
- new JMXConnectionNotification(
- JMXConnectionNotification.FAILED,
- this,
- connectionId,
- clientNotifSeqNo++,
- "Failed to communicate with the server: "+ioe.toString(),
- ioe);
-
- sendNotification(failedNotif);
-
- try {
- close(true);
- } catch (Exception e) {
- // OK.
- // We are closing
- }
- }
- }
-
- // forward the exception
- if (ioe instanceof ServerException) {
- /* Need to unwrap the exception.
- Some user-thrown exception at server side will be wrapped by
- rmi into a ServerException.
- For example, a RMIConnnectorServer will wrap a
- ClassNotFoundException into a UnmarshalException, and rmi
- will throw a ServerException at client side which wraps this
- UnmarshalException.
- No failed notif here.
- */
- Throwable tt = ((ServerException)ioe).detail;
-
- if (tt instanceof IOException) {
- throw (IOException)tt;
- } else if (tt instanceof RuntimeException) {
- throw (RuntimeException)tt;
- }
- }
-
- throw ioe;
- }
-
- public void reconnectNotificationListeners(ClientListenerInfo[] old) throws IOException {
- final int len = old.length;
- int i;
-
- ClientListenerInfo[] clis = new ClientListenerInfo[len];
-
- final Subject[] subjects = new Subject[len];
- final ObjectName[] names = new ObjectName[len];
- final NotificationListener[] listeners = new NotificationListener[len];
- final NotificationFilter[] filters = new NotificationFilter[len];
- final MarshalledObject<NotificationFilter>[] mFilters =
- Util.cast(new MarshalledObject<?>[len]);
- final Object[] handbacks = new Object[len];
-
- for (i=0;i<len;i++) {
- subjects[i] = old[i].getDelegationSubject();
- names[i] = old[i].getObjectName();
- listeners[i] = old[i].getListener();
- filters[i] = old[i].getNotificationFilter();
- mFilters[i] = new MarshalledObject<NotificationFilter>(filters[i]);
- handbacks[i] = old[i].getHandback();
- }
-
- try {
- Integer[] ids = addListenersWithSubjects(names,mFilters,subjects,false);
-
- for (i=0;i<len;i++) {
- clis[i] = new ClientListenerInfo(ids[i],
- names[i],
- listeners[i],
- filters[i],
- handbacks[i],
- subjects[i]);
- }
-
- rmiNotifClient.postReconnection(clis);
-
- return;
- } catch (InstanceNotFoundException infe) {
- // OK, we will do one by one
- }
-
- int j = 0;
- for (i=0;i<len;i++) {
- try {
- Integer id = addListenerWithSubject(names[i],
- new MarshalledObject<NotificationFilter>(filters[i]),
- subjects[i],
- false);
-
- clis[j++] = new ClientListenerInfo(id,
- names[i],
- listeners[i],
- filters[i],
- handbacks[i],
- subjects[i]);
- } catch (InstanceNotFoundException infe) {
- logger.warning("reconnectNotificationListeners",
- "Can't reconnect listener for " +
- names[i]);
- }
- }
-
- if (j != len) {
- ClientListenerInfo[] tmp = clis;
- clis = new ClientListenerInfo[j];
- System.arraycopy(tmp, 0, clis, 0, j);
- }
-
- rmiNotifClient.postReconnection(clis);
- }
-
- protected void checkConnection() throws IOException {
- if (logger.debugOn())
- logger.debug("RMIClientCommunicatorAdmin-checkConnection",
- "Calling the method getDefaultDomain.");
-
- connection.getDefaultDomain(null);
- }
-
- protected void doStart() throws IOException {
- // Get RMIServer stub from directory or URL encoding if needed.
- RMIServer stub;
- try {
- stub = (rmiServer!=null)?rmiServer:
- findRMIServer(jmxServiceURL, env);
- } catch (NamingException ne) {
- throw new IOException("Failed to get a RMI stub: "+ne);
- }
-
- // Calling newClient on the RMIServer stub.
- Object credentials = env.get(CREDENTIALS);
- connection = stub.newClient(credentials);
-
- // notif issues
- final ClientListenerInfo[] old = rmiNotifClient.preReconnection();
-
- reconnectNotificationListeners(old);
-
- connectionId = getConnectionId();
-
- Notification reconnectedNotif =
- new JMXConnectionNotification(JMXConnectionNotification.OPENED,
- this,
- connectionId,
- clientNotifSeqNo++,
- "Reconnected to server",
- null);
- sendNotification(reconnectedNotif);
-
- }
-
- protected void doStop() {
- try {
- close();
- } catch (IOException ioe) {
- logger.warning("RMIClientCommunicatorAdmin-doStop",
- "Failed to call the method close():" + ioe);
- logger.debug("RMIClientCommunicatorAdmin-doStop",ioe);
- }
- }
- }
-
- //--------------------------------------------------------------------
- // Private stuff - Serialization
- //--------------------------------------------------------------------
- /**
- * Read RMIConnector fields from an {@link java.io.ObjectInputStream
- * ObjectInputStream}.
- * Calls {@code s.defaultReadObject()} and then initializes
- * all transient variables that need initializing.
- * @param s The ObjectInputStream to read from.
- * @exception InvalidObjectException if none of <var>rmiServer</var> stub
- * or <var>jmxServiceURL</var> are set.
- * @see #RMIConnector(JMXServiceURL,Map)
- * @see #RMIConnector(RMIServer,Map)
- **/
- private void readObject(java.io.ObjectInputStream s)
- throws IOException, ClassNotFoundException {
- s.defaultReadObject();
-
- if (rmiServer == null && jmxServiceURL == null) throw new
- InvalidObjectException("rmiServer and jmxServiceURL both null");
-
- initTransients();
- }
-
- /**
- * Writes the RMIConnector fields to an {@link java.io.ObjectOutputStream
- * ObjectOutputStream}.
- * <p>Connects the underlying RMIServer stub to an ORB, if needed,
- * before serializing it. This is done using the environment
- * map that was provided to the constructor, if any, and as documented
- * in {@link javax.management.remote.rmi}.</p>
- * <p>This method then calls {@code s.defaultWriteObject()}.
- * Usually, <var>rmiServer</var> is null if this object
- * was constructed with a JMXServiceURL, and <var>jmxServiceURL</var>
- * is null if this object is constructed with a RMIServer stub.
- * <p>Note that the environment Map is not serialized, since the objects
- * it contains are assumed to be contextual and relevant only
- * with respect to the local environment (class loader, ORB, etc...).</p>
- * <p>After an RMIConnector is deserialized, it is assumed that the
- * user will call {@link #connect(Map)}, providing a new Map that
- * can contain values which are contextually relevant to the new
- * local environment.</p>
- * <p>Since connection to the ORB is needed prior to serializing, and
- * since the ORB to connect to is one of those contextual parameters,
- * it is not recommended to re-serialize a just de-serialized object -
- * as the de-serialized object has no map. Thus, when an RMIConnector
- * object is needed for serialization or transmission to a remote
- * application, it is recommended to obtain a new RMIConnector stub
- * by calling {@link RMIConnectorServer#toJMXConnector(Map)}.</p>
- * @param s The ObjectOutputStream to write to.
- * @exception InvalidObjectException if none of <var>rmiServer</var> stub
- * or <var>jmxServiceURL</var> are set.
- * @see #RMIConnector(JMXServiceURL,Map)
- * @see #RMIConnector(RMIServer,Map)
- **/
- private void writeObject(java.io.ObjectOutputStream s)
- throws IOException {
- if (rmiServer == null && jmxServiceURL == null) throw new
- InvalidObjectException("rmiServer and jmxServiceURL both null.");
- s.defaultWriteObject();
- }
-
- // Initialization of transient variables.
- private void initTransients() {
- rmbscMap = new WeakHashMap<Subject, WeakReference<MBeanServerConnection>>();
- connected = false;
- terminated = false;
-
- connectionBroadcaster = new NotificationBroadcasterSupport();
- }
-
- //--------------------------------------------------------------------
- // Private stuff - Check if stub can be trusted.
- //--------------------------------------------------------------------
-
- private static void checkStub(Remote stub,
- Class<?> stubClass) {
-
- // Check remote stub is from the expected class.
- //
- if (stub.getClass() != stubClass) {
- if (!Proxy.isProxyClass(stub.getClass())) {
- throw new SecurityException(
- "Expecting a " + stubClass.getName() + " stub!");
- } else {
- InvocationHandler handler = Proxy.getInvocationHandler(stub);
- if (handler.getClass() != RemoteObjectInvocationHandler.class)
- throw new SecurityException(
- "Expecting a dynamic proxy instance with a " +
- RemoteObjectInvocationHandler.class.getName() +
- " invocation handler!");
- else
- stub = (Remote) handler;
- }
- }
-
- // Check RemoteRef in stub is from the expected class
- // "sun.rmi.server.UnicastRef2".
- //
- RemoteRef ref = ((RemoteObject)stub).getRef();
- if (ref.getClass() != UnicastRef2.class)
- throw new SecurityException(
- "Expecting a " + UnicastRef2.class.getName() +
- " remote reference in stub!");
-
- // Check RMIClientSocketFactory in stub is from the expected class
- // "javax.rmi.ssl.SslRMIClientSocketFactory".
- //
- LiveRef liveRef = ((UnicastRef2)ref).getLiveRef();
- RMIClientSocketFactory csf = liveRef.getClientSocketFactory();
- if (csf == null || csf.getClass() != SslRMIClientSocketFactory.class)
- throw new SecurityException(
- "Expecting a " + SslRMIClientSocketFactory.class.getName() +
- " RMI client socket factory in stub!");
- }
-
- //--------------------------------------------------------------------
- // Private stuff - RMIServer creation
- //--------------------------------------------------------------------
-
- private RMIServer findRMIServer(JMXServiceURL directoryURL,
- Map<String, Object> environment)
- throws NamingException, IOException {
-
- String path = directoryURL.getURLPath();
- int end = path.indexOf(';');
- if (end < 0) end = path.length();
- if (path.startsWith("/jndi/"))
- return findRMIServerJNDI(path.substring(6,end), environment);
- else if (path.startsWith("/stub/"))
- return findRMIServerJRMP(path.substring(6,end), environment);
- else {
- final String msg = "URL path must begin with /jndi/ or /stub/ " +
- "or /ior/: " + path;
- throw new MalformedURLException(msg);
- }
- }
-
- /**
- * Lookup the RMIServer stub in a directory.
- * @param jndiURL A JNDI URL indicating the location of the Stub
- * (see {@link javax.management.remote.rmi}), e.g.:
- * <ul><li>{@code rmi://registry-host:port/rmi-stub-name}</li>
- * <li>or {@code ldap://ldap-host:port/java-container-dn}</li>
- * </ul>
- * @param env the environment Map passed to the connector.
- * @return The retrieved RMIServer stub.
- * @exception NamingException if the stub couldn't be found.
- **/
- private RMIServer findRMIServerJNDI(String jndiURL, Map<String, ?> env)
- throws NamingException {
-
- InitialContext ctx = new InitialContext(EnvHelp.mapToHashtable(env));
-
- Object objref = ctx.lookup(jndiURL);
- ctx.close();
-
- return narrowJRMPServer(objref);
- }
-
- private static RMIServer narrowJRMPServer(Object objref) {
-
- return (RMIServer) objref;
- }
-
- private RMIServer findRMIServerJRMP(String base64, Map<String, ?> env)
- throws IOException {
- final byte[] serialized;
- try {
- serialized = base64ToByteArray(base64);
- } catch (IllegalArgumentException e) {
- throw new MalformedURLException("Bad BASE64 encoding: " +
- e.getMessage());
- }
- final ByteArrayInputStream bin = new ByteArrayInputStream(serialized);
-
- final ClassLoader loader = EnvHelp.resolveClientClassLoader(env);
- final ObjectInputStream oin =
- (loader == null) ?
- new ObjectInputStream(bin) :
- new ObjectInputStreamWithLoader(bin, loader);
- final Object stub;
- try {
- stub = oin.readObject();
- } catch (ClassNotFoundException e) {
- throw new MalformedURLException("Class not found: " + e);
- }
- return (RMIServer)stub;
- }
-
- private static final class ObjectInputStreamWithLoader
- extends ObjectInputStream {
- ObjectInputStreamWithLoader(InputStream in, ClassLoader cl)
- throws IOException, IllegalArgumentException {
- super(in);
- if (cl == null ) {
- throw new IllegalArgumentException("class loader is null");
- }
- this.loader = cl;
- }
-
- @Override
- protected Class<?> resolveClass(ObjectStreamClass classDesc)
- throws IOException, ClassNotFoundException {
- String name = classDesc.getName();
- ReflectUtil.checkPackageAccess(name);
- return Class.forName(name, false, Objects.requireNonNull(loader));
- }
-
- private final ClassLoader loader;
- }
-
- private MBeanServerConnection getConnectionWithSubject(Subject delegationSubject) {
- MBeanServerConnection conn = null;
-
- if (delegationSubject == null) {
- if (nullSubjectConnRef == null
- || (conn = nullSubjectConnRef.get()) == null) {
- conn = new RemoteMBeanServerConnection(null);
- nullSubjectConnRef = new WeakReference<MBeanServerConnection>(conn);
- }
- } else {
- WeakReference<MBeanServerConnection> wr = rmbscMap.get(delegationSubject);
- if (wr == null || (conn = wr.get()) == null) {
- conn = new RemoteMBeanServerConnection(delegationSubject);
- rmbscMap.put(delegationSubject, new WeakReference<MBeanServerConnection>(conn));
- }
- }
- return conn;
- }
-
- /*
- The following section of code avoids a class loading problem
- with RMI. The problem is that an RMI stub, when deserializing
- a remote method return value or exception, will first of all
- consult the first non-bootstrap class loader it finds in the
- call stack. This can lead to behavior that is not portable
- between implementations of the JMX Remote API. Notably, an
- implementation on J2SE 1.4 will find the RMI stub's loader on
- the stack. But in J2SE 5, this stub is loaded by the
- bootstrap loader, so RMI will find the loader of the user code
- that called an MBeanServerConnection method.
-
- To avoid this problem, we take advantage of what the RMI stub
- is doing internally. Each remote call will end up calling
- ref.invoke(...), where ref is the RemoteRef parameter given to
- the RMI stub's constructor. It is within this call that the
- deserialization will happen. So we fabricate our own RemoteRef
- that delegates everything to the "real" one but that is loaded
- by a class loader that knows no other classes. The class
- loader NoCallStackClassLoader does this: the RemoteRef is an
- instance of the class named by proxyRefClassName, which is
- fabricated by the class loader using byte code that is defined
- by the string below.
-
- The call stack when the deserialization happens is thus this:
- MBeanServerConnection.getAttribute (or whatever)
- -> RMIConnectionImpl_Stub.getAttribute
- -> ProxyRef.invoke(...getAttribute...)
- -> UnicastRef.invoke(...getAttribute...)
- -> internal RMI stuff
-
- Here UnicastRef is the RemoteRef created when the stub was
- deserialized (which is of some RMI internal class). It and the
- "internal RMI stuff" are loaded by the bootstrap loader, so are
- transparent to the stack search. The first non-bootstrap
- loader found is our ProxyRefLoader, as required.
-
- In a future version of this code as integrated into J2SE 5,
- this workaround could be replaced by direct access to the
- internals of RMI. For now, we use the same code base for J2SE
- and for the standalone Reference Implementation.
-
- The byte code below encodes the following class, compiled using
- J2SE 1.4.2 with the -g:none option.
-
- package com.sun.jmx.remote.internal;
-
- import java.lang.reflect.Method;
- import java.rmi.Remote;
- import java.rmi.server.RemoteRef;
- import com.sun.jmx.remote.internal.ProxyRef;
-
- public class PRef extends ProxyRef {
- public PRef(RemoteRef ref) {
- super(ref);
- }
-
- public Object invoke(Remote obj, Method method,
- Object[] params, long opnum)
- throws Exception {
- return ref.invoke(obj, method, params, opnum);
- }
- }
- */
-
- private static final String rmiServerImplStubClassName =
- RMIServer.class.getName() + "Impl_Stub";
- private static final Class<?> rmiServerImplStubClass;
- private static final String rmiConnectionImplStubClassName =
- RMIConnection.class.getName() + "Impl_Stub";
- private static final Class<?> rmiConnectionImplStubClass;
- private static final String pRefClassName =
- "jdk.jmx.remote.internal.PRef";
- private static final Constructor<?> proxyRefConstructor;
- static {
- final String pRefByteCodeString =
- "\312\376\272\276\0\0\0\60\0\27\12\0\5\0\15\11\0\4\0\16\13\0\17"+
- "\0\20\7\0\21\7\0\22\1\0\6<init>\1\0\36(Ljava/rmi/server/Remote"+
- "Ref;)V\1\0\4Code\1\0\6invoke\1\0S(Ljava/rmi/Remote;Ljava/lang/"+
- "reflect/Method;[Ljava/lang/Object;J)Ljava/lang/Object;\1\0\12E"+
- "xceptions\7\0\23\14\0\6\0\7\14\0\24\0\25\7\0\26\14\0\11\0\12\1"+
- "\0\34jdk/jmx/remote/internal/PRef\1\0$com/sun/jmx/remote/inter"+
- "nal/ProxyRef\1\0\23java/lang/Exception\1\0\3ref\1\0\33Ljava/rm"+
- "i/server/RemoteRef;\1\0\31java/rmi/server/RemoteRef\0!\0\4\0\5"+
- "\0\0\0\0\0\2\0\1\0\6\0\7\0\1\0\10\0\0\0\22\0\2\0\2\0\0\0\6*+\267"+
- "\0\1\261\0\0\0\0\0\1\0\11\0\12\0\2\0\10\0\0\0\33\0\6\0\6\0\0\0"+
- "\17*\264\0\2+,-\26\4\271\0\3\6\0\260\0\0\0\0\0\13\0\0\0\4\0\1\0"+
- "\14\0\0";
- final byte[] pRefByteCode =
- NoCallStackClassLoader.stringToBytes(pRefByteCodeString);
- PrivilegedExceptionAction<Constructor<?>> action =
- new PrivilegedExceptionAction<Constructor<?>>() {
- public Constructor<?> run() throws Exception {
- Class<RMIConnector> thisClass = RMIConnector.class;
- ClassLoader thisLoader = thisClass.getClassLoader();
- ProtectionDomain thisProtectionDomain =
- thisClass.getProtectionDomain();
-
- String proxyRefCName = ProxyRef.class.getName();
- ClassLoader cl =
- new NoCallStackClassLoader(pRefClassName,
- pRefByteCode,
- new String[] { proxyRefCName },
- thisLoader,
- thisProtectionDomain);
-
- Module jmxModule = ProxyRef.class.getModule();
- Module rmiModule = RemoteRef.class.getModule();
-
- String pkg = packageOf(pRefClassName);
- assert pkg != null && pkg.length() > 0 && !pkg.equals(packageOf(proxyRefCName));
- Module m = Modules.defineModule(cl, "jdk.remoteref", Collections.singleton(pkg));
-
- // jdk.remoteref needs to read to java.base and jmxModule
- Modules.addReads(m, Object.class.getModule());
- Modules.addReads(m, jmxModule);
- Modules.addReads(m, rmiModule);
-
- // jdk.remoteref needs access to ProxyRef class
- Modules.addExports(jmxModule, packageOf(proxyRefCName), m);
-
- // java.management needs to instantiate the fabricated RemoteRef class
- Modules.addReads(jmxModule, m);
- Modules.addExports(m, pkg, jmxModule);
-
- Class<?> c = cl.loadClass(pRefClassName);
- return c.getConstructor(RemoteRef.class);
- }
- };
-
- Class<?> serverStubClass;
- try {
- serverStubClass = Class.forName(rmiServerImplStubClassName);
- } catch (Exception e) {
- logger.error("<clinit>",
- "Failed to instantiate " +
- rmiServerImplStubClassName + ": " + e);
- logger.debug("<clinit>",e);
- serverStubClass = null;
- }
- rmiServerImplStubClass = serverStubClass;
-
- Class<?> stubClass;
- Constructor<?> constr;
- try {
- stubClass = Class.forName(rmiConnectionImplStubClassName);
- constr = (Constructor<?>) AccessController.doPrivileged(action);
- } catch (Exception e) {
- logger.error("<clinit>",
- "Failed to initialize proxy reference constructor "+
- "for " + rmiConnectionImplStubClassName + ": " + e);
- logger.debug("<clinit>",e);
- stubClass = null;
- constr = null;
- }
- rmiConnectionImplStubClass = stubClass;
- proxyRefConstructor = constr;
- }
-
- private static String packageOf(String cn) {
- int i = cn.lastIndexOf('.');
- return i > 0 ? cn.substring(0, i) : "";
- }
-
- private static RMIConnection shadowJrmpStub(RemoteObject stub)
- throws InstantiationException, IllegalAccessException,
- InvocationTargetException, ClassNotFoundException,
- NoSuchMethodException {
- RemoteRef ref = stub.getRef();
- RemoteRef proxyRef = (RemoteRef)
- proxyRefConstructor.newInstance(new Object[] {ref});
- final Constructor<?> rmiConnectionImplStubConstructor =
- rmiConnectionImplStubClass.getConstructor(RemoteRef.class);
- Object[] args = {proxyRef};
- RMIConnection proxyStub = (RMIConnection)
- rmiConnectionImplStubConstructor.newInstance(args);
- return proxyStub;
- }
-
- private static RMIConnection getConnection(RMIServer server,
- Object credentials,
- boolean checkStub)
- throws IOException {
- RMIConnection c = server.newClient(credentials);
- if (checkStub) checkStub(c, rmiConnectionImplStubClass);
- try {
- if (c.getClass() == rmiConnectionImplStubClass)
- return shadowJrmpStub((RemoteObject) c);
- logger.trace("getConnection",
- "Did not wrap " + c.getClass() + " to foil " +
- "stack search for classes: class loading semantics " +
- "may be incorrect");
- } catch (Exception e) {
- logger.error("getConnection",
- "Could not wrap " + c.getClass() + " to foil " +
- "stack search for classes: class loading semantics " +
- "may be incorrect: " + e);
- logger.debug("getConnection",e);
- // so just return the original stub, which will work for all
- // but the most exotic class loading situations
- }
- return c;
- }
-
- private static byte[] base64ToByteArray(String s) {
- int sLen = s.length();
- int numGroups = sLen/4;
- if (4*numGroups != sLen)
- throw new IllegalArgumentException(
- "String length must be a multiple of four.");
- int missingBytesInLastGroup = 0;
- int numFullGroups = numGroups;
- if (sLen != 0) {
- if (s.charAt(sLen-1) == '=') {
- missingBytesInLastGroup++;
- numFullGroups--;
- }
- if (s.charAt(sLen-2) == '=')
- missingBytesInLastGroup++;
- }
- byte[] result = new byte[3*numGroups - missingBytesInLastGroup];
-
- // Translate all full groups from base64 to byte array elements
- int inCursor = 0, outCursor = 0;
- for (int i=0; i<numFullGroups; i++) {
- int ch0 = base64toInt(s.charAt(inCursor++));
- int ch1 = base64toInt(s.charAt(inCursor++));
- int ch2 = base64toInt(s.charAt(inCursor++));
- int ch3 = base64toInt(s.charAt(inCursor++));
- result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
- result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
- result[outCursor++] = (byte) ((ch2 << 6) | ch3);
- }
-
- // Translate partial group, if present
- if (missingBytesInLastGroup != 0) {
- int ch0 = base64toInt(s.charAt(inCursor++));
- int ch1 = base64toInt(s.charAt(inCursor++));
- result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4));
-
- if (missingBytesInLastGroup == 1) {
- int ch2 = base64toInt(s.charAt(inCursor++));
- result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2));
- }
- }
- // assert inCursor == s.length()-missingBytesInLastGroup;
- // assert outCursor == result.length;
- return result;
- }
-
- /**
- * Translates the specified character, which is assumed to be in the
- * "Base 64 Alphabet" into its equivalent 6-bit positive integer.
- *
- * @throws IllegalArgumentException if
- * c is not in the Base64 Alphabet.
- */
- private static int base64toInt(char c) {
- int result;
-
- if (c >= base64ToInt.length)
- result = -1;
- else
- result = base64ToInt[c];
-
- if (result < 0)
- throw new IllegalArgumentException("Illegal character " + c);
- return result;
- }
-
- /**
- * This array is a lookup table that translates unicode characters
- * drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045)
- * into their 6-bit positive integer equivalents. Characters that
- * are not in the Base64 alphabet but fall within the bounds of the
- * array are translated to -1.
- */
- private static final byte base64ToInt[] = {
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4,
- 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34,
- 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
- };
-
- //--------------------------------------------------------------------
- // Private stuff - Find / Set default class loader
- //--------------------------------------------------------------------
- private ClassLoader pushDefaultClassLoader() {
- final Thread t = Thread.currentThread();
- final ClassLoader old = t.getContextClassLoader();
- if (defaultClassLoader != null)
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- t.setContextClassLoader(defaultClassLoader);
- return null;
- }
- });
- return old;
- }
-
- private void popDefaultClassLoader(final ClassLoader old) {
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- public Void run() {
- Thread.currentThread().setContextClassLoader(old);
- return null;
- }
- });
- }
-
- //--------------------------------------------------------------------
- // Private variables
- //--------------------------------------------------------------------
- /**
- * @serial The RMIServer stub of the RMI JMX Connector server to
- * which this client connector is (or will be) connected. This
- * field can be null when <var>jmxServiceURL</var> is not
- * null. This includes the case where <var>jmxServiceURL</var>
- * contains a serialized RMIServer stub. If both
- * <var>rmiServer</var> and <var>jmxServiceURL</var> are null then
- * serialization will fail.
- *
- * @see #RMIConnector(RMIServer,Map)
- **/
- private final RMIServer rmiServer;
-
- /**
- * @serial The JMXServiceURL of the RMI JMX Connector server to
- * which this client connector will be connected. This field can
- * be null when <var>rmiServer</var> is not null. If both
- * <var>rmiServer</var> and <var>jmxServiceURL</var> are null then
- * serialization will fail.
- *
- * @see #RMIConnector(JMXServiceURL,Map)
- **/
- private final JMXServiceURL jmxServiceURL;
-
- // ---------------------------------------------------------
- // WARNING - WARNING - WARNING - WARNING - WARNING - WARNING
- // ---------------------------------------------------------
- // Any transient variable which needs to be initialized should
- // be initialized in the method initTransient()
- private transient Map<String, Object> env;
- private transient ClassLoader defaultClassLoader;
- private transient RMIConnection connection;
- private transient String connectionId;
-
- private transient long clientNotifSeqNo = 0;
-
- private transient WeakHashMap<Subject, WeakReference<MBeanServerConnection>> rmbscMap;
- private transient WeakReference<MBeanServerConnection> nullSubjectConnRef = null;
-
- private transient RMINotifClient rmiNotifClient;
- // = new RMINotifClient(new Integer(0));
-
- private transient long clientNotifCounter = 0;
-
- private transient boolean connected;
- // = false;
- private transient boolean terminated;
- // = false;
-
- private transient Exception closeException;
-
- private transient NotificationBroadcasterSupport connectionBroadcaster;
-
- private transient ClientCommunicatorAdmin communicatorAdmin;
-
- /**
- * A static WeakReference to an {@link org.omg.CORBA.ORB ORB} to
- * connect unconnected stubs.
- **/
- private static volatile WeakReference<Object> orb = null;
-
- // TRACES & DEBUG
- //---------------
- private static String objects(final Object[] objs) {
- if (objs == null)
- return "null";
- else
- return Arrays.asList(objs).toString();
- }
-
- private static String strings(final String[] strs) {
- return objects(strs);
- }
-
- static String getAttributesNames(AttributeList attributes) {
- return attributes != null ?
- attributes.asList().stream()
- .map(Attribute::getName)
- .collect(Collectors.joining(", ", "[", "]"))
- : "[]";
- }
-}
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectorServer.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,819 +0,0 @@
-/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javax.management.remote.rmi;
-
-
-import com.sun.jmx.remote.security.MBeanServerFileAccessController;
-import com.sun.jmx.remote.util.ClassLogger;
-import com.sun.jmx.remote.util.EnvHelp;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-import java.net.MalformedURLException;
-import java.rmi.server.RMIClientSocketFactory;
-import java.rmi.server.RMIServerSocketFactory;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Map;
-import java.util.Set;
-
-import javax.management.InstanceNotFoundException;
-import javax.management.MBeanServer;
-import javax.management.remote.JMXAuthenticator;
-
-import javax.management.remote.JMXConnectionNotification;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.MBeanServerForwarder;
-
-import javax.naming.InitialContext;
-import javax.naming.NamingException;
-
-/**
- * <p>A JMX API connector server that creates RMI-based connections
- * from remote clients. Usually, such connector servers are made
- * using {@link javax.management.remote.JMXConnectorServerFactory
- * JMXConnectorServerFactory}. However, specialized applications can
- * use this class directly, for example with an {@link RMIServerImpl}
- * object.</p>
- *
- * @since 1.5
- */
-public class RMIConnectorServer extends JMXConnectorServer {
- /**
- * <p>Name of the attribute that specifies whether the {@link
- * RMIServer} stub that represents an RMI connector server should
- * override an existing stub at the same address. The value
- * associated with this attribute, if any, should be a string that
- * is equal, ignoring case, to <code>"true"</code> or
- * <code>"false"</code>. The default value is false.</p>
- */
- public static final String JNDI_REBIND_ATTRIBUTE =
- "jmx.remote.jndi.rebind";
-
- /**
- * <p>Name of the attribute that specifies the {@link
- * RMIClientSocketFactory} for the RMI objects created in
- * conjunction with this connector. The value associated with this
- * attribute must be of type <code>RMIClientSocketFactory</code> and can
- * only be specified in the <code>Map</code> argument supplied when
- * creating a connector server.</p>
- */
- public static final String RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE =
- "jmx.remote.rmi.client.socket.factory";
-
- /**
- * <p>Name of the attribute that specifies the {@link
- * RMIServerSocketFactory} for the RMI objects created in
- * conjunction with this connector. The value associated with this
- * attribute must be of type <code>RMIServerSocketFactory</code> and can
- * only be specified in the <code>Map</code> argument supplied when
- * creating a connector server.</p>
- */
- public static final String RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE =
- "jmx.remote.rmi.server.socket.factory";
-
- /**
- * Name of the attribute that specifies a list of class names acceptable
- * as parameters to the {@link RMIServer#newClient(java.lang.Object) RMIServer.newClient()}
- * remote method call.
- * <p>
- * This list of classes should correspond to the transitive closure of the
- * credentials class (or classes) used by the installed {@linkplain JMXAuthenticator}
- * associated with the {@linkplain RMIServer} implementation.
- * <p>
- * If the attribute is not set, or is null, then any class is
- * deemed acceptable.
- */
- public static final String CREDENTIAL_TYPES =
- "jmx.remote.rmi.server.credential.types";
-
- /**
- * <p>Makes an <code>RMIConnectorServer</code>.
- * This is equivalent to calling {@link #RMIConnectorServer(
- * JMXServiceURL,Map,RMIServerImpl,MBeanServer)
- * RMIConnectorServer(directoryURL,environment,null,null)}</p>
- *
- * @param url the URL defining how to create the connector server.
- * Cannot be null.
- *
- * @param environment attributes governing the creation and
- * storing of the RMI object. Can be null, which is equivalent to
- * an empty Map.
- *
- * @exception IllegalArgumentException if <code>url</code> is null.
- *
- * @exception MalformedURLException if <code>url</code> does not
- * conform to the syntax for an RMI connector, or if its protocol
- * is not recognized by this implementation. Only "rmi" is valid when
- * this constructor is used.
- *
- * @exception IOException if the connector server cannot be created
- * for some reason or if it is inevitable that its {@link #start()
- * start} method will fail.
- */
- public RMIConnectorServer(JMXServiceURL url, Map<String,?> environment)
- throws IOException {
- this(url, environment, (MBeanServer) null);
- }
-
- /**
- * <p>Makes an <code>RMIConnectorServer</code> for the given MBean
- * server.
- * This is equivalent to calling {@link #RMIConnectorServer(
- * JMXServiceURL,Map,RMIServerImpl,MBeanServer)
- * RMIConnectorServer(directoryURL,environment,null,mbeanServer)}</p>
- *
- * @param url the URL defining how to create the connector server.
- * Cannot be null.
- *
- * @param environment attributes governing the creation and
- * storing of the RMI object. Can be null, which is equivalent to
- * an empty Map.
- *
- * @param mbeanServer the MBean server to which the new connector
- * server is attached, or null if it will be attached by being
- * registered as an MBean in the MBean server.
- *
- * @exception IllegalArgumentException if <code>url</code> is null.
- *
- * @exception MalformedURLException if <code>url</code> does not
- * conform to the syntax for an RMI connector, or if its protocol
- * is not recognized by this implementation. Only "rmi" is valid
- * when this constructor is used.
- *
- * @exception IOException if the connector server cannot be created
- * for some reason or if it is inevitable that its {@link #start()
- * start} method will fail.
- */
- public RMIConnectorServer(JMXServiceURL url, Map<String,?> environment,
- MBeanServer mbeanServer)
- throws IOException {
- this(url, environment, (RMIServerImpl) null, mbeanServer);
- }
-
- /**
- * <p>Makes an <code>RMIConnectorServer</code> for the given MBean
- * server.</p>
- *
- * @param url the URL defining how to create the connector server.
- * Cannot be null.
- *
- * @param environment attributes governing the creation and
- * storing of the RMI object. Can be null, which is equivalent to
- * an empty Map.
- *
- * @param rmiServerImpl An implementation of the RMIServer interface,
- * consistent with the protocol type specified in <var>url</var>.
- * If this parameter is non null, the protocol type specified by
- * <var>url</var> is not constrained, and is assumed to be valid.
- * Otherwise, only "rmi" will be recognized.
- *
- * @param mbeanServer the MBean server to which the new connector
- * server is attached, or null if it will be attached by being
- * registered as an MBean in the MBean server.
- *
- * @exception IllegalArgumentException if <code>url</code> is null.
- *
- * @exception MalformedURLException if <code>url</code> does not
- * conform to the syntax for an RMI connector, or if its protocol
- * is not recognized by this implementation. Only "rmi" is recognized
- * when <var>rmiServerImpl</var> is null.
- *
- * @exception IOException if the connector server cannot be created
- * for some reason or if it is inevitable that its {@link #start()
- * start} method will fail.
- *
- * @see #start
- */
- public RMIConnectorServer(JMXServiceURL url, Map<String,?> environment,
- RMIServerImpl rmiServerImpl,
- MBeanServer mbeanServer)
- throws IOException {
- super(mbeanServer);
-
- if (url == null) throw new
- IllegalArgumentException("Null JMXServiceURL");
- if (rmiServerImpl == null) {
- final String prt = url.getProtocol();
- if (prt == null || !(prt.equals("rmi"))) {
- final String msg = "Invalid protocol type: " + prt;
- throw new MalformedURLException(msg);
- }
- final String urlPath = url.getURLPath();
- if (!urlPath.equals("")
- && !urlPath.equals("/")
- && !urlPath.startsWith("/jndi/")) {
- final String msg = "URL path must be empty or start with " +
- "/jndi/";
- throw new MalformedURLException(msg);
- }
- }
-
- if (environment == null)
- this.attributes = Collections.emptyMap();
- else {
- EnvHelp.checkAttributes(environment);
- this.attributes = Collections.unmodifiableMap(environment);
- }
-
- this.address = url;
- this.rmiServerImpl = rmiServerImpl;
- }
-
- /**
- * <p>Returns a client stub for this connector server. A client
- * stub is a serializable object whose {@link
- * JMXConnector#connect(Map) connect} method can be used to make
- * one new connection to this connector server.</p>
- *
- * @param env client connection parameters of the same sort that
- * could be provided to {@link JMXConnector#connect(Map)
- * JMXConnector.connect(Map)}. Can be null, which is equivalent
- * to an empty map.
- *
- * @return a client stub that can be used to make a new connection
- * to this connector server.
- *
- * @exception UnsupportedOperationException if this connector
- * server does not support the generation of client stubs.
- *
- * @exception IllegalStateException if the JMXConnectorServer is
- * not started (see {@link #isActive()}).
- *
- * @exception IOException if a communications problem means that a
- * stub cannot be created.
- **/
- public JMXConnector toJMXConnector(Map<String,?> env) throws IOException {
- // The serialized for of rmiServerImpl is automatically
- // a RMI server stub.
- if (!isActive()) throw new
- IllegalStateException("Connector is not active");
-
- // Merge maps
- Map<String, Object> usemap = new HashMap<String, Object>(
- (this.attributes==null)?Collections.<String, Object>emptyMap():
- this.attributes);
-
- if (env != null) {
- EnvHelp.checkAttributes(env);
- usemap.putAll(env);
- }
-
- usemap = EnvHelp.filterAttributes(usemap);
-
- final RMIServer stub=(RMIServer)rmiServerImpl.toStub();
-
- return new RMIConnector(stub, usemap);
- }
-
- /**
- * <p>Activates the connector server, that is starts listening for
- * client connections. Calling this method when the connector
- * server is already active has no effect. Calling this method
- * when the connector server has been stopped will generate an
- * <code>IOException</code>.</p>
- *
- * <p>The behavior of this method when called for the first time
- * depends on the parameters that were supplied at construction,
- * as described below.</p>
- *
- * <p>First, an object of a subclass of {@link RMIServerImpl} is
- * required, to export the connector server through RMI:</p>
- *
- * <ul>
- *
- * <li>If an <code>RMIServerImpl</code> was supplied to the
- * constructor, it is used.
- *
- * <li>Otherwise, if the <code>JMXServiceURL</code>
- * was null, or its protocol part was <code>rmi</code>, an object
- * of type {@link RMIJRMPServerImpl} is created.
- *
- * <li>Otherwise, the implementation can create an
- * implementation-specific {@link RMIServerImpl} or it can throw
- * {@link MalformedURLException}.
- *
- * </ul>
- *
- * <p>If the given address includes a JNDI directory URL as
- * specified in the package documentation for {@link
- * javax.management.remote.rmi}, then this
- * <code>RMIConnectorServer</code> will bootstrap by binding the
- * <code>RMIServerImpl</code> to the given address.</p>
- *
- * <p>If the URL path part of the <code>JMXServiceURL</code> was
- * empty or a single slash (<code>/</code>), then the RMI object
- * will not be bound to a directory. Instead, a reference to it
- * will be encoded in the URL path of the RMIConnectorServer
- * address (returned by {@link #getAddress()}). The encodings for
- * <code>rmi</code> are described in the package documentation for
- * {@link javax.management.remote.rmi}.</p>
- *
- * <p>The behavior when the URL path is neither empty nor a JNDI
- * directory URL, or when the protocol is not <code>rmi</code>,
- * is implementation defined, and may include throwing
- * {@link MalformedURLException} when the connector server is created
- * or when it is started.</p>
- *
- * @exception IllegalStateException if the connector server has
- * not been attached to an MBean server.
- * @exception IOException if the connector server cannot be
- * started.
- */
- public synchronized void start() throws IOException {
- final boolean tracing = logger.traceOn();
-
- if (state == STARTED) {
- if (tracing) logger.trace("start", "already started");
- return;
- } else if (state == STOPPED) {
- if (tracing) logger.trace("start", "already stopped");
- throw new IOException("The server has been stopped.");
- }
-
- if (getMBeanServer() == null)
- throw new IllegalStateException("This connector server is not " +
- "attached to an MBean server");
-
- // Check the internal access file property to see
- // if an MBeanServerForwarder is to be provided
- //
- if (attributes != null) {
- // Check if access file property is specified
- //
- String accessFile =
- (String) attributes.get("jmx.remote.x.access.file");
- if (accessFile != null) {
- // Access file property specified, create an instance
- // of the MBeanServerFileAccessController class
- //
- MBeanServerForwarder mbsf;
- try {
- mbsf = new MBeanServerFileAccessController(accessFile);
- } catch (IOException e) {
- throw EnvHelp.initCause(
- new IllegalArgumentException(e.getMessage()), e);
- }
- // Set the MBeanServerForwarder
- //
- setMBeanServerForwarder(mbsf);
- }
- }
-
- try {
- if (tracing) logger.trace("start", "setting default class loader");
- defaultClassLoader = EnvHelp.resolveServerClassLoader(
- attributes, getMBeanServer());
- } catch (InstanceNotFoundException infc) {
- IllegalArgumentException x = new
- IllegalArgumentException("ClassLoader not found: "+infc);
- throw EnvHelp.initCause(x,infc);
- }
-
- if (tracing) logger.trace("start", "setting RMIServer object");
- final RMIServerImpl rmiServer;
-
- if (rmiServerImpl != null)
- rmiServer = rmiServerImpl;
- else
- rmiServer = newServer();
-
- rmiServer.setMBeanServer(getMBeanServer());
- rmiServer.setDefaultClassLoader(defaultClassLoader);
- rmiServer.setRMIConnectorServer(this);
- rmiServer.export();
-
- try {
- if (tracing) logger.trace("start", "getting RMIServer object to export");
- final RMIServer objref = objectToBind(rmiServer, attributes);
-
- if (address != null && address.getURLPath().startsWith("/jndi/")) {
- final String jndiUrl = address.getURLPath().substring(6);
-
- if (tracing)
- logger.trace("start", "Using external directory: " + jndiUrl);
-
- String stringBoolean = (String) attributes.get(JNDI_REBIND_ATTRIBUTE);
- final boolean rebind = EnvHelp.computeBooleanFromString( stringBoolean );
-
- if (tracing)
- logger.trace("start", JNDI_REBIND_ATTRIBUTE + "=" + rebind);
-
- try {
- if (tracing) logger.trace("start", "binding to " + jndiUrl);
-
- final Hashtable<?, ?> usemap = EnvHelp.mapToHashtable(attributes);
-
- bind(jndiUrl, usemap, objref, rebind);
-
- boundJndiUrl = jndiUrl;
- } catch (NamingException e) {
- // fit e in the nested exception if we are on 1.4
- throw newIOException("Cannot bind to URL ["+jndiUrl+"]: "
- + e, e);
- }
- } else {
- // if jndiURL is null, we must encode the stub into the URL.
- if (tracing) logger.trace("start", "Encoding URL");
-
- encodeStubInAddress(objref, attributes);
-
- if (tracing) logger.trace("start", "Encoded URL: " + this.address);
- }
- } catch (Exception e) {
- try {
- rmiServer.close();
- } catch (Exception x) {
- // OK: we are already throwing another exception
- }
- if (e instanceof RuntimeException)
- throw (RuntimeException) e;
- else if (e instanceof IOException)
- throw (IOException) e;
- else
- throw newIOException("Got unexpected exception while " +
- "starting the connector server: "
- + e, e);
- }
-
- rmiServerImpl = rmiServer;
-
- synchronized(openedServers) {
- openedServers.add(this);
- }
-
- state = STARTED;
-
- if (tracing) {
- logger.trace("start", "Connector Server Address = " + address);
- logger.trace("start", "started.");
- }
- }
-
- /**
- * <p>Deactivates the connector server, that is, stops listening for
- * client connections. Calling this method will also close all
- * client connections that were made by this server. After this
- * method returns, whether normally or with an exception, the
- * connector server will not create any new client
- * connections.</p>
- *
- * <p>Once a connector server has been stopped, it cannot be started
- * again.</p>
- *
- * <p>Calling this method when the connector server has already
- * been stopped has no effect. Calling this method when the
- * connector server has not yet been started will disable the
- * connector server object permanently.</p>
- *
- * <p>If closing a client connection produces an exception, that
- * exception is not thrown from this method. A {@link
- * JMXConnectionNotification} is emitted from this MBean with the
- * connection ID of the connection that could not be closed.</p>
- *
- * <p>Closing a connector server is a potentially slow operation.
- * For example, if a client machine with an open connection has
- * crashed, the close operation might have to wait for a network
- * protocol timeout. Callers that do not want to block in a close
- * operation should do it in a separate thread.</p>
- *
- * <p>This method calls the method {@link RMIServerImpl#close()
- * close} on the connector server's <code>RMIServerImpl</code>
- * object.</p>
- *
- * <p>If the <code>RMIServerImpl</code> was bound to a JNDI
- * directory by the {@link #start() start} method, it is unbound
- * from the directory by this method.</p>
- *
- * @exception IOException if the server cannot be closed cleanly,
- * or if the <code>RMIServerImpl</code> cannot be unbound from the
- * directory. When this exception is thrown, the server has
- * already attempted to close all client connections, if
- * appropriate; to call {@link RMIServerImpl#close()}; and to
- * unbind the <code>RMIServerImpl</code> from its directory, if
- * appropriate. All client connections are closed except possibly
- * those that generated exceptions when the server attempted to
- * close them.
- */
- public void stop() throws IOException {
- final boolean tracing = logger.traceOn();
-
- synchronized (this) {
- if (state == STOPPED) {
- if (tracing) logger.trace("stop","already stopped.");
- return;
- } else if (state == CREATED) {
- if (tracing) logger.trace("stop","not started yet.");
- }
-
- if (tracing) logger.trace("stop", "stopping.");
- state = STOPPED;
- }
-
- synchronized(openedServers) {
- openedServers.remove(this);
- }
-
- IOException exception = null;
-
- // rmiServerImpl can be null if stop() called without start()
- if (rmiServerImpl != null) {
- try {
- if (tracing) logger.trace("stop", "closing RMI server.");
- rmiServerImpl.close();
- } catch (IOException e) {
- if (tracing) logger.trace("stop", "failed to close RMI server: " + e);
- if (logger.debugOn()) logger.debug("stop",e);
- exception = e;
- }
- }
-
- if (boundJndiUrl != null) {
- try {
- if (tracing)
- logger.trace("stop",
- "unbind from external directory: " + boundJndiUrl);
-
- final Hashtable<?, ?> usemap = EnvHelp.mapToHashtable(attributes);
-
- InitialContext ctx =
- new InitialContext(usemap);
-
- ctx.unbind(boundJndiUrl);
-
- ctx.close();
- } catch (NamingException e) {
- if (tracing) logger.trace("stop", "failed to unbind RMI server: "+e);
- if (logger.debugOn()) logger.debug("stop",e);
- // fit e in as the nested exception if we are on 1.4
- if (exception == null)
- exception = newIOException("Cannot bind to URL: " + e, e);
- }
- }
-
- if (exception != null) throw exception;
-
- if (tracing) logger.trace("stop", "stopped");
- }
-
- public synchronized boolean isActive() {
- return (state == STARTED);
- }
-
- public JMXServiceURL getAddress() {
- if (!isActive())
- return null;
- return address;
- }
-
- public Map<String,?> getAttributes() {
- Map<String, ?> map = EnvHelp.filterAttributes(attributes);
- return Collections.unmodifiableMap(map);
- }
-
- @Override
- public synchronized
- void setMBeanServerForwarder(MBeanServerForwarder mbsf) {
- super.setMBeanServerForwarder(mbsf);
- if (rmiServerImpl != null)
- rmiServerImpl.setMBeanServer(getMBeanServer());
- }
-
- /* We repeat the definitions of connection{Opened,Closed,Failed}
- here so that they are accessible to other classes in this package
- even though they have protected access. */
-
- @Override
- protected void connectionOpened(String connectionId, String message,
- Object userData) {
- super.connectionOpened(connectionId, message, userData);
- }
-
- @Override
- protected void connectionClosed(String connectionId, String message,
- Object userData) {
- super.connectionClosed(connectionId, message, userData);
- }
-
- @Override
- protected void connectionFailed(String connectionId, String message,
- Object userData) {
- super.connectionFailed(connectionId, message, userData);
- }
-
- /**
- * Bind a stub to a registry.
- * @param jndiUrl URL of the stub in the registry, extracted
- * from the <code>JMXServiceURL</code>.
- * @param attributes A Hashtable containing environment parameters,
- * built from the Map specified at this object creation.
- * @param rmiServer The object to bind in the registry
- * @param rebind true if the object must be rebound.
- **/
- void bind(String jndiUrl, Hashtable<?, ?> attributes,
- RMIServer rmiServer, boolean rebind)
- throws NamingException, MalformedURLException {
- // if jndiURL is not null, we nust bind the stub to a
- // directory.
- InitialContext ctx =
- new InitialContext(attributes);
-
- if (rebind)
- ctx.rebind(jndiUrl, rmiServer);
- else
- ctx.bind(jndiUrl, rmiServer);
- ctx.close();
- }
-
- /**
- * Creates a new RMIServerImpl.
- **/
- RMIServerImpl newServer() throws IOException {
- final int port;
- if (address == null)
- port = 0;
- else
- port = address.getPort();
-
- return newJRMPServer(attributes, port);
- }
-
- /**
- * Encode a stub into the JMXServiceURL.
- * @param rmiServer The stub object to encode in the URL
- * @param attributes A Map containing environment parameters,
- * built from the Map specified at this object creation.
- **/
- private void encodeStubInAddress(
- RMIServer rmiServer, Map<String, ?> attributes)
- throws IOException {
-
- final String protocol, host;
- final int port;
-
- if (address == null) {
- protocol = "rmi";
- host = null; // will default to local host name
- port = 0;
- } else {
- protocol = address.getProtocol();
- host = (address.getHost().equals("")) ? null : address.getHost();
- port = address.getPort();
- }
-
- final String urlPath = encodeStub(rmiServer, attributes);
-
- address = new JMXServiceURL(protocol, host, port, urlPath);
- }
-
- /**
- * Returns the IOR of the given rmiServer.
- **/
- static String encodeStub(
- RMIServer rmiServer, Map<String, ?> env) throws IOException {
- return "/stub/" + encodeJRMPStub(rmiServer, env);
- }
-
- static String encodeJRMPStub(
- RMIServer rmiServer, Map<String, ?> env)
- throws IOException {
- ByteArrayOutputStream bout = new ByteArrayOutputStream();
- ObjectOutputStream oout = new ObjectOutputStream(bout);
- oout.writeObject(rmiServer);
- oout.close();
- byte[] bytes = bout.toByteArray();
- return byteArrayToBase64(bytes);
- }
-
- /**
- * Object that we will bind to the registry.
- * This object is a stub connected to our RMIServerImpl.
- **/
- private static RMIServer objectToBind(
- RMIServerImpl rmiServer, Map<String, ?> env)
- throws IOException {
- return (RMIServer)rmiServer.toStub();
- }
-
- private static RMIServerImpl newJRMPServer(Map<String, ?> env, int port)
- throws IOException {
- RMIClientSocketFactory csf = (RMIClientSocketFactory)
- env.get(RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE);
- RMIServerSocketFactory ssf = (RMIServerSocketFactory)
- env.get(RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE);
- return new RMIJRMPServerImpl(port, csf, ssf, env);
- }
-
- private static String byteArrayToBase64(byte[] a) {
- int aLen = a.length;
- int numFullGroups = aLen/3;
- int numBytesInPartialGroup = aLen - 3*numFullGroups;
- int resultLen = 4*((aLen + 2)/3);
- final StringBuilder result = new StringBuilder(resultLen);
-
- // Translate all full groups from byte array elements to Base64
- int inCursor = 0;
- for (int i=0; i<numFullGroups; i++) {
- int byte0 = a[inCursor++] & 0xff;
- int byte1 = a[inCursor++] & 0xff;
- int byte2 = a[inCursor++] & 0xff;
- result.append(intToAlpha[byte0 >> 2]);
- result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
- result.append(intToAlpha[(byte1 << 2)&0x3f | (byte2 >> 6)]);
- result.append(intToAlpha[byte2 & 0x3f]);
- }
-
- // Translate partial group if present
- if (numBytesInPartialGroup != 0) {
- int byte0 = a[inCursor++] & 0xff;
- result.append(intToAlpha[byte0 >> 2]);
- if (numBytesInPartialGroup == 1) {
- result.append(intToAlpha[(byte0 << 4) & 0x3f]);
- result.append("==");
- } else {
- // assert numBytesInPartialGroup == 2;
- int byte1 = a[inCursor++] & 0xff;
- result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
- result.append(intToAlpha[(byte1 << 2)&0x3f]);
- result.append('=');
- }
- }
- // assert inCursor == a.length;
- // assert result.length() == resultLen;
- return result.toString();
- }
-
- /**
- * This array is a lookup table that translates 6-bit positive integer
- * index values into their "Base64 Alphabet" equivalents as specified
- * in Table 1 of RFC 2045.
- */
- private static final char intToAlpha[] = {
- 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
- 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
- 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
- '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
- };
-
- /**
- * Construct a new IOException with a nested exception.
- * The nested exception is set only if JDK {@literal >= 1.4}
- */
- private static IOException newIOException(String message,
- Throwable cause) {
- final IOException x = new IOException(message);
- return EnvHelp.initCause(x,cause);
- }
-
-
- // Private variables
- // -----------------
-
- private static ClassLogger logger =
- new ClassLogger("javax.management.remote.rmi", "RMIConnectorServer");
-
- private JMXServiceURL address;
- private RMIServerImpl rmiServerImpl;
- private final Map<String, ?> attributes;
- private ClassLoader defaultClassLoader = null;
-
- private String boundJndiUrl;
-
- // state
- private static final int CREATED = 0;
- private static final int STARTED = 1;
- private static final int STOPPED = 2;
-
- private int state = CREATED;
- private final static Set<RMIConnectorServer> openedServers =
- new HashSet<RMIConnectorServer>();
-}
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIIIOPServerImpl.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * 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 javax.management.remote.rmi;
-
-import java.io.IOException;
-import java.rmi.Remote;
-import java.util.Map;
-import javax.security.auth.Subject;
-
-/**
- * <p>An {@link RMIServerImpl} that is exported through IIOP and that
- * creates client connections as RMI objects exported through IIOP.
- * User code does not usually reference this class directly.</p>
- *
- * @see RMIServerImpl
- *
- * @since 1.5
- * @deprecated This transport is no longer supported.
- */
-@Deprecated
-public class RMIIIOPServerImpl extends RMIServerImpl {
- /**
- * Throws {@linkplain UnsupportedOperationException}
- *
- * @param env the environment containing attributes for the new
- * <code>RMIServerImpl</code>. Can be null, which is equivalent
- * to an empty Map.
- *
- * @throws IOException if the RMI object cannot be created.
- */
- public RMIIIOPServerImpl(Map<String,?> env)
- throws IOException {
- super(env);
-
- throw new UnsupportedOperationException();
- }
-
- @Override
- protected void export() throws IOException {
- throw new UnsupportedOperationException("Method not supported. JMX RMI-IIOP is deprecated");
- }
-
- @Override
- protected String getProtocol() {
- return "iiop";
- }
-
- @Override
- public Remote toStub() throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- protected RMIConnection makeClient(String connectionId, Subject subject)
- throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- protected void closeClient(RMIConnection client) throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- protected void closeServer() throws IOException {
- throw new UnsupportedOperationException();
- }
-
- @Override
- RMIConnection doNewClient(final Object credentials) throws IOException {
- throw new UnsupportedOperationException();
- }
-}
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,279 +0,0 @@
-/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javax.management.remote.rmi;
-
-import java.io.IOException;
-import java.rmi.NoSuchObjectException;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.server.RMIClientSocketFactory;
-import java.rmi.server.RMIServerSocketFactory;
-import java.rmi.server.UnicastRemoteObject;
-import java.rmi.server.RemoteObject;
-import java.util.Map;
-import java.util.Collections;
-import javax.security.auth.Subject;
-
-import com.sun.jmx.remote.internal.RMIExporter;
-import com.sun.jmx.remote.util.EnvHelp;
-import java.io.ObjectStreamClass;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import sun.reflect.misc.ReflectUtil;
-import sun.rmi.server.DeserializationChecker;
-import sun.rmi.server.UnicastServerRef;
-import sun.rmi.server.UnicastServerRef2;
-
-/**
- * <p>An {@link RMIServer} object that is exported through JRMP and that
- * creates client connections as RMI objects exported through JRMP.
- * User code does not usually reference this class directly.</p>
- *
- * @see RMIServerImpl
- *
- * @since 1.5
- */
-public class RMIJRMPServerImpl extends RMIServerImpl {
-
- private final ExportedWrapper exportedWrapper;
-
- /**
- * <p>Creates a new {@link RMIServer} object that will be exported
- * on the given port using the given socket factories.</p>
- *
- * @param port the port on which this object and the {@link
- * RMIConnectionImpl} objects it creates will be exported. Can be
- * zero, to indicate any available port.
- *
- * @param csf the client socket factory for the created RMI
- * objects. Can be null.
- *
- * @param ssf the server socket factory for the created RMI
- * objects. Can be null.
- *
- * @param env the environment map. Can be null.
- *
- * @exception IOException if the {@link RMIServer} object
- * cannot be created.
- *
- * @exception IllegalArgumentException if <code>port</code> is
- * negative.
- */
- public RMIJRMPServerImpl(int port,
- RMIClientSocketFactory csf,
- RMIServerSocketFactory ssf,
- Map<String,?> env)
- throws IOException {
-
- super(env);
-
- if (port < 0)
- throw new IllegalArgumentException("Negative port: " + port);
-
- this.port = port;
- this.csf = csf;
- this.ssf = ssf;
- this.env = (env == null) ? Collections.<String, Object>emptyMap() : env;
-
- String[] credentialsTypes
- = (String[]) this.env.get(RMIConnectorServer.CREDENTIAL_TYPES);
- List<String> types = null;
- if (credentialsTypes != null) {
- types = new ArrayList<>();
- for (String type : credentialsTypes) {
- if (type == null) {
- throw new IllegalArgumentException("A credential type is null.");
- }
- ReflectUtil.checkPackageAccess(type);
- types.add(type);
- }
- }
- exportedWrapper = types != null ?
- new ExportedWrapper(this, types) :
- null;
- }
-
- protected void export() throws IOException {
- if (exportedWrapper != null) {
- export(exportedWrapper);
- } else {
- export(this);
- }
- }
-
- private void export(Remote obj) throws RemoteException {
- final RMIExporter exporter =
- (RMIExporter) env.get(RMIExporter.EXPORTER_ATTRIBUTE);
- final boolean daemon = EnvHelp.isServerDaemon(env);
-
- if (daemon && exporter != null) {
- throw new IllegalArgumentException("If "+EnvHelp.JMX_SERVER_DAEMON+
- " is specified as true, "+RMIExporter.EXPORTER_ATTRIBUTE+
- " cannot be used to specify an exporter!");
- }
-
- if (daemon) {
- if (csf == null && ssf == null) {
- new UnicastServerRef(port).exportObject(obj, null, true);
- } else {
- new UnicastServerRef2(port, csf, ssf).exportObject(obj, null, true);
- }
- } else if (exporter != null) {
- exporter.exportObject(obj, port, csf, ssf);
- } else {
- UnicastRemoteObject.exportObject(obj, port, csf, ssf);
- }
- }
-
- private void unexport(Remote obj, boolean force)
- throws NoSuchObjectException {
- RMIExporter exporter =
- (RMIExporter) env.get(RMIExporter.EXPORTER_ATTRIBUTE);
- if (exporter == null)
- UnicastRemoteObject.unexportObject(obj, force);
- else
- exporter.unexportObject(obj, force);
- }
-
- protected String getProtocol() {
- return "rmi";
- }
-
- /**
- * <p>Returns a serializable stub for this {@link RMIServer} object.</p>
- *
- * @return a serializable stub.
- *
- * @exception IOException if the stub cannot be obtained - e.g the
- * RMIJRMPServerImpl has not been exported yet.
- */
- public Remote toStub() throws IOException {
- if (exportedWrapper != null) {
- return RemoteObject.toStub(exportedWrapper);
- } else {
- return RemoteObject.toStub(this);
- }
- }
-
- /**
- * <p>Creates a new client connection as an RMI object exported
- * through JRMP. The port and socket factories for the new
- * {@link RMIConnection} object are the ones supplied
- * to the <code>RMIJRMPServerImpl</code> constructor.</p>
- *
- * @param connectionId the ID of the new connection. Every
- * connection opened by this connector server will have a
- * different id. The behavior is unspecified if this parameter is
- * null.
- *
- * @param subject the authenticated subject. Can be null.
- *
- * @return the newly-created <code>RMIConnection</code>.
- *
- * @exception IOException if the new {@link RMIConnection}
- * object cannot be created or exported.
- */
- protected RMIConnection makeClient(String connectionId, Subject subject)
- throws IOException {
-
- if (connectionId == null)
- throw new NullPointerException("Null connectionId");
-
- RMIConnection client =
- new RMIConnectionImpl(this, connectionId, getDefaultClassLoader(),
- subject, env);
- export(client);
- return client;
- }
-
- protected void closeClient(RMIConnection client) throws IOException {
- unexport(client, true);
- }
-
- /**
- * <p>Called by {@link #close()} to close the connector server by
- * unexporting this object. After returning from this method, the
- * connector server must not accept any new connections.</p>
- *
- * @exception IOException if the attempt to close the connector
- * server failed.
- */
- protected void closeServer() throws IOException {
- if (exportedWrapper != null) {
- unexport(exportedWrapper, true);
- } else {
- unexport(this, true);
- }
- }
-
- private final int port;
- private final RMIClientSocketFactory csf;
- private final RMIServerSocketFactory ssf;
- private final Map<String, ?> env;
-
- private static class ExportedWrapper implements RMIServer, DeserializationChecker {
- private final RMIServer impl;
- private final List<String> allowedTypes;
-
- private ExportedWrapper(RMIServer impl, List<String> credentialsTypes) {
- this.impl = impl;
- allowedTypes = credentialsTypes;
- }
-
- @Override
- public String getVersion() throws RemoteException {
- return impl.getVersion();
- }
-
- @Override
- public RMIConnection newClient(Object credentials) throws IOException {
- return impl.newClient(credentials);
- }
-
- @Override
- public void check(Method method, ObjectStreamClass descriptor,
- int paramIndex, int callID) {
- String type = descriptor.getName();
- if (!allowedTypes.contains(type)) {
- throw new ClassCastException("Unsupported type: " + type);
- }
- }
-
- @Override
- public void checkProxyClass(Method method, String[] ifaces,
- int paramIndex, int callID) {
- if (ifaces != null && ifaces.length > 0) {
- for (String iface : ifaces) {
- if (!allowedTypes.contains(iface)) {
- throw new ClassCastException("Unsupported type: " + iface);
- }
- }
- }
- }
- }
-}
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIServer.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package javax.management.remote.rmi;
-
-import java.io.IOException;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-
-/**
- * <p>RMI object used to establish connections to an RMI connector.
- * There is one Remote object implementing this interface for each RMI
- * connector.</p>
- *
- * <p>User code does not usually refer to this interface. It is
- * specified as part of the public API so that different
- * implementations of that API will interoperate.</p>
- *
- * @since 1.5
- */
-public interface RMIServer extends Remote {
- /**
- * <p>The version of the RMI Connector Protocol understood by this
- * connector server. This is a string with the following format:</p>
- *
- * <pre>
- * <em>protocol-version</em> <em>implementation-name</em>
- * </pre>
- *
- * <p>The <code><em>protocol-version</em></code> is a series of
- * two or more non-negative integers separated by periods
- * (<code>.</code>). An implementation of the version described
- * by this documentation must use the string <code>1.0</code>
- * here.</p>
- *
- * <p>After the protocol version there must be a space, followed
- * by the implementation name. The format of the implementation
- * name is unspecified. It is recommended that it include an
- * implementation version number. An implementation can use an
- * empty string as its implementation name, for example for
- * security reasons.</p>
- *
- * @return a string with the format described here.
- *
- * @exception RemoteException if there is a communication
- * exception during the remote method call.
- */
- public String getVersion() throws RemoteException;
-
- /**
- * <p>Makes a new connection through this RMI connector. Each
- * remote client calls this method to obtain a new RMI object
- * representing its connection.</p>
- *
- * @param credentials this object specifies the user-defined credentials
- * to be passed in to the server in order to authenticate the user before
- * creating the <code>RMIConnection</code>. Can be null.
- *
- * @return the newly-created connection object.
- *
- * @exception IOException if the new client object cannot be
- * created or exported, or if there is a communication exception
- * during the remote method call.
- *
- * @exception SecurityException if the given credentials do not
- * allow the server to authenticate the caller successfully.
- */
- public RMIConnection newClient(Object credentials) throws IOException;
-}
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIServerImpl.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,550 +0,0 @@
-/*
- * Copyright (c) 2002, 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 javax.management.remote.rmi;
-
-import com.sun.jmx.remote.internal.ArrayNotificationBuffer;
-import com.sun.jmx.remote.internal.NotificationBuffer;
-import com.sun.jmx.remote.security.JMXPluggableAuthenticator;
-import com.sun.jmx.remote.util.ClassLogger;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.lang.ref.WeakReference;
-import java.rmi.Remote;
-import java.rmi.server.RemoteServer;
-import java.rmi.server.ServerNotActiveException;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.management.MBeanServer;
-import javax.management.remote.JMXAuthenticator;
-import javax.management.remote.JMXConnectorServer;
-import javax.security.auth.Subject;
-
-/**
- * <p>An RMI object representing a connector server. Remote clients
- * can make connections using the {@link #newClient(Object)} method. This
- * method returns an RMI object representing the connection.</p>
- *
- * <p>User code does not usually reference this class directly.
- * RMI connection servers are usually created with the class {@link
- * RMIConnectorServer}. Remote clients usually create connections
- * either with {@link javax.management.remote.JMXConnectorFactory}
- * or by instantiating {@link RMIConnector}.</p>
- *
- * <p>This is an abstract class. Concrete subclasses define the
- * details of the client connection objects.</p>
- *
- * @since 1.5
- */
-public abstract class RMIServerImpl implements Closeable, RMIServer {
- /**
- * <p>Constructs a new <code>RMIServerImpl</code>.</p>
- *
- * @param env the environment containing attributes for the new
- * <code>RMIServerImpl</code>. Can be null, which is equivalent
- * to an empty Map.
- */
- public RMIServerImpl(Map<String,?> env) {
- this.env = (env == null) ? Collections.<String,Object>emptyMap() : env;
- }
-
- void setRMIConnectorServer(RMIConnectorServer connServer)
- throws IOException {
- this.connServer = connServer;
- }
-
- /**
- * <p>Exports this RMI object.</p>
- *
- * @exception IOException if this RMI object cannot be exported.
- */
- protected abstract void export() throws IOException;
-
- /**
- * Returns a remotable stub for this server object.
- * @return a remotable stub.
- * @exception IOException if the stub cannot be obtained - e.g the
- * RMIServerImpl has not been exported yet.
- **/
- public abstract Remote toStub() throws IOException;
-
- /**
- * <p>Sets the default <code>ClassLoader</code> for this connector
- * server. New client connections will use this classloader.
- * Existing client connections are unaffected.</p>
- *
- * @param cl the new <code>ClassLoader</code> to be used by this
- * connector server.
- *
- * @see #getDefaultClassLoader
- */
- public synchronized void setDefaultClassLoader(ClassLoader cl) {
- this.cl = cl;
- }
-
- /**
- * <p>Gets the default <code>ClassLoader</code> used by this connector
- * server.</p>
- *
- * @return the default <code>ClassLoader</code> used by this
- * connector server.
- *
- * @see #setDefaultClassLoader
- */
- public synchronized ClassLoader getDefaultClassLoader() {
- return cl;
- }
-
- /**
- * <p>Sets the <code>MBeanServer</code> to which this connector
- * server is attached. New client connections will interact
- * with this <code>MBeanServer</code>. Existing client connections are
- * unaffected.</p>
- *
- * @param mbs the new <code>MBeanServer</code>. Can be null, but
- * new client connections will be refused as long as it is.
- *
- * @see #getMBeanServer
- */
- public synchronized void setMBeanServer(MBeanServer mbs) {
- this.mbeanServer = mbs;
- }
-
- /**
- * <p>The <code>MBeanServer</code> to which this connector server
- * is attached. This is the last value passed to {@link
- * #setMBeanServer} on this object, or null if that method has
- * never been called.</p>
- *
- * @return the <code>MBeanServer</code> to which this connector
- * is attached.
- *
- * @see #setMBeanServer
- */
- public synchronized MBeanServer getMBeanServer() {
- return mbeanServer;
- }
-
- public String getVersion() {
- // Expected format is: "protocol-version implementation-name"
- try {
- return "1.0 java_runtime_" +
- System.getProperty("java.runtime.version");
- } catch (SecurityException e) {
- return "1.0 ";
- }
- }
-
- /**
- * <p>Creates a new client connection. This method calls {@link
- * #makeClient makeClient} and adds the returned client connection
- * object to an internal list. When this
- * <code>RMIServerImpl</code> is shut down via its {@link
- * #close()} method, the {@link RMIConnection#close() close()}
- * method of each object remaining in the list is called.</p>
- *
- * <p>The fact that a client connection object is in this internal
- * list does not prevent it from being garbage collected.</p>
- *
- * @param credentials this object specifies the user-defined
- * credentials to be passed in to the server in order to
- * authenticate the caller before creating the
- * <code>RMIConnection</code>. Can be null.
- *
- * @return the newly-created <code>RMIConnection</code>. This is
- * usually the object created by <code>makeClient</code>, though
- * an implementation may choose to wrap that object in another
- * object implementing <code>RMIConnection</code>.
- *
- * @exception IOException if the new client object cannot be
- * created or exported.
- *
- * @exception SecurityException if the given credentials do not allow
- * the server to authenticate the user successfully.
- *
- * @exception IllegalStateException if {@link #getMBeanServer()}
- * is null.
- */
- public RMIConnection newClient(Object credentials) throws IOException {
- return doNewClient(credentials);
- }
-
- /**
- * This method could be overridden by subclasses defined in this package
- * to perform additional operations specific to the underlying transport
- * before creating the new client connection.
- */
- RMIConnection doNewClient(Object credentials) throws IOException {
- final boolean tracing = logger.traceOn();
-
- if (tracing) logger.trace("newClient","making new client");
-
- if (getMBeanServer() == null)
- throw new IllegalStateException("Not attached to an MBean server");
-
- Subject subject = null;
- JMXAuthenticator authenticator =
- (JMXAuthenticator) env.get(JMXConnectorServer.AUTHENTICATOR);
- if (authenticator == null) {
- /*
- * Create the JAAS-based authenticator only if authentication
- * has been enabled
- */
- if (env.get("jmx.remote.x.password.file") != null ||
- env.get("jmx.remote.x.login.config") != null) {
- authenticator = new JMXPluggableAuthenticator(env);
- }
- }
- if (authenticator != null) {
- if (tracing) logger.trace("newClient","got authenticator: " +
- authenticator.getClass().getName());
- try {
- subject = authenticator.authenticate(credentials);
- } catch (SecurityException e) {
- logger.trace("newClient", "Authentication failed: " + e);
- throw e;
- }
- }
-
- if (tracing) {
- if (subject != null)
- logger.trace("newClient","subject is not null");
- else logger.trace("newClient","no subject");
- }
-
- final String connectionId = makeConnectionId(getProtocol(), subject);
-
- if (tracing)
- logger.trace("newClient","making new connection: " + connectionId);
-
- RMIConnection client = makeClient(connectionId, subject);
-
- dropDeadReferences();
- WeakReference<RMIConnection> wr = new WeakReference<RMIConnection>(client);
- synchronized (clientList) {
- clientList.add(wr);
- }
-
- connServer.connectionOpened(connectionId, "Connection opened", null);
-
- synchronized (clientList) {
- if (!clientList.contains(wr)) {
- // can be removed only by a JMXConnectionNotification listener
- throw new IOException("The connection is refused.");
- }
- }
-
- if (tracing)
- logger.trace("newClient","new connection done: " + connectionId );
-
- return client;
- }
-
- /**
- * <p>Creates a new client connection. This method is called by
- * the public method {@link #newClient(Object)}.</p>
- *
- * @param connectionId the ID of the new connection. Every
- * connection opened by this connector server will have a
- * different ID. The behavior is unspecified if this parameter is
- * null.
- *
- * @param subject the authenticated subject. Can be null.
- *
- * @return the newly-created <code>RMIConnection</code>.
- *
- * @exception IOException if the new client object cannot be
- * created or exported.
- */
- protected abstract RMIConnection makeClient(String connectionId,
- Subject subject)
- throws IOException;
-
- /**
- * <p>Closes a client connection made by {@link #makeClient makeClient}.
- *
- * @param client a connection previously returned by
- * <code>makeClient</code> on which the <code>closeClient</code>
- * method has not previously been called. The behavior is
- * unspecified if these conditions are violated, including the
- * case where <code>client</code> is null.
- *
- * @exception IOException if the client connection cannot be
- * closed.
- */
- protected abstract void closeClient(RMIConnection client)
- throws IOException;
-
- /**
- * <p>Returns the protocol string for this object. The string is
- * <code>rmi</code> for RMI/JRMP.
- *
- * @return the protocol string for this object.
- */
- protected abstract String getProtocol();
-
- /**
- * <p>Method called when a client connection created by {@link
- * #makeClient makeClient} is closed. A subclass that defines
- * <code>makeClient</code> must arrange for this method to be
- * called when the resultant object's {@link RMIConnection#close()
- * close} method is called. This enables it to be removed from
- * the <code>RMIServerImpl</code>'s list of connections. It is
- * not an error for <code>client</code> not to be in that
- * list.</p>
- *
- * <p>After removing <code>client</code> from the list of
- * connections, this method calls {@link #closeClient
- * closeClient(client)}.</p>
- *
- * @param client the client connection that has been closed.
- *
- * @exception IOException if {@link #closeClient} throws this
- * exception.
- *
- * @exception NullPointerException if <code>client</code> is null.
- */
- protected void clientClosed(RMIConnection client) throws IOException {
- final boolean debug = logger.debugOn();
-
- if (debug) logger.trace("clientClosed","client="+client);
-
- if (client == null)
- throw new NullPointerException("Null client");
-
- synchronized (clientList) {
- dropDeadReferences();
- for (Iterator<WeakReference<RMIConnection>> it = clientList.iterator();
- it.hasNext(); ) {
- WeakReference<RMIConnection> wr = it.next();
- if (wr.get() == client) {
- it.remove();
- break;
- }
- }
- /* It is not a bug for this loop not to find the client. In
- our close() method, we remove a client from the list before
- calling its close() method. */
- }
-
- if (debug) logger.trace("clientClosed", "closing client.");
- closeClient(client);
-
- if (debug) logger.trace("clientClosed", "sending notif");
- connServer.connectionClosed(client.getConnectionId(),
- "Client connection closed", null);
-
- if (debug) logger.trace("clientClosed","done");
- }
-
- /**
- * <p>Closes this connection server. This method first calls the
- * {@link #closeServer()} method so that no new client connections
- * will be accepted. Then, for each remaining {@link
- * RMIConnection} object returned by {@link #makeClient
- * makeClient}, its {@link RMIConnection#close() close} method is
- * called.</p>
- *
- * <p>The behavior when this method is called more than once is
- * unspecified.</p>
- *
- * <p>If {@link #closeServer()} throws an
- * <code>IOException</code>, the individual connections are
- * nevertheless closed, and then the <code>IOException</code> is
- * thrown from this method.</p>
- *
- * <p>If {@link #closeServer()} returns normally but one or more
- * of the individual connections throws an
- * <code>IOException</code>, then, after closing all the
- * connections, one of those <code>IOException</code>s is thrown
- * from this method. If more than one connection throws an
- * <code>IOException</code>, it is unspecified which one is thrown
- * from this method.</p>
- *
- * @exception IOException if {@link #closeServer()} or one of the
- * {@link RMIConnection#close()} calls threw
- * <code>IOException</code>.
- */
- public synchronized void close() throws IOException {
- final boolean tracing = logger.traceOn();
- final boolean debug = logger.debugOn();
-
- if (tracing) logger.trace("close","closing");
-
- IOException ioException = null;
- try {
- if (debug) logger.debug("close","closing Server");
- closeServer();
- } catch (IOException e) {
- if (tracing) logger.trace("close","Failed to close server: " + e);
- if (debug) logger.debug("close",e);
- ioException = e;
- }
-
- if (debug) logger.debug("close","closing Clients");
- // Loop to close all clients
- while (true) {
- synchronized (clientList) {
- if (debug) logger.debug("close","droping dead references");
- dropDeadReferences();
-
- if (debug) logger.debug("close","client count: "+clientList.size());
- if (clientList.size() == 0)
- break;
- /* Loop until we find a non-null client. Because we called
- dropDeadReferences(), this will usually be the first
- element of the list, but a garbage collection could have
- happened in between. */
- for (Iterator<WeakReference<RMIConnection>> it = clientList.iterator();
- it.hasNext(); ) {
- WeakReference<RMIConnection> wr = it.next();
- RMIConnection client = wr.get();
- it.remove();
- if (client != null) {
- try {
- client.close();
- } catch (IOException e) {
- if (tracing)
- logger.trace("close","Failed to close client: " + e);
- if (debug) logger.debug("close",e);
- if (ioException == null)
- ioException = e;
- }
- break;
- }
- }
- }
- }
-
- if(notifBuffer != null)
- notifBuffer.dispose();
-
- if (ioException != null) {
- if (tracing) logger.trace("close","close failed.");
- throw ioException;
- }
-
- if (tracing) logger.trace("close","closed.");
- }
-
- /**
- * <p>Called by {@link #close()} to close the connector server.
- * After returning from this method, the connector server must
- * not accept any new connections.</p>
- *
- * @exception IOException if the attempt to close the connector
- * server failed.
- */
- protected abstract void closeServer() throws IOException;
-
- private static synchronized String makeConnectionId(String protocol,
- Subject subject) {
- connectionIdNumber++;
-
- String clientHost = "";
- try {
- clientHost = RemoteServer.getClientHost();
- /*
- * According to the rules specified in the javax.management.remote
- * package description, a numeric IPv6 address (detected by the
- * presence of otherwise forbidden ":" character) forming a part
- * of the connection id must be enclosed in square brackets.
- */
- if (clientHost.contains(":")) {
- clientHost = "[" + clientHost + "]";
- }
- } catch (ServerNotActiveException e) {
- logger.trace("makeConnectionId", "getClientHost", e);
- }
-
- final StringBuilder buf = new StringBuilder();
- buf.append(protocol).append(":");
- if (clientHost.length() > 0)
- buf.append("//").append(clientHost);
- buf.append(" ");
- if (subject != null) {
- Set<Principal> principals = subject.getPrincipals();
- String sep = "";
- for (Iterator<Principal> it = principals.iterator(); it.hasNext(); ) {
- Principal p = it.next();
- String name = p.getName().replace(' ', '_').replace(';', ':');
- buf.append(sep).append(name);
- sep = ";";
- }
- }
- buf.append(" ").append(connectionIdNumber);
- if (logger.traceOn())
- logger.trace("newConnectionId","connectionId="+buf);
- return buf.toString();
- }
-
- private void dropDeadReferences() {
- synchronized (clientList) {
- for (Iterator<WeakReference<RMIConnection>> it = clientList.iterator();
- it.hasNext(); ) {
- WeakReference<RMIConnection> wr = it.next();
- if (wr.get() == null)
- it.remove();
- }
- }
- }
-
- synchronized NotificationBuffer getNotifBuffer() {
- //Notification buffer is lazily created when the first client connects
- if(notifBuffer == null)
- notifBuffer =
- ArrayNotificationBuffer.getNotificationBuffer(mbeanServer,
- env);
- return notifBuffer;
- }
-
- private static final ClassLogger logger =
- new ClassLogger("javax.management.remote.rmi", "RMIServerImpl");
-
- /** List of WeakReference values. Each one references an
- RMIConnection created by this object, or null if the
- RMIConnection has been garbage-collected. */
- private final List<WeakReference<RMIConnection>> clientList =
- new ArrayList<WeakReference<RMIConnection>>();
-
- private ClassLoader cl;
-
- private MBeanServer mbeanServer;
-
- private final Map<String, ?> env;
-
- private RMIConnectorServer connServer;
-
- private static int connectionIdNumber;
-
- private NotificationBuffer notifBuffer;
-}
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/package.html Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,340 +0,0 @@
-<html>
-<head>
- <title>RMI connector</title>
-<!--
-Copyright (c) 2002, 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.
--->
-</head>
-<body bgcolor="white">
- <p>The RMI connector is a connector for the JMX Remote API that
- uses RMI to transmit client requests to a remote MBean server.
- This package defines the classes that the user of an RMI
- connector needs to reference directly, for both the client and
- server sides. It also defines certain classes that the user
- will not usually reference directly, but that must be defined so
- that different implementations of the RMI connector can
- interoperate.</p>
-
- <p>The RMI connector supports the JRMP transport for RMI.</p>
-
- <p>Like most connectors in the JMX Remote API, an RMI connector
- usually has an address, which
- is a {@link javax.management.remote.JMXServiceURL
- JMXServiceURL}. The protocol part of this address is
- <code>rmi</code> for a connector that uses the default RMI
- transport (JRMP).</p>
-
- <p>There are two forms for RMI connector addresses:</p>
-
- <ul>
- <li>
- In the <em>JNDI form</em>, the URL indicates <em>where to find
- an RMI stub for the connector</em>. This RMI stub is a Java
- object of type {@link javax.management.remote.rmi.RMIServer
- RMIServer} that gives remote access to the connector server.
- With this address form, the RMI stub is obtained from an
- external directory entry included in the URL. An external
- directory is any directory recognized by {@link javax.naming
- JNDI}, typically the RMI registry, LDAP, or COS Naming.
-
- <li>
- In the <em>encoded form</em>, the URL directly includes the
- information needed to connect to the connector server. When
- using RMI/JRMP, the encoded form is the serialized RMI stub
- for the server object, encoded using BASE64 without embedded
- newlines.
- </ul>
-
- <p>Addresses are covered in more detail below.</p>
-
-
- <h3>Creating an RMI connector server</h3>
-
- <p>The usual way to create an RMI connector server is to supply an
- RMI connector address to the method {@link
- javax.management.remote.JMXConnectorServerFactory#newJMXConnectorServer
- JMXConnectorServerFactory.newJMXConnectorServer}. The MBean
- server to which the connector server is attached can be
- specified as a parameter to that method. Alternatively, the
- connector server can be registered as an MBean in that MBean
- server.</p>
-
- <p>An RMI connector server can also be created by constructing an
- instance of {@link
- javax.management.remote.rmi.RMIConnectorServer
- RMIConnectorServer}, explicitly or through the MBean server's
- <code>createMBean</code> method.</p>
-
- <h4>Choosing the RMI transport</h4>
-
- <p>You can choose the RMI transport by specifying
- <code>rmi</code> in the <code><em>protocol</em></code> part of the
- <code>serviceURL</code> when creating the connector server. You
- can also create specialized connector servers by instantiating
- an appropriate subclass of {@link
- javax.management.remote.rmi.RMIServerImpl RMIServerImpl} and
- supplying it to the <code>RMIConnectorServer</code>
- constructor.</p>
-
-
- <h4><a name="servergen">Connector addresses generated by the
- server</a></h4>
-
- <p>If the <code>serviceURL</code> you specify has an empty URL
- path (after the optional host and port), or if you do not
- specify a <code>serviceURL</code>, then the connector server
- will fabricate a new <code>JMXServiceURL</code> that clients can
- use to connect:</p>
-
- <ul>
-
- <li><p>If the <code>serviceURL</code> looks like:</p>
-
- <pre>
- <code>service:jmx:rmi://<em>host</em>:<em>port</em></code>
- </pre>
-
- <p>then the connector server will generate an {@link
- javax.management.remote.rmi.RMIJRMPServerImpl
- RMIJRMPServerImpl} and the returned <code>JMXServiceURL</code>
- looks like:</p>
-
- <pre>
- <code>service:jmx:rmi://<em>host</em>:<em>port</em>/stub/<em>XXXX</em></code>
- </pre>
-
- <p>where <code><em>XXXX</em></code> is the serialized form of the
- stub for the generated object, encoded in BASE64 without
- newlines.</p>
-
- <li><p>If there is no <code>serviceURL</code>, there must be a
- user-provided <code>RMIServerImpl</code>. The connector server
- will generate a <code>JMXServiceURL</code> using the <code>rmi</code>
- form.</p>
-
- </ul>
-
- <p>The <code><em>host</em></code> in a user-provided
- <code>serviceURL</code> is optional. If present, it is copied
- into the generated <code>JMXServiceURL</code> but otherwise
- ignored. If absent, the generated <code>JXMServiceURL</code>
- will have the local host name.</p>
-
- <p>The <code><em>port</em></code> in a user-provided
- <code>serviceURL</code> is also optional. If present, it is
- also copied into the generated <code>JMXServiceURL</code>;
- otherwise, the generated <code>JMXServiceURL</code> has no port.
- For an <code>serviceURL</code> using the <code>rmi</code>
- protocol, the <code><em>port</em></code>, if present, indicates
- what port the generated remote object should be exported on. It
- has no other effect.</p>
-
- <p>If the user provides an <code>RMIServerImpl</code> rather than a
- <code>JMXServiceURL</code>, then the generated
- <code>JMXServiceURL</code> will have the local host name in its
- <code><em>host</em></code> part and no
- <code><em>port</em></code>.</p>
-
-
- <h4><a name="directory">Connector addresses based on directory
- entries</a></h4>
-
- <p>As an alternative to the generated addresses just described,
- the <code>serviceURL</code> address supplied when creating a
- connector server can specify a <em>directory address</em> in
- which to store the provided or generated <code>RMIServer</code>
- stub. This directory address is then used by both client and
- server.</p>
-
- <p>In this case, the <code>serviceURL</code> has the following form:</p>
-
- <pre>
- <code>service:jmx:rmi://<em>host</em>:<em>port</em>/jndi/<em>jndi-name</em></code>
- </pre>
-
- <p>Here, <code><em>jndi-name</em></code> is a string that can be
- supplied to {@link javax.naming.InitialContext#bind
- javax.naming.InitialContext.bind}.</p>
-
- <p>As usual, the <code><em>host</em></code> and
- <code>:<em>port</em></code> can be omitted.</p>
-
- <p>The connector server will generate an
- <code>RMIServerImpl</code> based on the protocol
- (<code>rmi</code>) and the <code><em>port</em></code> if any. When
- the connector server is started, it will derive a stub from this
- object using its {@link
- javax.management.remote.rmi.RMIServerImpl#toStub toStub} method
- and store the object using the given
- <code><em>jndi-name</em></code>. The properties defined by the
- JNDI API are consulted as usual.</p>
-
- <p>For example, if the <code>JMXServiceURL</code> is:
-
- <pre>
- <code>service:jmx:rmi://ignoredhost/jndi/rmi://myhost/myname</code>
- </pre>
-
- then the connector server will generate an
- <code>RMIJRMPServerImpl</code> and store its stub using the JNDI
- name
-
- <pre>
- <code>rmi://myhost/myname</code>
- </pre>
-
- which means entry <code>myname</code> in the RMI registry
- running on the default port of host <code>myhost</code>. Note
- that the RMI registry only allows registration from the local
- host. So, in this case, <code>myhost</code> must be the name
- (or a name) of the host that the connector server is running
- on.
-
- <p>In this <code>JMXServiceURL</code>, the first <code>rmi:</code>
- specifies the RMI
- connector, while the second <code>rmi:</code> specifies the RMI
- registry.
-
- <p>As another example, if the <code>JMXServiceURL</code> is:
-
- <pre>
- <code>service:jmx:rmi://ignoredhost/jndi/ldap://dirhost:9999/cn=this,ou=that</code>
- </pre>
-
- then the connector server will generate an
- <code>RMIJRMPServerImpl</code> and store its stub using the JNDI
- name
-
- <pre>
- <code>ldap://dirhost:9999/cn=this,ou=that</code>
- </pre>
-
- which means entry <code>cn=this,ou=that</code> in the LDAP
- directory running on port 9999 of host <code>dirhost</code>.
-
- <p>If the <code>JMXServiceURL</code> is:
-
- <pre>
- <code>service:jmx:rmi://ignoredhost/jndi/cn=this,ou=that</code>
- </pre>
-
- then the connector server will generate an
- <code>RMIJRMPServerImpl</code> and store its stub using the JNDI
- name
-
- <pre>
- <code>cn=this,ou=that</code>
- </pre>
-
- For this case to work, the JNDI API must have been configured
- appropriately to supply the information about what directory to
- use.
-
- <p>In these examples, the host name <code>ignoredhost</code> is
- not used by the connector server or its clients. It can be
- omitted, for example:</p>
-
- <pre>
- <code>service:jmx:rmi:///jndi/cn=this,ou=that</code>
- </pre>
-
- <p>However, it is good practice to use the name of the host
- where the connector server is running. This is often different
- from the name of the directory host.</p>
-
-
- <h4>Connector server attributes</h4>
-
- <p>When using the default JRMP transport, RMI socket factories can
- be specified using the attributes
- <code>jmx.remote.rmi.client.socket.factory</code> and
- <code>jmx.remote.rmi.server.socket.factory</code> in the
- <code>environment</code> given to the
- <code>RMIConnectorServer</code> constructor. The values of these
- attributes must be of type {@link
- java.rmi.server.RMIClientSocketFactory} and {@link
- java.rmi.server.RMIServerSocketFactory}, respectively. These
- factories are used when creating the RMI objects associated with
- the connector.</p>
-
- <h3>Creating an RMI connector client</h3>
-
- <p>An RMI connector client is usually constructed using {@link
- javax.management.remote.JMXConnectorFactory}, with a
- <code>JMXServiceURL</code> that has <code>rmi</code> as its protocol.</p>
-
- <p>If the <code>JMXServiceURL</code> was generated by the server,
- as described above under <a href="#servergen">"connector
- addresses generated by the server"</a>, then the client will
- need to obtain it directly or indirectly from the server.
- Typically, the server makes the <code>JMXServiceURL</code>
- available by storing it in a file or a lookup service.</p>
-
- <p>If the <code>JMXServiceURL</code> uses the directory syntax, as
- described above under <a href="#directory">"connector addresses
- based on directory entries"</a>, then the client may obtain it
- as just explained, or client and server may both know the
- appropriate directory entry to use. For example, if the
- connector server for the Whatsit agent uses the entry
- <code>whatsit-agent-connector</code> in the RMI registry on host
- <code>myhost</code>, then client and server can both know
- that the appropriate <code>JMXServiceURL</code> is:</p>
-
- <pre>
- <code>service:jmx:rmi:///jndi/rmi://myhost/whatsit-agent-connector</code>
- </pre>
-
- <p>If you have an RMI stub of type {@link
- javax.management.remote.rmi.RMIServer RMIServer}, you can
- construct an RMI connection directly by using the appropriate
- constructor of {@link javax.management.remote.rmi.RMIConnector
- RMIConnector}.</p>
-
- <h3>Dynamic code downloading</h3>
-
- <p>If an RMI connector client or server receives from its peer an
- instance of a class that it does not know, and if dynamic code
- downloading is active for the RMI connection, then the class can
- be downloaded from a codebase specified by the peer. The
- article <a
- href="{@docRoot}/../technotes/guides/rmi/codebase.html"><em>Dynamic
- code downloading using Java RMI</em></a> explains this in more
- detail.</p>
-
-
- @see <a href="{@docRoot}/../technotes/guides/rmi/index.html">
- Java™ Remote Method
- Invocation (RMI)</a>
-
- @see <a href="{@docRoot}/../technotes/guides/jndi/index.html">
- Java Naming and Directory Interface™ (JNDI)</a>
-
- @see <a href="http://www.ietf.org/rfc/rfc2045.txt">RFC 2045,
- section 6.8, "Base64 Content-Transfer-Encoding"</a>
-
-
- @since 1.5
-
- </body>
-</html>
--- a/jdk/src/java.management/share/classes/module-info.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.management/share/classes/module-info.java Thu Feb 02 21:55:34 2017 +0000
@@ -30,8 +30,6 @@
* JVM and other components in the Java runtime.
*/
module java.management {
- requires transitive java.rmi;
- requires java.naming;
exports java.lang.management;
exports javax.management;
@@ -41,15 +39,25 @@
exports javax.management.openmbean;
exports javax.management.relation;
exports javax.management.remote;
- exports javax.management.remote.rmi;
exports javax.management.timer;
- exports sun.management to jdk.jconsole, jdk.management;
+ exports com.sun.jmx.remote.internal to
+ java.management.rmi,
+ jdk.management.agent;
+ exports com.sun.jmx.remote.security to
+ java.management.rmi,
+ jdk.management.agent;
+ exports com.sun.jmx.remote.util to java.management.rmi;
+ exports sun.management to
+ jdk.jconsole,
+ jdk.management,
+ jdk.management.agent;
+ exports sun.management.counter to jdk.management.agent;
+ exports sun.management.counter.perf to jdk.management.agent;
exports sun.management.spi to jdk.management;
uses javax.management.remote.JMXConnectorProvider;
uses javax.management.remote.JMXConnectorServerProvider;
uses sun.management.spi.PlatformMBeanProvider;
- uses sun.management.spi.AgentProvider;
provides javax.security.auth.spi.LoginModule
with com.sun.jmx.remote.security.FileLoginModule;
--- a/jdk/src/java.management/share/classes/sun/management/Agent.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,739 +0,0 @@
-/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.management;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.management.ManagementFactory;
-import java.lang.reflect.Method;
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.UnknownHostException;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.text.MessageFormat;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.MissingResourceException;
-import java.util.Properties;
-import java.util.ResourceBundle;
-import java.util.ServiceLoader;
-import java.util.function.Function;
-import java.util.function.Predicate;
-
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXServiceURL;
-
-import static sun.management.AgentConfigurationError.*;
-import sun.management.jmxremote.ConnectorBootstrap;
-import sun.management.jdp.JdpController;
-import sun.management.jdp.JdpException;
-import jdk.internal.vm.VMSupport;
-import sun.management.spi.AgentProvider;
-
-/**
- * This Agent is started by the VM when -Dcom.sun.management.snmp or
- * -Dcom.sun.management.jmxremote is set. This class will be loaded by the
- * system class loader. Also jmx framework could be started by jcmd
- */
-public class Agent {
- /**
- * Agent status collector strategy class
- */
- private static abstract class StatusCollector {
- protected static final Map<String, String> DEFAULT_PROPS = new HashMap<>();
-
- static {
- DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.PORT,
- ConnectorBootstrap.DefaultValues.PORT);
- DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.USE_LOCAL_ONLY,
- ConnectorBootstrap.DefaultValues.USE_LOCAL_ONLY);
- DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.USE_AUTHENTICATION,
- ConnectorBootstrap.DefaultValues.USE_AUTHENTICATION);
- DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.USE_SSL,
- ConnectorBootstrap.DefaultValues.USE_SSL);
- DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.USE_REGISTRY_SSL,
- ConnectorBootstrap.DefaultValues.USE_REGISTRY_SSL);
- DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.SSL_NEED_CLIENT_AUTH,
- ConnectorBootstrap.DefaultValues.SSL_NEED_CLIENT_AUTH);
- DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.CONFIG_FILE_NAME,
- ConnectorBootstrap.DefaultValues.CONFIG_FILE_NAME);
- DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.PASSWORD_FILE_NAME,
- ConnectorBootstrap.DefaultValues.PASSWORD_FILE_NAME);
- DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.ACCESS_FILE_NAME,
- ConnectorBootstrap.DefaultValues.ACCESS_FILE_NAME);
-
- }
-
- 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);
- addConfigProperties();
- appendConnectionFooter(remote);
- }
-
- private void addConfigProperties() {
- appendConfigPropsHeader();
-
- Properties remoteProps = configProps != null ?
- configProps : getManagementProperties();
- Map<Object, Object> props = new HashMap<>(DEFAULT_PROPS);
-
- if (remoteProps == null) {
- // local connector only
- String loc_only = System.getProperty(
- ConnectorBootstrap.PropertyNames.USE_LOCAL_ONLY
- );
-
- if (loc_only != null &&
- !ConnectorBootstrap.DefaultValues.USE_LOCAL_ONLY.equals(loc_only)) {
- props.put(
- ConnectorBootstrap.PropertyNames.USE_LOCAL_ONLY,
- loc_only
- );
- }
- } else {
- props.putAll(remoteProps);
- }
-
- props.entrySet().stream()
- .filter(preprocess(Map.Entry::getKey, StatusCollector::isManagementProp))
- .forEach(this::addConfigProp);
-
- appendConfigPropsFooter();
- }
-
- private static boolean isManagementProp(Object pName) {
- return pName != null && pName.toString().startsWith("com.sun.management.");
- }
-
- private static <T, V> Predicate<T> preprocess(Function<T, V> f, Predicate<V> p) {
- return (T t) -> p.test(f.apply(t));
- }
-
- 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(Map.Entry<?, ?> prop);
- }
-
- /**
- * 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(Map.Entry<?, ?> prop) {
- sb.append(" ").append(prop.getKey()).append(" = ")
- .append(prop.getValue());
- Object defVal = DEFAULT_PROPS.get(prop.getKey());
- if (defVal != null && defVal.equals(prop.getValue())) {
- sb.append(" [default]");
- }
- sb.append("\n");
- }
-
- @Override
- protected void appendConnectionsFooter() {}
-
- @Override
- protected void appendConnectionFooter(boolean remote) {
- sb.append('\n');
- }
-
- @Override
- protected void appendConfigPropsFooter() {}
- }
-
- // management properties
-
- private static Properties mgmtProps;
- private static ResourceBundle messageRB;
- private static final String CONFIG_FILE =
- "com.sun.management.config.file";
- private static final String SNMP_PORT =
- "com.sun.management.snmp.port";
- private static final String JMXREMOTE =
- "com.sun.management.jmxremote";
- private static final String JMXREMOTE_PORT =
- "com.sun.management.jmxremote.port";
- private static final String RMI_PORT =
- "com.sun.management.jmxremote.rmi.port";
- private static final String ENABLE_THREAD_CONTENTION_MONITORING =
- "com.sun.management.enableThreadContentionMonitoring";
- private static final String LOCAL_CONNECTOR_ADDRESS_PROP =
- "com.sun.management.jmxremote.localConnectorAddress";
- private static final String SNMP_AGENT_NAME =
- "SnmpAgent";
-
- private static final String JDP_DEFAULT_ADDRESS = "224.0.23.178";
- private static final int JDP_DEFAULT_PORT = 7095;
-
- // 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
- // return empty property set
- private static Properties parseString(String args) {
- Properties argProps = new Properties();
- if (args != null && !args.trim().equals("")) {
- for (String option : args.split(",")) {
- String s[] = option.split("=", 2);
- String name = s[0].trim();
- String value = (s.length > 1) ? s[1].trim() : "";
-
- if (!name.startsWith("com.sun.management.")) {
- error(INVALID_OPTION, name);
- }
-
- argProps.setProperty(name, value);
- }
- }
-
- return argProps;
- }
-
- // invoked by -javaagent or -Dcom.sun.management.agent.class
- public static void premain(String args) throws Exception {
- agentmain(args);
- }
-
- // invoked by attach mechanism
- public static void agentmain(String args) throws Exception {
- if (args == null || args.length() == 0) {
- args = JMXREMOTE; // default to local management
- }
-
- Properties arg_props = parseString(args);
-
- // Read properties from the config file
- Properties config_props = new Properties();
- String fname = arg_props.getProperty(CONFIG_FILE);
- readConfiguration(fname, config_props);
-
- // Arguments override config file
- config_props.putAll(arg_props);
- startAgent(config_props);
- }
-
- // jcmd ManagementAgent.start_local entry point
- // Also called due to command-line via startAgent()
- private static synchronized void startLocalManagementAgent() {
- Properties agentProps = VMSupport.getAgentProperties();
-
- // start local connector if not started
- if (agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP) == null) {
- JMXConnectorServer cs = ConnectorBootstrap.startLocalConnectorServer();
- String address = cs.getAddress().toString();
- // Add the local connector address to the agent properties
- agentProps.put(LOCAL_CONNECTOR_ADDRESS_PROP, address);
-
- try {
- // export the address to the instrumentation buffer
- ConnectorAddressLink.export(address);
- } catch (Exception x) {
- // Connector server started but unable to export address
- // to instrumentation buffer - non-fatal error.
- warning(EXPORT_ADDRESS_FAILED, x.getMessage());
- }
- }
- }
-
- // jcmd ManagementAgent.start entry point
- // This method starts the remote JMX agent and starts neither
- // the local JMX agent nor the SNMP agent
- // @see #startLocalManagementAgent and also @see #startAgent.
- private static synchronized void startRemoteManagementAgent(String args) throws Exception {
- if (jmxServer != null) {
- throw new RuntimeException(getText(INVALID_STATE, "Agent already started"));
- }
-
- try {
- Properties argProps = parseString(args);
- configProps = new Properties();
-
- // Load the management properties from the config file
- // if config file is not specified readConfiguration implicitly
- // reads <java.home>/conf/management/management.properties
-
- String fname = System.getProperty(CONFIG_FILE);
- readConfiguration(fname, configProps);
-
- // management properties can be overridden by system properties
- // which take precedence
- Properties sysProps = System.getProperties();
- synchronized (sysProps) {
- configProps.putAll(sysProps);
- }
-
- // if user specifies config file into command line for either
- // jcmd utilities or attach command it overrides properties set in
- // command line at the time of VM start
- String fnameUser = argProps.getProperty(CONFIG_FILE);
- if (fnameUser != null) {
- readConfiguration(fnameUser, configProps);
- }
-
- // arguments specified in command line of jcmd utilities
- // override both system properties and one set by config file
- // specified in jcmd command line
- configProps.putAll(argProps);
-
- // jcmd doesn't allow to change ThreadContentionMonitoring, but user
- // can specify this property inside config file, so enable optional
- // monitoring functionality if this property is set
- final String enableThreadContentionMonitoring =
- configProps.getProperty(ENABLE_THREAD_CONTENTION_MONITORING);
-
- if (enableThreadContentionMonitoring != null) {
- ManagementFactory.getThreadMXBean().
- setThreadContentionMonitoringEnabled(true);
- }
-
- String jmxremotePort = configProps.getProperty(JMXREMOTE_PORT);
- if (jmxremotePort != null) {
- jmxServer = ConnectorBootstrap.
- startRemoteConnectorServer(jmxremotePort, configProps);
-
- startDiscoveryService(configProps);
- } else {
- throw new AgentConfigurationError(INVALID_JMXREMOTE_PORT, "No port specified");
- }
- } catch (JdpException e) {
- error(e);
- } catch (AgentConfigurationError err) {
- error(err.getError(), err.getParams());
- }
- }
-
- private static synchronized void stopRemoteManagementAgent() throws Exception {
-
- JdpController.stopDiscoveryService();
-
- if (jmxServer != null) {
- ConnectorBootstrap.unexportRegistry();
- ConnectorAddressLink.unexportRemote();
-
- // Attempt to stop already stopped 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);
- String jmxremotePort = props.getProperty(JMXREMOTE_PORT);
-
- // Enable optional monitoring functionality if requested
- final String enableThreadContentionMonitoring =
- props.getProperty(ENABLE_THREAD_CONTENTION_MONITORING);
- if (enableThreadContentionMonitoring != null) {
- ManagementFactory.getThreadMXBean().
- setThreadContentionMonitoringEnabled(true);
- }
-
- try {
- if (snmpPort != null) {
- loadSnmpAgent(props);
- }
-
- /*
- * If the jmxremote.port property is set then we start the
- * RMIConnectorServer for remote M&M.
- *
- * If the jmxremote or jmxremote.port properties are set then
- * we start a RMIConnectorServer for local M&M. The address
- * of this "local" server is exported as a counter to the jstat
- * instrumentation buffer.
- */
- if (jmxremote != null || jmxremotePort != null) {
- if (jmxremotePort != null) {
- jmxServer = ConnectorBootstrap.
- startRemoteConnectorServer(jmxremotePort, props);
- startDiscoveryService(props);
- }
- startLocalManagementAgent();
- }
-
- } catch (AgentConfigurationError e) {
- error(e.getError(), e.getParams());
- } catch (Exception e) {
- error(e);
- }
- }
-
- private static void startDiscoveryService(Properties props)
- throws IOException, JdpException {
- // Start discovery service if requested
- String discoveryPort = props.getProperty("com.sun.management.jdp.port");
- String discoveryAddress = props.getProperty("com.sun.management.jdp.address");
- String discoveryShouldStart = props.getProperty("com.sun.management.jmxremote.autodiscovery");
-
- // Decide whether we should start autodicovery service.
- // To start autodiscovery following conditions should be met:
- // autodiscovery==true OR (autodicovery==null AND jdp.port != NULL)
-
- boolean shouldStart = false;
- if (discoveryShouldStart == null){
- shouldStart = (discoveryPort != null);
- }
- else{
- try{
- shouldStart = Boolean.parseBoolean(discoveryShouldStart);
- } catch (NumberFormatException e) {
- throw new AgentConfigurationError(AGENT_EXCEPTION, "Couldn't parse autodiscovery argument");
- }
- }
-
- if (shouldStart) {
- // port and address are required arguments and have no default values
- InetAddress address;
- try {
- address = (discoveryAddress == null) ?
- InetAddress.getByName(JDP_DEFAULT_ADDRESS) : InetAddress.getByName(discoveryAddress);
- } catch (UnknownHostException e) {
- throw new AgentConfigurationError(AGENT_EXCEPTION, e, "Unable to broadcast to requested address");
- }
-
- int port = JDP_DEFAULT_PORT;
- if (discoveryPort != null) {
- try {
- port = Integer.parseInt(discoveryPort);
- } catch (NumberFormatException e) {
- throw new AgentConfigurationError(AGENT_EXCEPTION, "Couldn't parse JDP port argument");
- }
- }
-
- // Rebuilding service URL to broadcast it
- String jmxremotePort = props.getProperty(JMXREMOTE_PORT);
- String rmiPort = props.getProperty(RMI_PORT);
-
- JMXServiceURL url = jmxServer.getAddress();
- String hostname = url.getHost();
-
- String jmxUrlStr = (rmiPort != null)
- ? String.format(
- "service:jmx:rmi://%s:%s/jndi/rmi://%s:%s/jmxrmi",
- hostname, rmiPort, hostname, jmxremotePort)
- : String.format(
- "service:jmx:rmi:///jndi/rmi://%s:%s/jmxrmi", hostname, jmxremotePort);
-
- String instanceName = props.getProperty("com.sun.management.jdp.name");
-
- JdpController.startDiscoveryService(address, port, instanceName, jmxUrlStr);
- }
- }
-
- public static Properties loadManagementProperties() {
- Properties props = new Properties();
-
- // Load the management properties from the config file
-
- String fname = System.getProperty(CONFIG_FILE);
- readConfiguration(fname, props);
-
- // management properties can be overridden by system properties
- // which take precedence
- Properties sysProps = System.getProperties();
- synchronized (sysProps) {
- props.putAll(sysProps);
- }
-
- return props;
- }
-
- public static synchronized Properties getManagementProperties() {
- if (mgmtProps == null) {
- String configFile = System.getProperty(CONFIG_FILE);
- String snmpPort = System.getProperty(SNMP_PORT);
- String jmxremote = System.getProperty(JMXREMOTE);
- String jmxremotePort = System.getProperty(JMXREMOTE_PORT);
-
- if (configFile == null && snmpPort == null
- && jmxremote == null && jmxremotePort == null) {
- // return if out-of-the-management option is not specified
- return null;
- }
- mgmtProps = loadManagementProperties();
- }
- return mgmtProps;
- }
-
- private static void loadSnmpAgent(Properties props) {
- /*
- * Load the jdk.snmp service
- */
- AgentProvider provider = AccessController.doPrivileged(
- (PrivilegedAction<AgentProvider>) () -> {
- for(AgentProvider aProvider : ServiceLoader.loadInstalled(AgentProvider.class)) {
- if(aProvider.getName().equals(SNMP_AGENT_NAME))
- return aProvider;
- }
- return null;
- }, null
- );
-
- if (provider != null) {
- provider.startAgent(props);
- } else { // snmp runtime doesn't exist - initialization fails
- throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT);
- }
- }
-
- // read config file and initialize the properties
- private static void readConfiguration(String fname, Properties p) {
- if (fname == null) {
- String home = System.getProperty("java.home");
- if (home == null) {
- throw new Error("Can't find java.home ??");
- }
- StringBuilder defaultFileName = new StringBuilder(home);
- defaultFileName.append(File.separator).append("conf");
- defaultFileName.append(File.separator).append("management");
- defaultFileName.append(File.separator).append("management.properties");
- // Set file name
- fname = defaultFileName.toString();
- }
- final File configFile = new File(fname);
- if (!configFile.exists()) {
- error(CONFIG_FILE_NOT_FOUND, fname);
- }
-
- InputStream in = null;
- try {
- in = new FileInputStream(configFile);
- BufferedInputStream bin = new BufferedInputStream(in);
- p.load(bin);
- } catch (FileNotFoundException e) {
- error(CONFIG_FILE_OPEN_FAILED, e.getMessage());
- } catch (IOException e) {
- error(CONFIG_FILE_OPEN_FAILED, e.getMessage());
- } catch (SecurityException e) {
- error(CONFIG_FILE_ACCESS_DENIED, fname);
- } finally {
- if (in != null) {
- try {
- in.close();
- } catch (IOException e) {
- error(CONFIG_FILE_CLOSE_FAILED, fname);
- }
- }
- }
- }
-
- public static void startAgent() throws Exception {
- String prop = System.getProperty("com.sun.management.agent.class");
-
- // -Dcom.sun.management.agent.class not set so read management
- // properties and start agent
- if (prop == null) {
- // initialize management properties
- Properties props = getManagementProperties();
- if (props != null) {
- startAgent(props);
- }
- return;
- }
-
- // -Dcom.sun.management.agent.class=<agent classname>:<agent args>
- String[] values = prop.split(":");
- if (values.length < 1 || values.length > 2) {
- error(AGENT_CLASS_INVALID, "\"" + prop + "\"");
- }
- String cname = values[0];
- String args = (values.length == 2 ? values[1] : null);
-
- if (cname == null || cname.length() == 0) {
- error(AGENT_CLASS_INVALID, "\"" + prop + "\"");
- }
-
- if (cname != null) {
- try {
- // Instantiate the named class.
- // invoke the premain(String args) method
- Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(cname);
- Method premain = clz.getMethod("premain",
- new Class<?>[]{String.class});
- premain.invoke(null, /* static */
- new Object[]{args});
- } catch (ClassNotFoundException ex) {
- error(AGENT_CLASS_NOT_FOUND, "\"" + cname + "\"");
- } catch (NoSuchMethodException ex) {
- error(AGENT_CLASS_PREMAIN_NOT_FOUND, "\"" + cname + "\"");
- } catch (SecurityException ex) {
- error(AGENT_CLASS_ACCESS_DENIED);
- } catch (Exception ex) {
- String msg = (ex.getCause() == null
- ? ex.getMessage()
- : ex.getCause().getMessage());
- error(AGENT_CLASS_FAILED, msg);
- }
- }
- }
-
- public static void error(String key) {
- String keyText = getText(key);
- System.err.print(getText("agent.err.error") + ": " + keyText);
- throw new RuntimeException(keyText);
- }
-
- public static void error(String key, String[] params) {
- if (params == null || params.length == 0) {
- error(key);
- } else {
- StringBuilder message = new StringBuilder(params[0]);
- for (int i = 1; i < params.length; i++) {
- message.append(' ').append(params[i]);
- }
- error(key, message.toString());
- }
- }
-
- public static void error(String key, String message) {
- String keyText = getText(key);
- System.err.print(getText("agent.err.error") + ": " + keyText);
- System.err.println(": " + message);
- throw new RuntimeException(keyText + ": " + message);
- }
-
- public static void error(Exception e) {
- e.printStackTrace();
- System.err.println(getText(AGENT_EXCEPTION) + ": " + e.toString());
- throw new RuntimeException(e);
- }
-
- public static void warning(String key, String message) {
- System.err.print(getText("agent.err.warning") + ": " + getText(key));
- System.err.println(": " + message);
- }
-
- private static void initResource() {
- try {
- messageRB =
- ResourceBundle.getBundle("sun.management.resources.agent");
- } catch (MissingResourceException e) {
- throw new Error("Fatal: Resource for management agent is missing");
- }
- }
-
- public static String getText(String key) {
- if (messageRB == null) {
- initResource();
- }
- try {
- return messageRB.getString(key);
- } catch (MissingResourceException e) {
- return "Missing management agent resource bundle: key = \"" + key + "\"";
- }
- }
-
- public static String getText(String key, String... args) {
- if (messageRB == null) {
- initResource();
- }
- String format = messageRB.getString(key);
- if (format == null) {
- format = "missing resource key: key = \"" + key + "\", "
- + "arguments = \"{0}\", \"{1}\", \"{2}\"";
- }
- return MessageFormat.format(format, (Object[]) args);
- }
-}
--- a/jdk/src/java.management/share/classes/sun/management/AgentConfigurationError.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management;
-
-/**
- * Configuration Error thrown by a management agent.
- */
-public class AgentConfigurationError extends Error {
- public static final String AGENT_EXCEPTION =
- "agent.err.exception";
- public static final String CONFIG_FILE_NOT_FOUND =
- "agent.err.configfile.notfound";
- public static final String CONFIG_FILE_OPEN_FAILED =
- "agent.err.configfile.failed";
- public static final String CONFIG_FILE_CLOSE_FAILED =
- "agent.err.configfile.closed.failed";
- public static final String CONFIG_FILE_ACCESS_DENIED =
- "agent.err.configfile.access.denied";
- public static final String EXPORT_ADDRESS_FAILED =
- "agent.err.exportaddress.failed";
- public static final String AGENT_CLASS_NOT_FOUND =
- "agent.err.agentclass.notfound";
- public static final String AGENT_CLASS_FAILED =
- "agent.err.agentclass.failed";
- public static final String AGENT_CLASS_PREMAIN_NOT_FOUND =
- "agent.err.premain.notfound";
- public static final String AGENT_CLASS_ACCESS_DENIED =
- "agent.err.agentclass.access.denied";
- public static final String AGENT_CLASS_INVALID =
- "agent.err.invalid.agentclass";
- public static final String INVALID_JMXREMOTE_PORT =
- "agent.err.invalid.jmxremote.port";
- public static final String INVALID_JMXREMOTE_RMI_PORT =
- "agent.err.invalid.jmxremote.rmi.port";
- public static final String PASSWORD_FILE_NOT_SET =
- "agent.err.password.file.notset";
- public static final String PASSWORD_FILE_NOT_READABLE =
- "agent.err.password.file.not.readable";
- public static final String PASSWORD_FILE_READ_FAILED =
- "agent.err.password.file.read.failed";
- public static final String PASSWORD_FILE_NOT_FOUND =
- "agent.err.password.file.notfound";
- public static final String ACCESS_FILE_NOT_SET =
- "agent.err.access.file.notset";
- public static final String ACCESS_FILE_NOT_READABLE =
- "agent.err.access.file.not.readable";
- public static final String ACCESS_FILE_READ_FAILED =
- "agent.err.access.file.read.failed";
- public static final String ACCESS_FILE_NOT_FOUND =
- "agent.err.access.file.notfound";
- public static final String PASSWORD_FILE_ACCESS_NOT_RESTRICTED =
- "agent.err.password.file.access.notrestricted";
- public static final String FILE_ACCESS_NOT_RESTRICTED =
- "agent.err.file.access.not.restricted";
- public static final String FILE_NOT_FOUND =
- "agent.err.file.not.found";
- public static final String FILE_NOT_READABLE =
- "agent.err.file.not.readable";
- public static final String FILE_NOT_SET =
- "agent.err.file.not.set";
- public static final String FILE_READ_FAILED =
- "agent.err.file.read.failed";
- public static final String CONNECTOR_SERVER_IO_ERROR =
- "agent.err.connector.server.io.error";
- public static final String INVALID_OPTION =
- "agent.err.invalid.option";
- public static final String INVALID_STATE =
- "agent.err.invalid.state";
-
- private final String error;
- private final String[] params;
-
- public AgentConfigurationError(String error) {
- super();
- this.error = error;
- this.params = null;
- }
-
- public AgentConfigurationError(String error, Throwable cause) {
- super(cause);
- this.error = error;
- this.params = null;
- }
-
- public AgentConfigurationError(String error, String... params) {
- super();
- this.error = error;
- this.params = params.clone();
- }
-
- public AgentConfigurationError(String error, Throwable cause, String... params) {
- super(cause);
- this.error = error;
- this.params = params.clone();
- }
-
- public String getError() {
- return error;
- }
-
- public String[] getParams() {
- return params.clone();
- }
-
- private static final long serialVersionUID = 1211605593516195475L;
-}
--- a/jdk/src/java.management/share/classes/sun/management/ConnectorAddressLink.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +0,0 @@
-/*
- * 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
- * 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 sun.management;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import jdk.internal.perf.Perf;
-import sun.management.counter.Units;
-import sun.management.counter.Counter;
-import sun.management.counter.perf.PerfInstrumentation;
-
-/**
- * A utility class to support the exporting and importing of the address
- * of a connector server using the instrumentation buffer.
- *
- * @since 1.5
- */
-public class ConnectorAddressLink {
- /**
- * A simple wrapper for the perf-counter backing {@linkplain ByteBuffer}
- */
- private static final class PerfHandle {
- private ByteBuffer bb;
-
- private PerfHandle(ByteBuffer bb) {
- this.bb = bb.order(ByteOrder.nativeOrder());
- }
-
- private void putLong(long l) {
- this.bb = bb.clear();
- this.bb.asLongBuffer().put(l);
- }
- }
-
- private static final String CONNECTOR_ADDRESS_COUNTER =
- "sun.management.JMXConnectorServer.address";
- private static final String REMOTE_CONNECTOR_STATE_COUNTER =
- "sun.management.JMXConnectorServer.remote.enabled";
-
- /*
- * The format of the jvmstat counters representing the properties of
- * a given out-of-the-box JMX remote connector will be as follows:
- *
- * sun.management.JMXConnectorServer.<counter>.<key>=<value>
- *
- * where:
- *
- * counter = index computed by this class which uniquely identifies
- * an out-of-the-box JMX remote connector running in this
- * Java virtual machine.
- * key/value = a given key/value pair in the map supplied to the
- * exportRemote() method.
- *
- * For example,
- *
- * sun.management.JMXConnectorServer.0.remoteAddress=service:jmx:rmi:///jndi/rmi://myhost:5000/jmxrmi
- * sun.management.JMXConnectorServer.0.authenticate=false
- * sun.management.JMXConnectorServer.0.ssl=false
- * sun.management.JMXConnectorServer.0.sslRegistry=false
- * sun.management.JMXConnectorServer.0.sslNeedClientAuth=false
- */
- private static final String REMOTE_CONNECTOR_COUNTER_PREFIX =
- "sun.management.JMXConnectorServer.";
-
- /*
- * JMX remote connector counter (it will be incremented every
- * time a new out-of-the-box JMX remote connector is created).
- */
- private static final AtomicInteger counter = new AtomicInteger();
-
- private static PerfHandle remotePerfHandle = null;
-
- /**
- * Exports the specified connector address to the instrumentation buffer
- * so that it can be read by this or other Java virtual machines running
- * on the same system.
- *
- * @param address The connector address.
- */
- public static void export(String address) {
- if (address == null || address.length() == 0) {
- throw new IllegalArgumentException("address not specified");
- }
- Perf perf = Perf.getPerf();
- perf.createString(
- CONNECTOR_ADDRESS_COUNTER, 1, Units.STRING.intValue(), address);
- }
-
- public static void unexportRemote() {
- unexport(remotePerfHandle);
- }
-
- private static void unexport(PerfHandle ph) {
- if (ph != null) {
- ph.putLong(-1L);
- }
- }
-
- /**
- * Imports the connector address from the instrument buffer
- * of the specified Java virtual machine.
- *
- * @param vmid an identifier that uniquely identifies a local Java virtual
- * machine, or <code>0</code> to indicate the current Java virtual machine.
- *
- * @return the value of the connector address, or <code>null</code> if the
- * target VM has not exported a connector address.
- *
- * @throws IOException An I/O error occurred while trying to acquire the
- * instrumentation buffer.
- */
- public static String importFrom(int vmid) throws IOException {
- Perf perf = Perf.getPerf();
- ByteBuffer bb;
- try {
- bb = perf.attach(vmid, "r");
- } catch (IllegalArgumentException iae) {
- throw new IOException(iae.getMessage());
- }
- List<Counter> counters =
- new PerfInstrumentation(bb).findByPattern(CONNECTOR_ADDRESS_COUNTER);
- Iterator<Counter> i = counters.iterator();
- if (i.hasNext()) {
- Counter c = i.next();
- return (String) c.getValue();
- } else {
- return null;
- }
- }
-
- /**
- * Exports the specified remote connector address and associated
- * configuration properties to the instrumentation buffer so that
- * it can be read by this or other Java virtual machines running
- * on the same system.
- *
- * @param properties The remote connector address properties.
- */
- public static void exportRemote(Map<String, String> properties) {
- final int index = counter.getAndIncrement();
- Perf perf = Perf.getPerf();
- for (Map.Entry<String, String> entry : properties.entrySet()) {
- perf.createString(REMOTE_CONNECTOR_COUNTER_PREFIX + index + "." +
- entry.getKey(), 1, Units.STRING.intValue(), entry.getValue());
- }
- if (remotePerfHandle != null) {
- remotePerfHandle.putLong(index);
- } else {
- remotePerfHandle = new PerfHandle(
- perf.createLong(REMOTE_CONNECTOR_STATE_COUNTER, 1, Units.NONE.intValue(), (long)index)
- );
- }
- }
-
- /**
- * Imports the remote connector address and associated
- * configuration properties from the instrument buffer
- * of the specified Java virtual machine.
- *
- * @param vmid an identifier that uniquely identifies a local Java virtual
- * machine, or <code>0</code> to indicate the current Java virtual machine.
- *
- * @return a map containing the remote connector's properties, or an empty
- * map if the target VM has not exported the remote connector's properties.
- *
- * @throws IOException An I/O error occurred while trying to acquire the
- * instrumentation buffer.
- */
- public static Map<String, String> importRemoteFrom(int vmid) throws IOException {
- Perf perf = Perf.getPerf();
- ByteBuffer bb;
- try {
- bb = perf.attach(vmid, "r");
- } catch (IllegalArgumentException iae) {
- throw new IOException(iae.getMessage());
- }
- List<Counter> counters = new PerfInstrumentation(bb).getAllCounters();
- Map<String, String> properties = new HashMap<>();
- for (Counter c : counters) {
- String name = c.getName();
- if (name.startsWith(REMOTE_CONNECTOR_COUNTER_PREFIX) &&
- !name.equals(CONNECTOR_ADDRESS_COUNTER)) {
- properties.put(name, c.getValue().toString());
- }
- }
- return properties;
- }
-}
--- a/jdk/src/java.management/share/classes/sun/management/FileSystem.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2004, 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 sun.management;
-
-import java.io.File;
-import java.io.IOException;
-
-/*
- * Utility class to support file system operations
- *
- * @since 1.5
- */
-public abstract class FileSystem {
-
- private static final Object lock = new Object();
- private static FileSystem fs;
-
- protected FileSystem() { }
-
- /**
- * Opens the file system
- */
- public static FileSystem open() {
- synchronized (lock) {
- if (fs == null) {
- fs = new FileSystemImpl();
- }
- return fs;
- }
- }
-
- /**
- * Tells whether or not the specified file is located on a
- * file system that supports file security or not.
- *
- * @throws IOException if an I/O error occurs.
- */
- public abstract boolean supportsFileSecurity(File f) throws IOException;
-
- /**
- * Tell whether or not the specified file is accessible
- * by anything other than the file owner.
- *
- * @throws IOException if an I/O error occurs.
- *
- * @throws UnsupportedOperationException
- * If file is located on a file system that doesn't support
- * file security.
- */
- public abstract boolean isAccessUserOnly(File f) throws IOException;
-}
--- a/jdk/src/java.management/share/classes/sun/management/jdp/JdpBroadcaster.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.management.jdp;
-
-import java.io.IOException;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.NetworkInterface;
-import java.net.ProtocolFamily;
-import java.net.StandardProtocolFamily;
-import java.net.StandardSocketOptions;
-import java.nio.ByteBuffer;
-import java.nio.channels.DatagramChannel;
-import java.nio.channels.UnsupportedAddressTypeException;
-import java.util.Enumeration;
-
-/**
- * JdpBroadcaster is responsible for sending pre-built JDP packet across a Net
- *
- * <p> Multicast group address, port number and ttl have to be chosen on upper
- * level and passed to broadcaster constructor. Also it's possible to specify
- * source address to broadcast from. </p>
- *
- * <p>JdpBradcaster doesn't perform any validation on a supplied {@code port} and {@code ttl} because
- * the allowed values depend on an operating system setup</p>
- *
- */
-public final class JdpBroadcaster {
-
- private final InetAddress addr;
- private final int port;
- private final DatagramChannel channel;
-
- /**
- * Create a new broadcaster
- *
- * @param address - multicast group address
- * @param srcAddress - address of interface we should use to broadcast.
- * @param port - udp port to use
- * @param ttl - packet ttl
- * @throws IOException
- */
- public JdpBroadcaster(InetAddress address, InetAddress srcAddress, int port, int ttl)
- throws IOException, JdpException {
- this.addr = address;
- this.port = port;
-
- ProtocolFamily family = (address instanceof Inet6Address)
- ? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
-
- channel = DatagramChannel.open(family);
- channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
- channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
-
- // with srcAddress equal to null, this constructor do exactly the same as
- // if srcAddress is not passed
- if (srcAddress != null) {
- // User requests particular interface to bind to
- NetworkInterface interf = NetworkInterface.getByInetAddress(srcAddress);
-
- if (interf == null) {
- throw new JdpException("Unable to get network interface for " + srcAddress.toString());
- }
-
- if (!interf.isUp()) {
- throw new JdpException(interf.getName() + " is not up.");
- }
-
- if (!interf.supportsMulticast()) {
- throw new JdpException(interf.getName() + " does not support multicast.");
- }
-
- try {
- channel.bind(new InetSocketAddress(srcAddress, 0));
- } catch (UnsupportedAddressTypeException ex) {
- throw new JdpException("Unable to bind to source address");
- }
- channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
- }
- }
-
- /**
- * Create a new broadcaster
- *
- * @param address - multicast group address
- * @param port - udp port to use
- * @param ttl - packet ttl
- * @throws IOException
- */
- public JdpBroadcaster(InetAddress address, int port, int ttl)
- throws IOException, JdpException {
- this(address, null, port, ttl);
- }
-
- /**
- * Broadcast pre-built packet
- *
- * @param packet - instance of JdpPacket
- * @throws IOException
- */
- public void sendPacket(JdpPacket packet)
- throws IOException {
- byte[] data = packet.getPacketData();
- // Unlike allocate/put wrap don't need a flip afterward
- ByteBuffer b = ByteBuffer.wrap(data);
- channel.send(b, new InetSocketAddress(addr, port));
- }
-
- /**
- * Shutdown broadcaster and close underlying socket channel
- *
- * @throws IOException
- */
- public void shutdown() throws IOException {
- channel.close();
- }
-}
--- a/jdk/src/java.management/share/classes/sun/management/jdp/JdpController.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,236 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.management.jdp;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-import java.util.UUID;
-
-import java.lang.management.ManagementFactory;
-import java.lang.management.RuntimeMXBean;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import sun.management.VMManagement;
-
-/**
- * JdpController is responsible to create and manage a broadcast loop.
- *
- * <p> Other part of code has no access to broadcast loop and have to use
- * provided static methods
- * {@link #startDiscoveryService(InetAddress,int,String,String) startDiscoveryService}
- * and {@link #stopDiscoveryService() stopDiscoveryService}
- * <p>{@link #startDiscoveryService(InetAddress,int,String,String) startDiscoveryService} could be called multiple
- * times as it stops the running service if it is necessary.
- * Call to {@link #stopDiscoveryService() stopDiscoveryService}
- * ignored if service isn't run.
- *
- *
- * <p> System properties below could be used to control broadcast loop behavior.
- * Property below have to be set explicitly in command line. It's not possible to
- * set it in management.config file. Careless changes of these properties could
- * lead to security or network issues.
- * <ul>
- * <li>com.sun.management.jdp.ttl - set ttl for broadcast packet</li>
- * <li>com.sun.management.jdp.pause - set broadcast interval in seconds</li>
- * <li>com.sun.management.jdp.source_addr - an address of interface to use for broadcast</li>
- * </ul>
- *
- * <p>null parameters values are filtered out on {@link JdpPacketWriter} level and
- * corresponding keys are not placed to packet.
- */
-public final class JdpController {
-
- private static class JDPControllerRunner implements Runnable {
-
- private final JdpJmxPacket packet;
- private final JdpBroadcaster bcast;
- private final int pause;
- private volatile boolean shutdown = false;
-
- private JDPControllerRunner(JdpBroadcaster bcast, JdpJmxPacket packet, int pause) {
- this.bcast = bcast;
- this.packet = packet;
- this.pause = pause;
- }
-
- @Override
- public void run() {
- try {
- while (!shutdown) {
- bcast.sendPacket(packet);
- try {
- Thread.sleep(this.pause);
- } catch (InterruptedException e) {
- // pass
- }
- }
-
- } catch (IOException e) {
- // pass;
- }
-
- // It's not possible to re-use controller,
- // nevertheless reset shutdown variable
- try {
- stop();
- bcast.shutdown();
- } catch (IOException ex) {
- // pass - ignore IOException during shutdown
- }
- }
-
- public void stop() {
- shutdown = true;
- }
- }
- private static JDPControllerRunner controller = null;
-
- private JdpController(){
- // Don't allow to instantiate this class.
- }
-
- // Utility to handle optional system properties
- // Parse an integer from string or return default if provided string is null
- private static int getInteger(String val, int dflt, String msg) throws JdpException {
- try {
- return (val == null) ? dflt : Integer.parseInt(val);
- } catch (NumberFormatException ex) {
- throw new JdpException(msg);
- }
- }
-
- // Parse an inet address from string or return default if provided string is null
- private static InetAddress getInetAddress(String val, InetAddress dflt, String msg) throws JdpException {
- try {
- return (val == null) ? dflt : InetAddress.getByName(val);
- } catch (UnknownHostException ex) {
- throw new JdpException(msg);
- }
- }
-
- // Get the process id of the current running Java process
- private static Integer getProcessId() {
- try {
- // Get the current process id using a reflection hack
- RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
- Field jvm = runtime.getClass().getDeclaredField("jvm");
- jvm.setAccessible(true);
-
- VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
- Method pid_method = mgmt.getClass().getDeclaredMethod("getProcessId");
- pid_method.setAccessible(true);
- Integer pid = (Integer) pid_method.invoke(mgmt);
- return pid;
- } catch(Exception ex) {
- return null;
- }
- }
-
-
- /**
- * Starts discovery service
- *
- * @param address - multicast group address
- * @param port - udp port to use
- * @param instanceName - name of running JVM instance
- * @param url - JMX service url
- * @throws IOException
- */
- public static synchronized void startDiscoveryService(InetAddress address, int port, String instanceName, String url)
- throws IOException, JdpException {
-
- // Limit packet to local subnet by default
- int ttl = getInteger(
- System.getProperty("com.sun.management.jdp.ttl"), 1,
- "Invalid jdp packet ttl");
-
- // Broadcast once a 5 seconds by default
- int pause = getInteger(
- System.getProperty("com.sun.management.jdp.pause"), 5,
- "Invalid jdp pause");
-
- // Converting seconds to milliseconds
- pause = pause * 1000;
-
- // Allow OS to choose broadcast source
- InetAddress sourceAddress = getInetAddress(
- System.getProperty("com.sun.management.jdp.source_addr"), null,
- "Invalid source address provided");
-
- // Generate session id
- UUID id = UUID.randomUUID();
-
- JdpJmxPacket packet = new JdpJmxPacket(id, url);
-
- // Don't broadcast whole command line for security reason.
- // Strip everything after first space
- String javaCommand = System.getProperty("sun.java.command");
- if (javaCommand != null) {
- String[] arr = javaCommand.split(" ", 2);
- packet.setMainClass(arr[0]);
- }
-
- // Put optional explicit java instance name to packet, if user doesn't specify
- // it the key is skipped. PacketWriter is responsible to skip keys having null value.
- packet.setInstanceName(instanceName);
-
- // Set rmi server hostname if it explicitly specified by user with
- // java.rmi.server.hostname
- String rmiHostname = System.getProperty("java.rmi.server.hostname");
- packet.setRmiHostname(rmiHostname);
-
- // Set broadcast interval
- packet.setBroadcastInterval(Integer.toString(pause));
-
- // Set process id
- Integer pid = getProcessId();
- if (pid != null) {
- packet.setProcessId(pid.toString());
- }
-
- JdpBroadcaster bcast = new JdpBroadcaster(address, sourceAddress, port, ttl);
-
- // Stop discovery service if it's already running
- stopDiscoveryService();
-
- controller = new JDPControllerRunner(bcast, packet, pause);
-
- Thread t = new Thread(null, controller, "JDP broadcaster", 0, false);
- t.setDaemon(true);
- t.start();
- }
-
- /**
- * Stop running discovery service,
- * it's safe to attempt to stop not started service
- */
- public static synchronized void stopDiscoveryService() {
- if ( controller != null ){
- controller.stop();
- controller = null;
- }
- }
-}
--- a/jdk/src/java.management/share/classes/sun/management/jdp/JdpException.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.management.jdp;
-
-/**
- * An Exception thrown if a JDP implementation encounters a problem.
- */
-public final class JdpException extends Exception {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * Construct a new JDP exception with a meaningful message
- *
- * @param msg - message
- */
- public JdpException(String msg) {
- super(msg);
- }
-}
--- a/jdk/src/java.management/share/classes/sun/management/jdp/JdpGenericPacket.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.management.jdp;
-
-/**
- * JdpGenericPacket responsible to provide fields
- * common for all Jdp packets
- */
-public abstract class JdpGenericPacket implements JdpPacket {
-
- /**
- * JDP protocol magic. Magic allows a reader to quickly select
- * JDP packets from a bunch of broadcast packets addressed to the same port
- * and broadcast group. Any packet intended to be parsed by JDP client
- * has to start from this magic.
- */
- private static final int MAGIC = 0xC0FFEE42;
-
- /**
- * Current version of protocol. Any implementation of this protocol has to
- * conform with the packet structure and the flow described in JEP-168
- */
- private static final short PROTOCOL_VERSION = 1;
-
- /**
- * Default do-nothing constructor
- */
- protected JdpGenericPacket(){
- // do nothing
- }
-
-
- /**
- * Validate protocol header magic field
- *
- * @param magic - value to validate
- * @throws JdpException
- */
- public static void checkMagic(int magic)
- throws JdpException {
- if (magic != MAGIC) {
- throw new JdpException("Invalid JDP magic header: " + magic);
- }
- }
-
- /**
- * Validate protocol header version field
- *
- * @param version - value to validate
- * @throws JdpException
- */
- public static void checkVersion(short version)
- throws JdpException {
-
- if (version > PROTOCOL_VERSION) {
- throw new JdpException("Unsupported protocol version: " + version);
- }
- }
-
- /**
- *
- * @return protocol magic
- */
- public static int getMagic() {
- return MAGIC;
- }
-
- /**
- *
- * @return current protocol version
- */
- public static short getVersion() {
- return PROTOCOL_VERSION;
- }
-}
--- a/jdk/src/java.management/share/classes/sun/management/jdp/JdpJmxPacket.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,245 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.management.jdp;
-
-import java.io.IOException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.UUID;
-
-/**
- * A packet to broadcasts JMX URL
- *
- * Fields:
- *
- * <ul>
- * <li>UUID - broadcast session ID, changed every time when we start/stop
- * discovery service</li>
- * <li>JMX_URL - URL to connect to JMX service</li>
- * <li>MAIN_CLASS - optional name of main class, filled from sun.java.command stripped for
- * security reason to first space</li>
- * <li>INSTANCE_NAME - optional custom name of particular instance as provided by customer</li>
- * </ul>
- */
-public final class JdpJmxPacket
- extends JdpGenericPacket
- implements JdpPacket {
-
- /**
- * Session ID
- */
- public final static String UUID_KEY = "DISCOVERABLE_SESSION_UUID";
- /**
- * Name of main class
- */
- public final static String MAIN_CLASS_KEY = "MAIN_CLASS";
- /**
- * JMX service URL
- */
- public final static String JMX_SERVICE_URL_KEY = "JMX_SERVICE_URL";
- /**
- * Name of Java instance
- */
- public final static String INSTANCE_NAME_KEY = "INSTANCE_NAME";
- /**
- * PID of java process, optional presented if it could be obtained
- */
- public final static String PROCESS_ID_KEY = "PROCESS_ID";
- /**
- * Hostname of rmi server, optional presented if user overrides rmi server
- * hostname by java.rmi.server.hostname property
- */
- public final static String RMI_HOSTNAME_KEY = "RMI_HOSTNAME";
- /**
- * Configured broadcast interval, optional
- */
- public final static String BROADCAST_INTERVAL_KEY = "BROADCAST_INTERVAL";
-
- private UUID id;
- private String mainClass;
- private String jmxServiceUrl;
- private String instanceName;
- private String processId;
- private String rmiHostname;
- private String broadcastInterval;
-
- /**
- * Create new instance from user provided data. Set mandatory fields
- *
- * @param id - java instance id
- * @param jmxServiceUrl - JMX service url
- */
- public JdpJmxPacket(UUID id, String jmxServiceUrl) {
- this.id = id;
- this.jmxServiceUrl = jmxServiceUrl;
- }
-
- /**
- * Create new instance from network data Parse packet and set fields.
- *
- * @param data - raw packet data as it came from a Net
- * @throws JdpException
- */
- public JdpJmxPacket(byte[] data)
- throws JdpException {
- JdpPacketReader reader;
-
- reader = new JdpPacketReader(data);
- Map<String, String> p = reader.getDiscoveryDataAsMap();
-
- String sId = p.get(UUID_KEY);
- this.id = (sId == null) ? null : UUID.fromString(sId);
- this.jmxServiceUrl = p.get(JMX_SERVICE_URL_KEY);
- this.mainClass = p.get(MAIN_CLASS_KEY);
- this.instanceName = p.get(INSTANCE_NAME_KEY);
- this.processId = p.get(PROCESS_ID_KEY);
- this.rmiHostname = p.get(RMI_HOSTNAME_KEY);
- this.broadcastInterval = p.get(BROADCAST_INTERVAL_KEY);
- }
-
- /**
- * Set main class field
- *
- * @param mainClass - main class of running app
- */
- public void setMainClass(String mainClass) {
- this.mainClass = mainClass;
- }
-
- /**
- * Set instance name field
- *
- * @param instanceName - name of instance as provided by customer
- */
- public void setInstanceName(String instanceName) {
- this.instanceName = instanceName;
- }
-
- /**
- * @return id of discovery session
- */
- public UUID getId() {
- return id;
- }
-
- /**
- *
- * @return main class field
- */
- public String getMainClass() {
- return mainClass;
- }
-
- /**
- *
- * @return JMX service URL
- */
- public String getJmxServiceUrl() {
- return jmxServiceUrl;
- }
-
- /**
- *
- * @return instance name
- */
- public String getInstanceName() {
- return instanceName;
- }
-
- public String getProcessId() {
- return processId;
- }
-
- public void setProcessId(String processId) {
- this.processId = processId;
- }
-
- public String getRmiHostname() {
- return rmiHostname;
- }
-
- public void setRmiHostname(String rmiHostname) {
- this.rmiHostname = rmiHostname;
- }
-
- public String getBroadcastInterval() {
- return broadcastInterval;
- }
-
- public void setBroadcastInterval(String broadcastInterval) {
- this.broadcastInterval = broadcastInterval;
- }
-
- /**
- *
- * @return assembled packet ready to be sent across a Net
- * @throws IOException
- */
- @Override
- public byte[] getPacketData() throws IOException {
- // Assemble packet from fields to byte array
- JdpPacketWriter writer;
- writer = new JdpPacketWriter();
- writer.addEntry(UUID_KEY, (id == null) ? null : id.toString());
- writer.addEntry(MAIN_CLASS_KEY, mainClass);
- writer.addEntry(JMX_SERVICE_URL_KEY, jmxServiceUrl);
- writer.addEntry(INSTANCE_NAME_KEY, instanceName);
- writer.addEntry(PROCESS_ID_KEY, processId);
- writer.addEntry(RMI_HOSTNAME_KEY, rmiHostname);
- writer.addEntry(BROADCAST_INTERVAL_KEY, broadcastInterval);
-
- return writer.getPacketBytes();
- }
-
- /**
- *
- * @return packet hash code
- */
- @Override
- public int hashCode() {
- int hash = 1;
- hash = hash * 31 + id.hashCode();
- hash = hash * 31 + jmxServiceUrl.hashCode();
- return hash;
- }
-
- /**
- * Compare two packets
- *
- * @param o - packet to compare
- * @return either packet equals or not
- */
- @Override
- public boolean equals(Object o) {
-
- if (o == null || ! (o instanceof JdpJmxPacket) ){
- return false;
- }
-
- JdpJmxPacket p = (JdpJmxPacket) o;
- return Objects.equals(id, p.getId()) && Objects.equals(jmxServiceUrl, p.getJmxServiceUrl());
- }
-}
--- a/jdk/src/java.management/share/classes/sun/management/jdp/JdpPacket.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.management.jdp;
-
-import java.io.IOException;
-
-/**
- * Packet to broadcast
- *
- * <p>Each packet have to contain MAGIC and PROTOCOL_VERSION in order to be
- * recognized as a valid JDP packet.</p>
- *
- * <p>Default implementation build packet as a set of UTF-8 encoded Key/Value pairs
- * are stored as an ordered list of values, and are sent to the server
- * in that order.</p>
- *
- * <p>
- * Packet structure:
- *
- * 4 bytes JDP magic (0xC0FFE42)
- * 2 bytes JDP protocol version (01)
- *
- * 2 bytes size of key
- * x bytes key (UTF-8 encoded)
- * 2 bytes size of value
- * x bytes value (UTF-8 encoded)
- *
- * repeat as many times as necessary ...
- * </p>
- */
-public interface JdpPacket {
-
- /**
- * This method responsible to assemble packet and return a byte array
- * ready to be sent across a Net.
- *
- * @return assembled packet as an array of bytes
- * @throws IOException
- */
- public byte[] getPacketData() throws IOException;
-
-}
--- a/jdk/src/java.management/share/classes/sun/management/jdp/JdpPacketReader.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.management.jdp;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * JdpPacketReader responsible for reading a packet <p>This class gets a byte
- * array as it came from a Net, validates it and breaks a part </p>
- */
-public final class JdpPacketReader {
-
- private final DataInputStream pkt;
- private Map<String, String> pmap = null;
-
- /**
- * Create packet reader, extract and check magic and version
- *
- * @param packet - packet received from a Net
- * @throws JdpException
- */
- public JdpPacketReader(byte[] packet)
- throws JdpException {
- ByteArrayInputStream bais = new ByteArrayInputStream(packet);
- pkt = new DataInputStream(bais);
-
- try {
- int magic = pkt.readInt();
- JdpGenericPacket.checkMagic(magic);
- } catch (IOException e) {
- throw new JdpException("Invalid JDP packet received, bad magic");
- }
-
- try {
- short version = pkt.readShort();
- JdpGenericPacket.checkVersion(version);
- } catch (IOException e) {
- throw new JdpException("Invalid JDP packet received, bad protocol version");
- }
- }
-
- /**
- * Get next entry from packet
- *
- * @return the entry
- * @throws EOFException
- * @throws JdpException
- */
- public String getEntry()
- throws EOFException, JdpException {
-
- try {
- short len = pkt.readShort();
- // Artificial setting the "len" field to Short.MAX_VALUE may cause a reader to allocate
- // to much memory. Prevent this possible DOS attack.
- if (len < 1 && len > pkt.available()) {
- throw new JdpException("Broken JDP packet. Invalid entry length field.");
- }
-
- byte[] b = new byte[len];
- if (pkt.read(b) != len) {
- throw new JdpException("Broken JDP packet. Unable to read entry.");
- }
- return new String(b, "UTF-8");
-
- } catch (EOFException e) {
- throw e;
- } catch (UnsupportedEncodingException ex) {
- throw new JdpException("Broken JDP packet. Unable to decode entry.");
- } catch (IOException e) {
- throw new JdpException("Broken JDP packet. Unable to read entry.");
- }
-
-
- }
-
- /**
- * return packet content as a key/value map
- *
- * @return map containing packet entries pair of entries treated as
- * key,value
- * @throws IOException
- * @throws JdpException
- */
- public Map<String, String> getDiscoveryDataAsMap()
- throws JdpException {
- // return cached map if possible
- if (pmap != null) {
- return pmap;
- }
-
- String key = null, value = null;
-
- final Map<String, String> tmpMap = new HashMap<>();
- try {
- while (true) {
- key = getEntry();
- value = getEntry();
- tmpMap.put(key, value);
- }
- } catch (EOFException e) {
- // EOF reached on reading value, report broken packet
- // otherwise ignore it.
- if (value == null) {
- throw new JdpException("Broken JDP packet. Key without value." + key);
- }
- }
-
- pmap = Collections.unmodifiableMap(tmpMap);
- return pmap;
- }
-}
--- a/jdk/src/java.management/share/classes/sun/management/jdp/JdpPacketWriter.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.management.jdp;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-
-/**
- * JdpPacketWriter responsible for writing a packet
- * <p>This class assembles a set of key/value pairs to valid JDP packet,
- * ready to be sent across a Net</p>
- */
-public final class JdpPacketWriter {
-
- private final ByteArrayOutputStream baos;
- private final DataOutputStream pkt;
-
- /**
- * Create a JDP packet, add mandatory magic and version headers
- *
- * @throws IOException
- */
- public JdpPacketWriter()
- throws IOException {
- baos = new ByteArrayOutputStream();
- pkt = new DataOutputStream(baos);
-
- pkt.writeInt(JdpGenericPacket.getMagic());
- pkt.writeShort(JdpGenericPacket.getVersion());
- }
-
- /**
- * Put string entry to packet
- *
- * @param entry - string to put (utf-8 encoded)
- * @throws IOException
- */
- public void addEntry(String entry)
- throws IOException {
- /* DataOutputStream.writeUTF() do essentially
- * the same as:
- * pkt.writeShort(entry.getBytes("UTF-8").length);
- * pkt.write(entry.getBytes("UTF-8"));
- */
- pkt.writeUTF(entry);
- }
-
- /**
- * Put key/value pair to packet
- *
- * @param key - key to put (utf-8 encoded)
- * @param val - value to put (utf-8 encoded)
- * @throws IOException
- */
- public void addEntry(String key, String val)
- throws IOException {
- /* Silently skip key if value is null.
- * We don't need to distinguish between key missing
- * and key has no value cases
- */
- if (val != null) {
- addEntry(key);
- addEntry(val);
- }
- }
-
- /**
- * Return assembled packet as a byte array
- *
- * @return packet bytes
- */
- public byte[] getPacketBytes() {
- return baos.toByteArray();
- }
-}
--- a/jdk/src/java.management/share/classes/sun/management/jdp/package-info.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-/**
- * Summary
- * -------
- *
- * Define a lightweight network protocol for discovering running and
- * manageable Java processes within a network subnet.
- *
- *
- * Description
- * -----------
- *
- * The protocol is lightweight multicast based, and works like a beacon,
- * broadcasting the JMXService URL needed to connect to the external JMX
- * agent if an application is started with appropriate parameters.
- *
- * The payload is structured like this:
- *
- * 4 bytes JDP magic (0xC0FFEE42)
- * 2 bytes JDP protocol version (1)
- * 2 bytes size of the next entry
- * x bytes next entry (UTF-8 encoded)
- * 2 bytes size of next entry
- * ... Rinse and repeat...
- *
- * The payload will be parsed as even entries being keys, odd entries being
- * values.
- *
- * The standard JDP packet contains four entries:
- *
- * - `DISCOVERABLE_SESSION_UUID` -- Unique id of the instance; this id changes every time
- * the discovery protocol starts and stops
- *
- * - `MAIN_CLASS` -- The value of the `sun.java.command` property
- *
- * - `JMX_SERVICE_URL` -- The URL to connect to the JMX agent
- *
- * - `INSTANCE_NAME` -- The user-provided name of the running instance
- *
- * The protocol sends packets to 224.0.23.178:7095 by default.
- *
- * The protocol uses system properties to control it's behaviour:
- * - `com.sun.management.jdp.port` -- override default port
- *
- * - `com.sun.management.jdp.address` -- override default address
- *
- * - `com.sun.management.jmxremote.autodiscovery` -- whether we should start autodiscovery or
- * not. Autodiscovery starts if and only if following conditions are met: (autodiscovery is
- * true OR (autodiscovery is not set AND jdp.port is set))
- *
- * - `com.sun.management.jdp.ttl` -- set ttl for broadcast packet, default is 1
- * - `com.sun.management.jdp.pause` -- set broadcast interval in seconds default is 5
- * - `com.sun.management.jdp.source_addr` -- an address of interface to use for broadcast
- */
-
-package sun.management.jdp;
--- a/jdk/src/java.management/share/classes/sun/management/jmxremote/ConnectorBootstrap.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1016 +0,0 @@
-/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management.jmxremote;
-
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.Serializable;
-import java.lang.management.ManagementFactory;
-import java.net.InetAddress;
-import java.net.MalformedURLException;
-import java.net.Socket;
-import java.net.ServerSocket;
-import java.net.UnknownHostException;
-import java.rmi.NoSuchObjectException;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.registry.Registry;
-import java.rmi.server.RMIClientSocketFactory;
-import java.rmi.server.RMIServerSocketFactory;
-import java.rmi.server.RMISocketFactory;
-import java.rmi.server.RemoteObject;
-import java.rmi.server.UnicastRemoteObject;
-import java.security.KeyStore;
-import java.security.Principal;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Properties;
-import java.util.Set;
-import java.util.StringTokenizer;
-
-import javax.management.MBeanServer;
-import javax.management.remote.JMXAuthenticator;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerFactory;
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.rmi.RMIConnectorServer;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.TrustManagerFactory;
-import javax.rmi.ssl.SslRMIClientSocketFactory;
-import javax.rmi.ssl.SslRMIServerSocketFactory;
-import javax.security.auth.Subject;
-
-import com.sun.jmx.remote.internal.RMIExporter;
-import com.sun.jmx.remote.security.JMXPluggableAuthenticator;
-import com.sun.jmx.remote.util.ClassLogger;
-
-import sun.management.Agent;
-import sun.management.AgentConfigurationError;
-import static sun.management.AgentConfigurationError.*;
-import sun.management.ConnectorAddressLink;
-import sun.management.FileSystem;
-import sun.rmi.server.UnicastRef;
-import sun.rmi.server.UnicastServerRef;
-import sun.rmi.server.UnicastServerRef2;
-
-/**
- * This class initializes and starts the RMIConnectorServer for JSR 163
- * JMX Monitoring.
- **/
-public final class ConnectorBootstrap {
-
- /**
- * Default values for JMX configuration properties.
- **/
- public static interface DefaultValues {
-
- public static final String PORT = "0";
- public static final String CONFIG_FILE_NAME = "management.properties";
- public static final String USE_SSL = "true";
- public static final String USE_LOCAL_ONLY = "true";
- public static final String USE_REGISTRY_SSL = "false";
- public static final String USE_AUTHENTICATION = "true";
- public static final String PASSWORD_FILE_NAME = "jmxremote.password";
- public static final String ACCESS_FILE_NAME = "jmxremote.access";
- public static final String SSL_NEED_CLIENT_AUTH = "false";
- }
-
- /**
- * Names of JMX configuration properties.
- **/
- public static interface PropertyNames {
-
- public static final String PORT =
- "com.sun.management.jmxremote.port";
- public static final String HOST =
- "com.sun.management.jmxremote.host";
- public static final String RMI_PORT =
- "com.sun.management.jmxremote.rmi.port";
- public static final String CONFIG_FILE_NAME =
- "com.sun.management.config.file";
- public static final String USE_LOCAL_ONLY =
- "com.sun.management.jmxremote.local.only";
- public static final String USE_SSL =
- "com.sun.management.jmxremote.ssl";
- public static final String USE_REGISTRY_SSL =
- "com.sun.management.jmxremote.registry.ssl";
- public static final String USE_AUTHENTICATION =
- "com.sun.management.jmxremote.authenticate";
- public static final String PASSWORD_FILE_NAME =
- "com.sun.management.jmxremote.password.file";
- public static final String ACCESS_FILE_NAME =
- "com.sun.management.jmxremote.access.file";
- public static final String LOGIN_CONFIG_NAME =
- "com.sun.management.jmxremote.login.config";
- public static final String SSL_ENABLED_CIPHER_SUITES =
- "com.sun.management.jmxremote.ssl.enabled.cipher.suites";
- public static final String SSL_ENABLED_PROTOCOLS =
- "com.sun.management.jmxremote.ssl.enabled.protocols";
- public static final String SSL_NEED_CLIENT_AUTH =
- "com.sun.management.jmxremote.ssl.need.client.auth";
- public static final String SSL_CONFIG_FILE_NAME =
- "com.sun.management.jmxremote.ssl.config.file";
- }
-
- /**
- * JMXConnectorServer associated data.
- */
- private static class JMXConnectorServerData {
-
- public JMXConnectorServerData(
- JMXConnectorServer jmxConnectorServer,
- JMXServiceURL jmxRemoteURL) {
- this.jmxConnectorServer = jmxConnectorServer;
- this.jmxRemoteURL = jmxRemoteURL;
- }
- JMXConnectorServer jmxConnectorServer;
- JMXServiceURL jmxRemoteURL;
- }
-
- /**
- * <p>Prevents our RMI server objects from keeping the JVM alive.</p>
- *
- * <p>We use a private interface in Sun's JMX Remote API implementation
- * that allows us to specify how to export RMI objects. We do so using
- * UnicastServerRef, a class in Sun's RMI implementation. This is all
- * non-portable, of course, so this is only valid because we are inside
- * Sun's JRE.</p>
- *
- * <p>Objects are exported using {@link
- * UnicastServerRef#exportObject(Remote, Object, boolean)}. The
- * boolean parameter is called <code>permanent</code> and means
- * both that the object is not eligible for Distributed Garbage
- * Collection, and that its continued existence will not prevent
- * the JVM from exiting. It is the latter semantics we want (we
- * already have the former because of the way the JMX Remote API
- * works). Hence the somewhat misleading name of this class.</p>
- */
- private static class PermanentExporter implements RMIExporter {
-
- public Remote exportObject(Remote obj,
- int port,
- RMIClientSocketFactory csf,
- RMIServerSocketFactory ssf)
- throws RemoteException {
-
- synchronized (this) {
- if (firstExported == null) {
- firstExported = obj;
- }
- }
-
- final UnicastServerRef ref;
- if (csf == null && ssf == null) {
- ref = new UnicastServerRef(port);
- } else {
- ref = new UnicastServerRef2(port, csf, ssf);
- }
- return ref.exportObject(obj, null, true);
- }
-
- // Nothing special to be done for this case
- public boolean unexportObject(Remote obj, boolean force)
- throws NoSuchObjectException {
- return UnicastRemoteObject.unexportObject(obj, force);
- }
- Remote firstExported;
- }
-
- /**
- * This JMXAuthenticator wraps the JMXPluggableAuthenticator and verifies
- * that at least one of the principal names contained in the authenticated
- * Subject is present in the access file.
- */
- private static class AccessFileCheckerAuthenticator
- implements JMXAuthenticator {
-
- public AccessFileCheckerAuthenticator(Map<String, Object> env) throws IOException {
- environment = env;
- accessFile = (String) env.get("jmx.remote.x.access.file");
- properties = propertiesFromFile(accessFile);
- }
-
- public Subject authenticate(Object credentials) {
- final JMXAuthenticator authenticator =
- new JMXPluggableAuthenticator(environment);
- final Subject subject = authenticator.authenticate(credentials);
- checkAccessFileEntries(subject);
- return subject;
- }
-
- private void checkAccessFileEntries(Subject subject) {
- if (subject == null) {
- throw new SecurityException(
- "Access denied! No matching entries found in " +
- "the access file [" + accessFile + "] as the " +
- "authenticated Subject is null");
- }
- final Set<Principal> principals = subject.getPrincipals();
- for (Principal p1: principals) {
- if (properties.containsKey(p1.getName())) {
- return;
- }
- }
-
- final Set<String> principalsStr = new HashSet<>();
- for (Principal p2: principals) {
- principalsStr.add(p2.getName());
- }
- throw new SecurityException(
- "Access denied! No entries found in the access file [" +
- accessFile + "] for any of the authenticated identities " +
- principalsStr);
- }
-
- private static Properties propertiesFromFile(String fname)
- throws IOException {
- Properties p = new Properties();
- if (fname == null) {
- return p;
- }
- try (FileInputStream fin = new FileInputStream(fname)) {
- p.load(fin);
- }
- return p;
- }
- private final Map<String, Object> environment;
- private final Properties properties;
- private final String accessFile;
- }
-
- // The variable below is here to support stop functionality
- // It would be overriten if you call startRemoteCommectionServer second
- // time. It's OK for now as logic in Agent.java forbids mutiple agents
- private static Registry registry = null;
-
- public static void unexportRegistry() {
- // Remove the entry from registry
- try {
- if (registry != null) {
- UnicastRemoteObject.unexportObject(registry, true);
- registry = null;
- }
- } catch(NoSuchObjectException ex) {
- // This exception can appears only if we attempt
- // to unexportRegistry second time. So it's safe
- // to ignore it without additional messages.
- }
- }
-
- /**
- * Initializes and starts the JMX Connector Server.
- * If the com.sun.management.jmxremote.port property is not defined,
- * simply return. Otherwise, attempts to load the config file, and
- * then calls {@link #startRemoteConnectorServer
- * (java.lang.String, java.util.Properties)}.
- *
- * This method is used by some jtreg tests.
- **/
- public static synchronized JMXConnectorServer initialize() {
-
- // Load a new management properties
- final Properties props = Agent.loadManagementProperties();
- if (props == null) {
- return null;
- }
-
- final String portStr = props.getProperty(PropertyNames.PORT);
- return startRemoteConnectorServer(portStr, props);
- }
-
- /**
- * This method is used by some jtreg tests.
- *
- * @see #startRemoteConnectorServer
- * (String portStr, Properties props)
- */
- public static synchronized JMXConnectorServer initialize(String portStr, Properties props) {
- return startRemoteConnectorServer(portStr, props);
- }
-
- /**
- * Initializes and starts a JMX Connector Server for remote
- * monitoring and management.
- **/
- public static synchronized JMXConnectorServer startRemoteConnectorServer(String portStr, Properties props) {
-
- // Get port number
- final int port;
- try {
- port = Integer.parseInt(portStr);
- } catch (NumberFormatException x) {
- throw new AgentConfigurationError(INVALID_JMXREMOTE_PORT, x, portStr);
- }
- if (port < 0) {
- throw new AgentConfigurationError(INVALID_JMXREMOTE_PORT, portStr);
- }
-
- // User can specify a port to be used to export rmi object,
- // in order to simplify firewall rules
- // if port is not specified random one will be allocated.
- int rmiPort = 0;
- String rmiPortStr = props.getProperty(PropertyNames.RMI_PORT);
- try {
- if (rmiPortStr != null) {
- rmiPort = Integer.parseInt(rmiPortStr);
- }
- } catch (NumberFormatException x) {
- throw new AgentConfigurationError(INVALID_JMXREMOTE_RMI_PORT, x, rmiPortStr);
- }
- if (rmiPort < 0) {
- throw new AgentConfigurationError(INVALID_JMXREMOTE_RMI_PORT, rmiPortStr);
- }
-
- // Do we use authentication?
- final String useAuthenticationStr =
- props.getProperty(PropertyNames.USE_AUTHENTICATION,
- DefaultValues.USE_AUTHENTICATION);
- final boolean useAuthentication =
- Boolean.valueOf(useAuthenticationStr).booleanValue();
-
- // Do we use SSL?
- final String useSslStr =
- props.getProperty(PropertyNames.USE_SSL,
- DefaultValues.USE_SSL);
- final boolean useSsl =
- Boolean.valueOf(useSslStr).booleanValue();
-
- // Do we use RMI Registry SSL?
- final String useRegistrySslStr =
- props.getProperty(PropertyNames.USE_REGISTRY_SSL,
- DefaultValues.USE_REGISTRY_SSL);
- final boolean useRegistrySsl =
- Boolean.valueOf(useRegistrySslStr).booleanValue();
-
- final String enabledCipherSuites =
- props.getProperty(PropertyNames.SSL_ENABLED_CIPHER_SUITES);
- String enabledCipherSuitesList[] = null;
- if (enabledCipherSuites != null) {
- StringTokenizer st = new StringTokenizer(enabledCipherSuites, ",");
- int tokens = st.countTokens();
- enabledCipherSuitesList = new String[tokens];
- for (int i = 0; i < tokens; i++) {
- enabledCipherSuitesList[i] = st.nextToken();
- }
- }
-
- final String enabledProtocols =
- props.getProperty(PropertyNames.SSL_ENABLED_PROTOCOLS);
- String enabledProtocolsList[] = null;
- if (enabledProtocols != null) {
- StringTokenizer st = new StringTokenizer(enabledProtocols, ",");
- int tokens = st.countTokens();
- enabledProtocolsList = new String[tokens];
- for (int i = 0; i < tokens; i++) {
- enabledProtocolsList[i] = st.nextToken();
- }
- }
-
- final String sslNeedClientAuthStr =
- props.getProperty(PropertyNames.SSL_NEED_CLIENT_AUTH,
- DefaultValues.SSL_NEED_CLIENT_AUTH);
- final boolean sslNeedClientAuth =
- Boolean.valueOf(sslNeedClientAuthStr).booleanValue();
-
- // Read SSL config file name
- final String sslConfigFileName =
- props.getProperty(PropertyNames.SSL_CONFIG_FILE_NAME);
-
- String loginConfigName = null;
- String passwordFileName = null;
- String accessFileName = null;
-
- // Initialize settings when authentication is active
- if (useAuthentication) {
-
- // Get non-default login configuration
- loginConfigName =
- props.getProperty(PropertyNames.LOGIN_CONFIG_NAME);
-
- if (loginConfigName == null) {
- // Get password file
- passwordFileName =
- props.getProperty(PropertyNames.PASSWORD_FILE_NAME,
- getDefaultFileName(DefaultValues.PASSWORD_FILE_NAME));
- checkPasswordFile(passwordFileName);
- }
-
- // Get access file
- accessFileName = props.getProperty(PropertyNames.ACCESS_FILE_NAME,
- getDefaultFileName(DefaultValues.ACCESS_FILE_NAME));
- checkAccessFile(accessFileName);
- }
-
- final String bindAddress =
- props.getProperty(PropertyNames.HOST);
-
- if (log.debugOn()) {
- log.debug("startRemoteConnectorServer",
- Agent.getText("jmxremote.ConnectorBootstrap.starting") +
- "\n\t" + PropertyNames.PORT + "=" + port +
- (bindAddress == null ? "" : "\n\t" + PropertyNames.HOST + "=" + bindAddress) +
- "\n\t" + PropertyNames.RMI_PORT + "=" + rmiPort +
- "\n\t" + PropertyNames.USE_SSL + "=" + useSsl +
- "\n\t" + PropertyNames.USE_REGISTRY_SSL + "=" + useRegistrySsl +
- "\n\t" + PropertyNames.SSL_CONFIG_FILE_NAME + "=" + sslConfigFileName +
- "\n\t" + PropertyNames.SSL_ENABLED_CIPHER_SUITES + "=" +
- enabledCipherSuites +
- "\n\t" + PropertyNames.SSL_ENABLED_PROTOCOLS + "=" +
- enabledProtocols +
- "\n\t" + PropertyNames.SSL_NEED_CLIENT_AUTH + "=" +
- sslNeedClientAuth +
- "\n\t" + PropertyNames.USE_AUTHENTICATION + "=" +
- useAuthentication +
- (useAuthentication ? (loginConfigName == null ? ("\n\t" + PropertyNames.PASSWORD_FILE_NAME + "=" +
- passwordFileName) : ("\n\t" + PropertyNames.LOGIN_CONFIG_NAME + "=" +
- loginConfigName)) : "\n\t" +
- Agent.getText("jmxremote.ConnectorBootstrap.noAuthentication")) +
- (useAuthentication ? ("\n\t" + PropertyNames.ACCESS_FILE_NAME + "=" +
- accessFileName) : "") +
- "");
- }
-
- final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- JMXConnectorServer cs = null;
- JMXServiceURL url = null;
- try {
- final JMXConnectorServerData data = exportMBeanServer(
- mbs, port, rmiPort, useSsl, useRegistrySsl,
- sslConfigFileName, enabledCipherSuitesList,
- enabledProtocolsList, sslNeedClientAuth,
- useAuthentication, loginConfigName,
- passwordFileName, accessFileName, bindAddress);
- cs = data.jmxConnectorServer;
- url = data.jmxRemoteURL;
- log.config("startRemoteConnectorServer",
- Agent.getText("jmxremote.ConnectorBootstrap.ready",
- url.toString()));
- } catch (Exception e) {
- throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString());
- }
- try {
- // Export remote connector address and associated configuration
- // properties to the instrumentation buffer.
- Map<String, String> properties = new HashMap<>();
- properties.put("remoteAddress", url.toString());
- properties.put("authenticate", useAuthenticationStr);
- properties.put("ssl", useSslStr);
- properties.put("sslRegistry", useRegistrySslStr);
- properties.put("sslNeedClientAuth", sslNeedClientAuthStr);
- ConnectorAddressLink.exportRemote(properties);
- } catch (Exception e) {
- // Remote connector server started but unable to export remote
- // connector address and associated configuration properties to
- // the instrumentation buffer - non-fatal error.
- log.debug("startRemoteConnectorServer", e);
- }
- return cs;
- }
-
- /*
- * Creates and starts a RMI Connector Server for "local" monitoring
- * and management.
- */
- public static JMXConnectorServer startLocalConnectorServer() {
- // Ensure cryptographically strong random number generater used
- // to choose the object number - see java.rmi.server.ObjID
- System.setProperty("java.rmi.server.randomIDs", "true");
-
- // This RMI server should not keep the VM alive
- Map<String, Object> env = new HashMap<>();
- env.put(RMIExporter.EXPORTER_ATTRIBUTE, new PermanentExporter());
- env.put(RMIConnectorServer.CREDENTIAL_TYPES, new String[]{
- String[].class.getName(), String.class.getName()
- });
-
- // The local connector server need only be available via the
- // loopback connection.
- String localhost = "localhost";
- InetAddress lh = null;
- try {
- lh = InetAddress.getByName(localhost);
- localhost = lh.getHostAddress();
- } catch (UnknownHostException x) {
- }
-
- // localhost unknown or (somehow) didn't resolve to
- // a loopback address.
- if (lh == null || !lh.isLoopbackAddress()) {
- localhost = "127.0.0.1";
- }
-
- MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
- try {
- JMXServiceURL url = new JMXServiceURL("rmi", localhost, 0);
- // Do we accept connections from local interfaces only?
- Properties props = Agent.getManagementProperties();
- if (props == null) {
- props = new Properties();
- }
- String useLocalOnlyStr = props.getProperty(
- PropertyNames.USE_LOCAL_ONLY, DefaultValues.USE_LOCAL_ONLY);
- boolean useLocalOnly = Boolean.valueOf(useLocalOnlyStr).booleanValue();
- if (useLocalOnly) {
- env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,
- new LocalRMIServerSocketFactory());
- }
- JMXConnectorServer server =
- JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
- server.start();
- return server;
- } catch (Exception e) {
- throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString());
- }
- }
-
- private static void checkPasswordFile(String passwordFileName) {
- if (passwordFileName == null || passwordFileName.length() == 0) {
- throw new AgentConfigurationError(PASSWORD_FILE_NOT_SET);
- }
- File file = new File(passwordFileName);
- if (!file.exists()) {
- throw new AgentConfigurationError(PASSWORD_FILE_NOT_FOUND, passwordFileName);
- }
-
- if (!file.canRead()) {
- throw new AgentConfigurationError(PASSWORD_FILE_NOT_READABLE, passwordFileName);
- }
-
- FileSystem fs = FileSystem.open();
- try {
- if (fs.supportsFileSecurity(file)) {
- if (!fs.isAccessUserOnly(file)) {
- final String msg = Agent.getText("jmxremote.ConnectorBootstrap.password.readonly",
- passwordFileName);
- log.config("startRemoteConnectorServer", msg);
- throw new AgentConfigurationError(PASSWORD_FILE_ACCESS_NOT_RESTRICTED,
- passwordFileName);
- }
- }
- } catch (IOException e) {
- throw new AgentConfigurationError(PASSWORD_FILE_READ_FAILED,
- e, passwordFileName);
- }
- }
-
- private static void checkAccessFile(String accessFileName) {
- if (accessFileName == null || accessFileName.length() == 0) {
- throw new AgentConfigurationError(ACCESS_FILE_NOT_SET);
- }
- File file = new File(accessFileName);
- if (!file.exists()) {
- throw new AgentConfigurationError(ACCESS_FILE_NOT_FOUND, accessFileName);
- }
-
- if (!file.canRead()) {
- throw new AgentConfigurationError(ACCESS_FILE_NOT_READABLE, accessFileName);
- }
- }
-
- private static void checkRestrictedFile(String restrictedFileName) {
- if (restrictedFileName == null || restrictedFileName.length() == 0) {
- throw new AgentConfigurationError(FILE_NOT_SET);
- }
- File file = new File(restrictedFileName);
- if (!file.exists()) {
- throw new AgentConfigurationError(FILE_NOT_FOUND, restrictedFileName);
- }
- if (!file.canRead()) {
- throw new AgentConfigurationError(FILE_NOT_READABLE, restrictedFileName);
- }
- FileSystem fs = FileSystem.open();
- try {
- if (fs.supportsFileSecurity(file)) {
- if (!fs.isAccessUserOnly(file)) {
- final String msg = Agent.getText(
- "jmxremote.ConnectorBootstrap.file.readonly",
- restrictedFileName);
- log.config("startRemoteConnectorServer", msg);
- throw new AgentConfigurationError(
- FILE_ACCESS_NOT_RESTRICTED, restrictedFileName);
- }
- }
- } catch (IOException e) {
- throw new AgentConfigurationError(
- FILE_READ_FAILED, e, restrictedFileName);
- }
- }
-
- /**
- * Compute the full path name for a default file.
- * @param basename basename (with extension) of the default file.
- * @return ${JRE}/conf/management/${basename}
- **/
- private static String getDefaultFileName(String basename) {
- final String fileSeparator = File.separator;
- return System.getProperty("java.home") + fileSeparator + "conf" +
- fileSeparator + "management" + fileSeparator +
- basename;
- }
-
- private static SslRMIServerSocketFactory createSslRMIServerSocketFactory(
- String sslConfigFileName,
- String[] enabledCipherSuites,
- String[] enabledProtocols,
- boolean sslNeedClientAuth,
- String bindAddress) {
- if (sslConfigFileName == null) {
- return new HostAwareSslSocketFactory(
- enabledCipherSuites,
- enabledProtocols,
- sslNeedClientAuth, bindAddress);
- } else {
- checkRestrictedFile(sslConfigFileName);
- try {
- // Load the SSL keystore properties from the config file
- Properties p = new Properties();
- try (InputStream in = new FileInputStream(sslConfigFileName)) {
- BufferedInputStream bin = new BufferedInputStream(in);
- p.load(bin);
- }
- String keyStore =
- p.getProperty("javax.net.ssl.keyStore");
- String keyStorePassword =
- p.getProperty("javax.net.ssl.keyStorePassword", "");
- String trustStore =
- p.getProperty("javax.net.ssl.trustStore");
- String trustStorePassword =
- p.getProperty("javax.net.ssl.trustStorePassword", "");
-
- char[] keyStorePasswd = null;
- if (keyStorePassword.length() != 0) {
- keyStorePasswd = keyStorePassword.toCharArray();
- }
-
- char[] trustStorePasswd = null;
- if (trustStorePassword.length() != 0) {
- trustStorePasswd = trustStorePassword.toCharArray();
- }
-
- KeyStore ks = null;
- if (keyStore != null) {
- ks = KeyStore.getInstance(KeyStore.getDefaultType());
- try (FileInputStream ksfis = new FileInputStream(keyStore)) {
- ks.load(ksfis, keyStorePasswd);
- }
- }
- KeyManagerFactory kmf = KeyManagerFactory.getInstance(
- KeyManagerFactory.getDefaultAlgorithm());
- kmf.init(ks, keyStorePasswd);
-
- KeyStore ts = null;
- if (trustStore != null) {
- ts = KeyStore.getInstance(KeyStore.getDefaultType());
- try (FileInputStream tsfis = new FileInputStream(trustStore)) {
- ts.load(tsfis, trustStorePasswd);
- }
- }
- TrustManagerFactory tmf = TrustManagerFactory.getInstance(
- TrustManagerFactory.getDefaultAlgorithm());
- tmf.init(ts);
-
- SSLContext ctx = SSLContext.getInstance("SSL");
- ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
-
- return new HostAwareSslSocketFactory(
- ctx,
- enabledCipherSuites,
- enabledProtocols,
- sslNeedClientAuth, bindAddress);
- } catch (Exception e) {
- throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString());
- }
- }
- }
-
- private static JMXConnectorServerData exportMBeanServer(
- MBeanServer mbs,
- int port,
- int rmiPort,
- boolean useSsl,
- boolean useRegistrySsl,
- String sslConfigFileName,
- String[] enabledCipherSuites,
- String[] enabledProtocols,
- boolean sslNeedClientAuth,
- boolean useAuthentication,
- String loginConfigName,
- String passwordFileName,
- String accessFileName,
- String bindAddress)
- throws IOException, MalformedURLException {
-
- /* Make sure we use non-guessable RMI object IDs. Otherwise
- * attackers could hijack open connections by guessing their
- * IDs. */
- System.setProperty("java.rmi.server.randomIDs", "true");
-
- JMXServiceURL url = new JMXServiceURL("rmi", bindAddress, rmiPort);
-
- Map<String, Object> env = new HashMap<>();
-
- PermanentExporter exporter = new PermanentExporter();
-
- env.put(RMIExporter.EXPORTER_ATTRIBUTE, exporter);
- env.put(RMIConnectorServer.CREDENTIAL_TYPES, new String[]{
- String[].class.getName(), String.class.getName()
- });
-
- boolean useSocketFactory = bindAddress != null && !useSsl;
-
- if (useAuthentication) {
- if (loginConfigName != null) {
- env.put("jmx.remote.x.login.config", loginConfigName);
- }
- if (passwordFileName != null) {
- env.put("jmx.remote.x.password.file", passwordFileName);
- }
-
- env.put("jmx.remote.x.access.file", accessFileName);
-
- if (env.get("jmx.remote.x.password.file") != null ||
- env.get("jmx.remote.x.login.config") != null) {
- env.put(JMXConnectorServer.AUTHENTICATOR,
- new AccessFileCheckerAuthenticator(env));
- }
- }
-
- RMIClientSocketFactory csf = null;
- RMIServerSocketFactory ssf = null;
-
- if (useSsl || useRegistrySsl) {
- csf = new SslRMIClientSocketFactory();
- ssf = createSslRMIServerSocketFactory(
- sslConfigFileName, enabledCipherSuites,
- enabledProtocols, sslNeedClientAuth, bindAddress);
- }
-
- if (useSsl) {
- env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE,
- csf);
- env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,
- ssf);
- }
-
- if (useSocketFactory) {
- ssf = new HostAwareSocketFactory(bindAddress);
- env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,
- ssf);
- }
-
- JMXConnectorServer connServer = null;
- try {
- connServer =
- JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
- connServer.start();
- } catch (IOException e) {
- if (connServer == null || connServer.getAddress() == null) {
- throw new AgentConfigurationError(CONNECTOR_SERVER_IO_ERROR,
- e, url.toString());
- } else {
- throw new AgentConfigurationError(CONNECTOR_SERVER_IO_ERROR,
- e, connServer.getAddress().toString());
- }
- }
-
- if (useRegistrySsl) {
- registry =
- new SingleEntryRegistry(port, csf, ssf,
- "jmxrmi", exporter.firstExported);
- } else if (useSocketFactory) {
- registry =
- new SingleEntryRegistry(port, csf, ssf,
- "jmxrmi", exporter.firstExported);
- } else {
- registry =
- new SingleEntryRegistry(port,
- "jmxrmi", exporter.firstExported);
- }
-
-
- int registryPort =
- ((UnicastRef) ((RemoteObject) registry).getRef()).getLiveRef().getPort();
- String jmxUrlStr = String.format("service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi",
- url.getHost(), registryPort);
- JMXServiceURL remoteURL = new JMXServiceURL(jmxUrlStr);
-
- /* Our exporter remembers the first object it was asked to
- export, which will be an RMIServerImpl appropriate for
- publication in our special registry. We could
- alternatively have constructed the RMIServerImpl explicitly
- and then constructed an RMIConnectorServer passing it as a
- parameter, but that's quite a bit more verbose and pulls in
- lots of knowledge of the RMI connector. */
-
- return new JMXConnectorServerData(connServer, remoteURL);
- }
-
- /**
- * This class cannot be instantiated.
- **/
- private ConnectorBootstrap() {
- }
-
- private static final ClassLogger log =
- new ClassLogger(ConnectorBootstrap.class.getPackage().getName(),
- "ConnectorBootstrap");
-
- private static class HostAwareSocketFactory implements RMIServerSocketFactory {
-
- private final String bindAddress;
-
- private HostAwareSocketFactory(String bindAddress) {
- this.bindAddress = bindAddress;
- }
-
- @Override
- public ServerSocket createServerSocket(int port) throws IOException {
- if (bindAddress == null) {
- return new ServerSocket(port);
- } else {
- try {
- InetAddress addr = InetAddress.getByName(bindAddress);
- return new ServerSocket(port, 0, addr);
- } catch (UnknownHostException e) {
- return new ServerSocket(port);
- }
- }
- }
- }
-
- private static class HostAwareSslSocketFactory extends SslRMIServerSocketFactory {
-
- private final String bindAddress;
- private final String[] enabledCipherSuites;
- private final String[] enabledProtocols;
- private final boolean needClientAuth;
- private final SSLContext context;
-
- private HostAwareSslSocketFactory(String[] enabledCipherSuites,
- String[] enabledProtocols,
- boolean sslNeedClientAuth,
- String bindAddress) throws IllegalArgumentException {
- this(null, enabledCipherSuites, enabledProtocols, sslNeedClientAuth, bindAddress);
- }
-
- private HostAwareSslSocketFactory(SSLContext ctx,
- String[] enabledCipherSuites,
- String[] enabledProtocols,
- boolean sslNeedClientAuth,
- String bindAddress) throws IllegalArgumentException {
- this.context = ctx;
- this.bindAddress = bindAddress;
- this.enabledProtocols = enabledProtocols;
- this.enabledCipherSuites = enabledCipherSuites;
- this.needClientAuth = sslNeedClientAuth;
- checkValues(ctx, enabledCipherSuites, enabledProtocols);
- }
-
- @Override
- public ServerSocket createServerSocket(int port) throws IOException {
- if (bindAddress != null) {
- try {
- InetAddress addr = InetAddress.getByName(bindAddress);
- return new SslServerSocket(port, 0, addr, context,
- enabledCipherSuites, enabledProtocols, needClientAuth);
- } catch (UnknownHostException e) {
- return new SslServerSocket(port, context,
- enabledCipherSuites, enabledProtocols, needClientAuth);
- }
- } else {
- return new SslServerSocket(port, context,
- enabledCipherSuites, enabledProtocols, needClientAuth);
- }
- }
-
- private static void checkValues(SSLContext context,
- String[] enabledCipherSuites,
- String[] enabledProtocols) throws IllegalArgumentException {
- // Force the initialization of the default at construction time,
- // rather than delaying it to the first time createServerSocket()
- // is called.
- //
- final SSLSocketFactory sslSocketFactory =
- context == null ?
- (SSLSocketFactory)SSLSocketFactory.getDefault() : context.getSocketFactory();
- SSLSocket sslSocket = null;
- if (enabledCipherSuites != null || enabledProtocols != null) {
- try {
- sslSocket = (SSLSocket) sslSocketFactory.createSocket();
- } catch (Exception e) {
- final String msg = "Unable to check if the cipher suites " +
- "and protocols to enable are supported";
- throw (IllegalArgumentException)
- new IllegalArgumentException(msg).initCause(e);
- }
- }
-
- // Check if all the cipher suites and protocol versions to enable
- // are supported by the underlying SSL/TLS implementation and if
- // true create lists from arrays.
- //
- if (enabledCipherSuites != null) {
- sslSocket.setEnabledCipherSuites(enabledCipherSuites);
- }
- if (enabledProtocols != null) {
- sslSocket.setEnabledProtocols(enabledProtocols);
- }
- }
- }
-
- private static class SslServerSocket extends ServerSocket {
-
- private static SSLSocketFactory defaultSSLSocketFactory;
- private final String[] enabledCipherSuites;
- private final String[] enabledProtocols;
- private final boolean needClientAuth;
- private final SSLContext context;
-
- private SslServerSocket(int port,
- SSLContext ctx,
- String[] enabledCipherSuites,
- String[] enabledProtocols,
- boolean needClientAuth) throws IOException {
- super(port);
- this.enabledProtocols = enabledProtocols;
- this.enabledCipherSuites = enabledCipherSuites;
- this.needClientAuth = needClientAuth;
- this.context = ctx;
- }
-
- private SslServerSocket(int port,
- int backlog,
- InetAddress bindAddr,
- SSLContext ctx,
- String[] enabledCipherSuites,
- String[] enabledProtocols,
- boolean needClientAuth) throws IOException {
- super(port, backlog, bindAddr);
- this.enabledProtocols = enabledProtocols;
- this.enabledCipherSuites = enabledCipherSuites;
- this.needClientAuth = needClientAuth;
- this.context = ctx;
- }
-
- @Override
- public Socket accept() throws IOException {
- final SSLSocketFactory sslSocketFactory =
- context == null ?
- getDefaultSSLSocketFactory() : context.getSocketFactory();
- Socket socket = super.accept();
- SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(
- socket, socket.getInetAddress().getHostName(),
- socket.getPort(), true);
- sslSocket.setUseClientMode(false);
- if (enabledCipherSuites != null) {
- sslSocket.setEnabledCipherSuites(enabledCipherSuites);
- }
- if (enabledProtocols != null) {
- sslSocket.setEnabledProtocols(enabledProtocols);
- }
- sslSocket.setNeedClientAuth(needClientAuth);
- return sslSocket;
- }
-
- private static synchronized SSLSocketFactory getDefaultSSLSocketFactory() {
- if (defaultSSLSocketFactory == null) {
- defaultSSLSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
- return defaultSSLSocketFactory;
- } else {
- return defaultSSLSocketFactory;
- }
- }
-
- }
-}
--- a/jdk/src/java.management/share/classes/sun/management/jmxremote/LocalRMIServerSocketFactory.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,135 +0,0 @@
-/*
- * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management.jmxremote;
-
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.SocketException;
-import java.rmi.server.RMIServerSocketFactory;
-import java.util.Enumeration;
-
-/**
- * This RMI server socket factory creates server sockets that
- * will only accept connection requests from clients running
- * on the host where the RMI remote objects have been exported.
- */
-public final class LocalRMIServerSocketFactory implements RMIServerSocketFactory {
- /**
- * Creates a server socket that only accepts connection requests from
- * clients running on the host where the RMI remote objects have been
- * exported.
- */
- public ServerSocket createServerSocket(int port) throws IOException {
- return new ServerSocket(port) {
- @Override
- public Socket accept() throws IOException {
- final Socket socket = super.accept();
- final InetAddress remoteAddr = socket.getInetAddress();
- final String msg = "The server sockets created using the " +
- "LocalRMIServerSocketFactory only accept connections " +
- "from clients running on the host where the RMI " +
- "remote objects have been exported.";
-
- if (remoteAddr == null) {
- // Though unlikeky, the socket could be already
- // closed... Send a more detailed message in
- // this case. Also avoid throwing NullPointerExceptiion
- //
- String details = "";
- if (socket.isClosed()) {
- details = " Socket is closed.";
- } else if (!socket.isConnected()) {
- details = " Socket is not connected";
- }
- try {
- socket.close();
- } catch (Exception ok) {
- // ok - this is just cleanup before throwing detailed
- // exception.
- }
- throw new IOException(msg +
- " Couldn't determine client address." +
- details);
- } else if (remoteAddr.isLoopbackAddress()) {
- // local address: accept the connection.
- return socket;
- }
- // Retrieve all the network interfaces on this host.
- Enumeration<NetworkInterface> nis;
- try {
- nis = NetworkInterface.getNetworkInterfaces();
- } catch (SocketException e) {
- try {
- socket.close();
- } catch (IOException ioe) {
- // Ignore...
- }
- throw new IOException(msg, e);
- }
- // Walk through the network interfaces to see
- // if any of them matches the client's address.
- // If true, then the client's address is local.
- while (nis.hasMoreElements()) {
- NetworkInterface ni = nis.nextElement();
- Enumeration<InetAddress> addrs = ni.getInetAddresses();
- while (addrs.hasMoreElements()) {
- InetAddress localAddr = addrs.nextElement();
- if (localAddr.equals(remoteAddr)) {
- return socket;
- }
- }
- }
- // The client's address is remote so refuse the connection.
- try {
- socket.close();
- } catch (IOException ioe) {
- // Ignore...
- }
- throw new IOException(msg);
- }
- };
- }
-
- /**
- * Two LocalRMIServerSocketFactory objects
- * are equal if they are of the same type.
- */
- @Override
- public boolean equals(Object obj) {
- return (obj instanceof LocalRMIServerSocketFactory);
- }
-
- /**
- * Returns a hash code value for this LocalRMIServerSocketFactory.
- */
- @Override
- public int hashCode() {
- return getClass().hashCode();
- }
-}
--- a/jdk/src/java.management/share/classes/sun/management/jmxremote/SingleEntryRegistry.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +0,0 @@
-/*
- * Copyright (c) 2003, 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.
- */
-
-/*
- * @author Sun Microsystems, Inc.
- * @build @BUILD_TAG_PLACEHOLDER@
- *
- * @COPYRIGHT_MINI_LEGAL_NOTICE_PLACEHOLDER@
- */
-
-package sun.management.jmxremote;
-
-import java.rmi.AccessException;
-import java.rmi.NotBoundException;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.server.RMIClientSocketFactory;
-import java.rmi.server.RMIServerSocketFactory;
-
-import sun.rmi.registry.RegistryImpl;
-
-/** A Registry that consists of a single entry that never changes. */
-public class SingleEntryRegistry extends RegistryImpl {
- SingleEntryRegistry(int port, String name, Remote object)
- throws RemoteException {
- super(port);
- this.name = name;
- this.object = object;
- }
-
- SingleEntryRegistry(int port,
- RMIClientSocketFactory csf,
- RMIServerSocketFactory ssf,
- String name,
- Remote object)
- throws RemoteException {
- super(port, csf, ssf);
- this.name = name;
- this.object = object;
- }
-
- public String[] list() {
- return new String[] {name};
- }
-
- public Remote lookup(String name) throws NotBoundException {
- if (name.equals(this.name))
- return object;
- throw new NotBoundException("Not bound: \"" + name + "\" (only " +
- "bound name is \"" + this.name + "\")");
- }
-
- public void bind(String name, Remote obj) throws AccessException {
- throw new AccessException("Cannot modify this registry");
- }
-
- public void rebind(String name, Remote obj) throws AccessException {
- throw new AccessException("Cannot modify this registry");
- }
-
- public void unbind(String name) throws AccessException {
- throw new AccessException("Cannot modify this registry");
- }
-
- private final String name;
- private final Remote object;
-
- private static final long serialVersionUID = -4897238949499730950L;
-}
--- a/jdk/src/java.management/share/classes/sun/management/jmxremote/package.html Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
-<html>
-<head>
-<!--
-
- Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
- DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-
- This code is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License version 2 only, as
- published by the Free Software Foundation. Oracle designates this
- particular file as subject to the "Classpath" exception as provided
- by Oracle in the LICENSE file that accompanied this code.
-
- This code is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- version 2 for more details (a copy is included in the LICENSE file that
- accompanied this code).
-
- You should have received a copy of the GNU General Public License version
- 2 along with this work; if not, write to the Free Software Foundation,
- Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-
- Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- or visit www.oracle.com if you need additional information or have any
- questions.
-
--->
-
-</head>
-<body bgcolor="white">
-
-Provides classes that make it possible to create a JMX RMI Connector Server
-at bootstrap for the JSR 163 instrumentation.
-
-@since 1.5
-</body>
-</html>
--- a/jdk/src/java.management/share/classes/sun/management/resources/agent.properties Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#
-# Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-agent.err.error = Error
-agent.err.exception = Exception thrown by the agent
-agent.err.warning = Warning
-
-agent.err.configfile.notfound = Config file not found
-agent.err.configfile.failed = Failed in reading the config file
-agent.err.configfile.closed.failed = Failed in closing the config file
-agent.err.configfile.access.denied = Access to the config file is denied
-
-agent.err.exportaddress.failed = Export of JMX connector address to instrumentation buffer failed
-
-agent.err.agentclass.notfound = Management agent class not found
-agent.err.agentclass.failed = Management agent class failed
-agent.err.premain.notfound = premain(String) does not exist in agent class
-agent.err.agentclass.access.denied = Access to premain(String) is denied
-agent.err.invalid.agentclass = Invalid com.sun.management.agent.class property value
-agent.err.invalid.state = Invalid agent state: {0}
-agent.err.invalid.jmxremote.port = Invalid com.sun.management.jmxremote.port number
-agent.err.invalid.jmxremote.rmi.port = Invalid com.sun.management.jmxremote.rmi.port number
-
-agent.err.file.not.set = File not specified
-agent.err.file.not.readable = File not readable
-agent.err.file.read.failed = Failed in reading the file
-agent.err.file.not.found = File not found
-agent.err.file.access.not.restricted = File read access must be restricted
-
-agent.err.password.file.notset = Password file is not specified but com.sun.management.jmxremote.authenticate=true
-agent.err.password.file.not.readable = Password file not readable
-agent.err.password.file.read.failed = Failed in reading the password file
-agent.err.password.file.notfound = Password file not found
-agent.err.password.file.access.notrestricted = Password file read access must be restricted
-
-agent.err.access.file.notset = Access file is not specified but com.sun.management.jmxremote.authenticate=true
-agent.err.access.file.not.readable = Access file not readable
-agent.err.access.file.read.failed = Failed in reading the access file
-agent.err.access.file.notfound = Access file not found
-
-agent.err.connector.server.io.error = JMX connector server communication error
-
-agent.err.invalid.option = Invalid option specified
-
-jmxremote.ConnectorBootstrap.starting = Starting JMX Connector Server:
-jmxremote.ConnectorBootstrap.noAuthentication = No Authentication
-jmxremote.ConnectorBootstrap.ready = JMX Connector ready at: {0}
-jmxremote.ConnectorBootstrap.password.readonly = Password file read access must be restricted: {0}
-jmxremote.ConnectorBootstrap.file.readonly = File read access must be restricted: {0}
--- a/jdk/src/java.management/share/classes/sun/management/resources/agent_de.properties Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#
-# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-agent.err.error = Fehler
-agent.err.exception = Ausnahme von Agent ausgel\u00F6st
-agent.err.warning = Warnung
-
-agent.err.configfile.notfound = Konfigurationsdatei wurde nicht gefunden
-agent.err.configfile.failed = Konfigurationsdatei konnte nicht gelesen werden
-agent.err.configfile.closed.failed = Konfigurationsdatei konnte nicht geschlossen werden
-agent.err.configfile.access.denied = Zugriff auf Konfigurationsdatei wurde abgelehnt
-
-agent.err.exportaddress.failed = Export der JMX-Connector-Adresse in Instrumentierungspuffer nicht erfolgreich
-
-agent.err.agentclass.notfound = Management Agent-Klasse nicht gefunden
-agent.err.agentclass.failed = Management Agent-Klasse nicht erfolgreich
-agent.err.premain.notfound = premain(String) ist in Agent-Klasse nicht vorhanden
-agent.err.agentclass.access.denied = Zugriff auf premain(String) wurde abgelehnt
-agent.err.invalid.agentclass = Ung\u00FCltiger Eigenschaftswert f\u00FCr com.sun.management.agent.class
-agent.err.invalid.state = Ung\u00FCltiger Agent-Zustand: {0}
-agent.err.invalid.jmxremote.port = Ung\u00FCltige Nummer f\u00FCr com.sun.management.jmxremote.port
-agent.err.invalid.jmxremote.rmi.port = Ung\u00FCltige Nummer f\u00FCr com.sun.management.jmxremote.rmi.port
-
-agent.err.file.not.set = Datei nicht angegeben
-agent.err.file.not.readable = Datei nicht lesbar
-agent.err.file.read.failed = Datei konnte nicht gelesen werden
-agent.err.file.not.found = Datei wurde nicht gefunden
-agent.err.file.access.not.restricted = Lesezugriff auf Datei muss eingeschr\u00E4nkt werden
-
-agent.err.password.file.notset = Es wurde keine Kennwortdatei angegeben, obwohl com.sun.management.jmxremote.authenticate auf "true" gesetzt ist
-agent.err.password.file.not.readable = Kennwortdatei nicht lesbar
-agent.err.password.file.read.failed = Kennwortdatei konnte nicht gelesen werden
-agent.err.password.file.notfound = Kennwortdatei nicht gefunden
-agent.err.password.file.access.notrestricted = Lesezugriff auf Kennwortdatei muss eingeschr\u00E4nkt werden
-
-agent.err.access.file.notset = Es wurde keine Zugriffsdatei angegeben, obwohl com.sun.management.jmxremote.authenticate auf "true" gesetzt ist
-agent.err.access.file.not.readable = Zugriffsdatei kann nicht gelesen werden
-agent.err.access.file.read.failed = Zugriffsdatei konnte nicht gelesen werden
-agent.err.access.file.notfound = Zugriffsdatei nicht gefunden
-
-agent.err.connector.server.io.error = Fehler bei JMX-Connector-Serverkommunikation
-
-agent.err.invalid.option = Ung\u00FCltige Option angegeben
-
-jmxremote.ConnectorBootstrap.starting = JMX-Connector-Server starten:
-jmxremote.ConnectorBootstrap.noAuthentication = Keine Authentifizierung
-jmxremote.ConnectorBootstrap.ready = JMX-Connector bereit unter: {0}
-jmxremote.ConnectorBootstrap.password.readonly = Lesezugriff auf Kennwortdatei muss eingeschr\u00E4nkt werden: {0}
-jmxremote.ConnectorBootstrap.file.readonly = Lesezugriff auf Datei muss eingeschr\u00E4nkt werden: {0}
--- a/jdk/src/java.management/share/classes/sun/management/resources/agent_es.properties Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#
-# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-agent.err.error = Error
-agent.err.exception = Excepci\u00F3n devuelta por el agente
-agent.err.warning = Advertencia
-
-agent.err.configfile.notfound = No se ha encontrado el archivo de configuraci\u00F3n
-agent.err.configfile.failed = Fallo al leer el archivo de configuraci\u00F3n
-agent.err.configfile.closed.failed = Fallo al cerrar el archivo de configuraci\u00F3n
-agent.err.configfile.access.denied = Acceso denegado al archivo de configuraci\u00F3n
-
-agent.err.exportaddress.failed = Fallo al exportar la direcci\u00F3n del conector JMX al buffer de instrumentaci\u00F3n
-
-agent.err.agentclass.notfound = Clase de agente de gesti\u00F3n no encontrada
-agent.err.agentclass.failed = Fallo de clase de agente de gesti\u00F3n
-agent.err.premain.notfound = premain(String) no existe en la clase del agente
-agent.err.agentclass.access.denied = Acceso denegado a premain(String)
-agent.err.invalid.agentclass = Valor de propiedad com.sun.management.agent.class no v\u00E1lido
-agent.err.invalid.state = Estado de agente no v\u00E1lido: {0}
-agent.err.invalid.jmxremote.port = N\u00FAmero com.sun.management.jmxremote.port no v\u00E1lido
-agent.err.invalid.jmxremote.rmi.port = N\u00FAmero com.sun.management.jmxremote.rmi.port no v\u00E1lido
-
-agent.err.file.not.set = Archivo no especificado
-agent.err.file.not.readable = Archivo ilegible
-agent.err.file.read.failed = Fallo al leer el archivo
-agent.err.file.not.found = Archivo no encontrado
-agent.err.file.access.not.restricted = El acceso de lectura al archivo debe ser restringido
-
-agent.err.password.file.notset = El archivo de contrase\u00F1as no se ha especificado, pero com.sun.management.jmxremote.authenticate=true
-agent.err.password.file.not.readable = No se puede leer el archivo de contrase\u00F1as
-agent.err.password.file.read.failed = Fallo al leer el archivo de contrase\u00F1as
-agent.err.password.file.notfound = Archivo de contrase\u00F1as no encontrado
-agent.err.password.file.access.notrestricted = Se debe restringir el acceso de lectura al archivo de contrase\u00F1as
-
-agent.err.access.file.notset = El archivo de acceso no se ha especificado, pero com.sun.management.jmxremote.authenticate=true
-agent.err.access.file.not.readable = No se puede leer el archivo de acceso
-agent.err.access.file.read.failed = Fallo al leer el archivo de acceso
-agent.err.access.file.notfound = Archivo de acceso no encontrado
-
-agent.err.connector.server.io.error = Error de comunicaci\u00F3n con el servidor de conector JMX
-
-agent.err.invalid.option = Opci\u00F3n especificada no v\u00E1lida
-
-jmxremote.ConnectorBootstrap.starting = Iniciando servidor de conector JMX:
-jmxremote.ConnectorBootstrap.noAuthentication = Sin autenticaci\u00F3n
-jmxremote.ConnectorBootstrap.ready = Conector JMX listo en: {0}
-jmxremote.ConnectorBootstrap.password.readonly = Se debe restringir el acceso de lectura al archivo de contrase\u00F1as: {0}
-jmxremote.ConnectorBootstrap.file.readonly = El acceso de lectura al archivo debe ser restringido: {0}
--- a/jdk/src/java.management/share/classes/sun/management/resources/agent_fr.properties Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#
-# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-agent.err.error = Erreur
-agent.err.exception = Exception envoy\u00E9e par l'agent
-agent.err.warning = Avertissement
-
-agent.err.configfile.notfound = Fichier de configuration introuvable
-agent.err.configfile.failed = Impossible de lire le fichier de configuration
-agent.err.configfile.closed.failed = Impossible de fermer le fichier de configuration
-agent.err.configfile.access.denied = Acc\u00E8s refus\u00E9 au fichier de configuration
-
-agent.err.exportaddress.failed = Impossible d'exporter l'adresse du connecteur JMX dans le tampon d'instrumentation
-
-agent.err.agentclass.notfound = Classe d'agents de gestion introuvable
-agent.err.agentclass.failed = Echec de la classe d'agents de gestion
-agent.err.premain.notfound = premain(String) n'existe pas dans la classe d'agents
-agent.err.agentclass.access.denied = Acc\u00E8s \u00E0 premain(String) refus\u00E9
-agent.err.invalid.agentclass = Valeur de propri\u00E9t\u00E9 com.sun.management.agent.class incorrecte
-agent.err.invalid.state = Etat de l''agent non valide : {0}
-agent.err.invalid.jmxremote.port = Num\u00E9ro com.sun.management.jmxremote.port incorrect
-agent.err.invalid.jmxremote.rmi.port = Num\u00E9ro com.sun.management.jmxremote.rmi.port non valide
-
-agent.err.file.not.set = Fichier non sp\u00E9cifi\u00E9
-agent.err.file.not.readable = Fichier illisible
-agent.err.file.read.failed = Impossible de lire le fichier
-agent.err.file.not.found = Fichier introuvable
-agent.err.file.access.not.restricted = L'acc\u00E8s en lecture au fichier doit \u00EAtre limit\u00E9
-
-agent.err.password.file.notset = Le fichier de mots de passe n'est pas sp\u00E9cifi\u00E9 mais com.sun.management.jmxremote.authenticate=true
-agent.err.password.file.not.readable = Fichier de mots de passe illisible
-agent.err.password.file.read.failed = Impossible de lire le fichier de mots de passe
-agent.err.password.file.notfound = Fichier de mots de passe introuvable
-agent.err.password.file.access.notrestricted = L'acc\u00E8s en lecture au fichier de mots de passe doit \u00EAtre limit\u00E9
-
-agent.err.access.file.notset = Le fichier d'acc\u00E8s n'est pas sp\u00E9cifi\u00E9 mais com.sun.management.jmxremote.authenticate=true
-agent.err.access.file.not.readable = Fichier d'acc\u00E8s illisible
-agent.err.access.file.read.failed = Impossible de lire le fichier d'acc\u00E8s
-agent.err.access.file.notfound = Fichier d'acc\u00E8s introuvable
-
-agent.err.connector.server.io.error = Erreur de communication avec le serveur du connecteur JMX
-
-agent.err.invalid.option = Option sp\u00E9cifi\u00E9e non valide
-
-jmxremote.ConnectorBootstrap.starting = D\u00E9marrage du serveur du connecteur JMX :
-jmxremote.ConnectorBootstrap.noAuthentication = Pas d'authentification
-jmxremote.ConnectorBootstrap.ready = Connecteur JMX pr\u00EAt \u00E0 : {0}
-jmxremote.ConnectorBootstrap.password.readonly = L''acc\u00E8s en lecture au fichier de mots de passe doit \u00EAtre limit\u00E9 : {0}
-jmxremote.ConnectorBootstrap.file.readonly = L''acc\u00E8s en lecture au fichier doit \u00EAtre limit\u00E9 : {0}
--- a/jdk/src/java.management/share/classes/sun/management/resources/agent_it.properties Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#
-# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-agent.err.error = Errore
-agent.err.exception = Eccezione dell'agente
-agent.err.warning = Avvertenza
-
-agent.err.configfile.notfound = File di configurazione non trovato
-agent.err.configfile.failed = Errore di lettura file di configurazione
-agent.err.configfile.closed.failed = Errore di chiusura file di configurazione
-agent.err.configfile.access.denied = Accesso negato al file di configurazione
-
-agent.err.exportaddress.failed = Errore di esportazione dell'indirizzo connettore JMX nel buffer strumenti
-
-agent.err.agentclass.notfound = Classe agente gestione non trovata
-agent.err.agentclass.failed = Errore classe agente gestione
-agent.err.premain.notfound = premain(String) non esiste nella classe agente
-agent.err.agentclass.access.denied = Accesso negato a premain(String)
-agent.err.invalid.agentclass = Valore propriet\u00E0 com.sun.management.agent.class non valido
-agent.err.invalid.state = Stato agente non valido: {0}
-agent.err.invalid.jmxremote.port = Numero com.sun.management.jmxremote.port non valido
-agent.err.invalid.jmxremote.rmi.port = Numero com.sun.management.jmxremote.rmi.port non valido
-
-agent.err.file.not.set = File non specificato
-agent.err.file.not.readable = File non leggibile
-agent.err.file.read.failed = Errore di lettura file
-agent.err.file.not.found = File non trovato
-agent.err.file.access.not.restricted = Limitare l'accesso in lettura al file
-
-agent.err.password.file.notset = Il password file non \u00E8 specificato ma com.sun.management.jmxremote.authenticate=true
-agent.err.password.file.not.readable = Password file non leggibile
-agent.err.password.file.read.failed = Errore di lettura password file
-agent.err.password.file.notfound = Password file non trovato
-agent.err.password.file.access.notrestricted = Limitare l'accesso in lettura al password file
-
-agent.err.access.file.notset = Il file di accesso non \u00E8 specificato ma com.sun.management.jmxremote.authenticate=true
-agent.err.access.file.not.readable = File di accesso non leggibile
-agent.err.access.file.read.failed = Errore di lettura file di accesso
-agent.err.access.file.notfound = File di accesso non trovato
-
-agent.err.connector.server.io.error = Errore di comunicazione server del connettore JMX
-
-agent.err.invalid.option = Specificata opzione non valida
-
-jmxremote.ConnectorBootstrap.starting = Avvio del server connettore JMX:
-jmxremote.ConnectorBootstrap.noAuthentication = Nessuna autenticazione
-jmxremote.ConnectorBootstrap.ready = Connettore JMX pronto in: {0}
-jmxremote.ConnectorBootstrap.password.readonly = Limitare l''accesso in lettura al password file: {0}
-jmxremote.ConnectorBootstrap.file.readonly = Limitare l''accesso in lettura al file: {0}
--- a/jdk/src/java.management/share/classes/sun/management/resources/agent_ja.properties Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#
-# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-agent.err.error = \u30A8\u30E9\u30FC
-agent.err.exception = \u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u304C\u4F8B\u5916\u3092\u30B9\u30ED\u30FC\u3057\u307E\u3057\u305F
-agent.err.warning = \u8B66\u544A
-
-agent.err.configfile.notfound = \u69CB\u6210\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
-agent.err.configfile.failed = \u69CB\u6210\u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u306B\u5931\u6557\u3057\u307E\u3057\u305F
-agent.err.configfile.closed.failed = \u69CB\u6210\u30D5\u30A1\u30A4\u30EB\u3092\u9589\u3058\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F
-agent.err.configfile.access.denied = \u69CB\u6210\u30D5\u30A1\u30A4\u30EB\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u304C\u62D2\u5426\u3055\u308C\u307E\u3057\u305F
-
-agent.err.exportaddress.failed = JMX\u30B3\u30CD\u30AF\u30BF\u30FB\u30A2\u30C9\u30EC\u30B9\u306E\u8A08\u6E2C\u30D0\u30C3\u30D5\u30A1\u3078\u306E\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u304C\u5931\u6557\u3057\u307E\u3057\u305F
-
-agent.err.agentclass.notfound = \u7BA1\u7406\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30AF\u30E9\u30B9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
-agent.err.agentclass.failed = \u7BA1\u7406\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30AF\u30E9\u30B9\u304C\u5931\u6557\u3057\u307E\u3057\u305F
-agent.err.premain.notfound = premain(String)\u304C\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30AF\u30E9\u30B9\u306B\u5B58\u5728\u3057\u307E\u305B\u3093
-agent.err.agentclass.access.denied = premain(String)\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u304C\u62D2\u5426\u3055\u308C\u307E\u3057\u305F
-agent.err.invalid.agentclass = com.sun.management.agent.class\u30D7\u30ED\u30D1\u30C6\u30A3\u306E\u5024\u304C\u7121\u52B9\u3067\u3059
-agent.err.invalid.state = \u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u306E\u72B6\u614B\u304C\u7121\u52B9\u3067\u3059: {0}
-agent.err.invalid.jmxremote.port = com.sun.management.jmxremote.port\u306E\u756A\u53F7\u304C\u7121\u52B9\u3067\u3059
-agent.err.invalid.jmxremote.rmi.port = com.sun.management.jmxremote.rmi.port\u306E\u756A\u53F7\u304C\u7121\u52B9\u3067\u3059
-
-agent.err.file.not.set = \u30D5\u30A1\u30A4\u30EB\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093
-agent.err.file.not.readable = \u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u307F\u53D6\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u305B\u3093
-agent.err.file.read.failed = \u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u306B\u5931\u6557\u3057\u307E\u3057\u305F
-agent.err.file.not.found = \u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F
-agent.err.file.access.not.restricted = \u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u30A2\u30AF\u30BB\u30B9\u306F\u5236\u9650\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
-
-agent.err.password.file.notset = \u30D1\u30B9\u30EF\u30FC\u30C9\u30FB\u30D5\u30A1\u30A4\u30EB\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u304C\u3001com.sun.management.jmxremote.authenticate=true\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059
-agent.err.password.file.not.readable = \u30D1\u30B9\u30EF\u30FC\u30C9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u307F\u53D6\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u305B\u3093
-agent.err.password.file.read.failed = \u30D1\u30B9\u30EF\u30FC\u30C9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u306B\u5931\u6557\u3057\u307E\u3057\u305F
-agent.err.password.file.notfound = \u30D1\u30B9\u30EF\u30FC\u30C9\u30FB\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
-agent.err.password.file.access.notrestricted = \u30D1\u30B9\u30EF\u30FC\u30C9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u30A2\u30AF\u30BB\u30B9\u306F\u5236\u9650\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
-
-agent.err.access.file.notset = \u30A2\u30AF\u30BB\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u304C\u3001com.sun.management.jmxremote.authenticate=true\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059
-agent.err.access.file.not.readable = \u30A2\u30AF\u30BB\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u307F\u53D6\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u305B\u3093
-agent.err.access.file.read.failed = \u30A2\u30AF\u30BB\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u306B\u5931\u6557\u3057\u307E\u3057\u305F
-agent.err.access.file.notfound = \u30A2\u30AF\u30BB\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
-
-agent.err.connector.server.io.error = JMX\u30B3\u30CD\u30AF\u30BF\u30FB\u30B5\u30FC\u30D0\u30FC\u306E\u901A\u4FE1\u30A8\u30E9\u30FC
-
-agent.err.invalid.option = \u7121\u52B9\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F
-
-jmxremote.ConnectorBootstrap.starting = JMX\u30B3\u30CD\u30AF\u30BF\u30FB\u30B5\u30FC\u30D0\u30FC\u3092\u8D77\u52D5\u3057\u3066\u3044\u307E\u3059:
-jmxremote.ConnectorBootstrap.noAuthentication = \u8A8D\u8A3C\u306A\u3057
-jmxremote.ConnectorBootstrap.ready = JMX\u30B3\u30CD\u30AF\u30BF\u306E\u6E96\u5099\u304C\u3067\u304D\u307E\u3057\u305F: {0}
-jmxremote.ConnectorBootstrap.password.readonly = \u30D1\u30B9\u30EF\u30FC\u30C9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u30A2\u30AF\u30BB\u30B9\u306F\u5236\u9650\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059: {0}
-jmxremote.ConnectorBootstrap.file.readonly = \u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u30A2\u30AF\u30BB\u30B9\u306F\u5236\u9650\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059: {0}
--- a/jdk/src/java.management/share/classes/sun/management/resources/agent_ko.properties Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#
-# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-agent.err.error = \uC624\uB958
-agent.err.exception = \uC5D0\uC774\uC804\uD2B8\uC5D0 \uC608\uC678\uC0AC\uD56D\uC774 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.
-agent.err.warning = \uACBD\uACE0
-
-agent.err.configfile.notfound = \uAD6C\uC131 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
-agent.err.configfile.failed = \uAD6C\uC131 \uD30C\uC77C \uC77D\uAE30\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.
-agent.err.configfile.closed.failed = \uAD6C\uC131 \uD30C\uC77C \uB2EB\uAE30\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.
-agent.err.configfile.access.denied = \uAD6C\uC131 \uD30C\uC77C\uC5D0 \uB300\uD55C \uC561\uC138\uC2A4\uAC00 \uAC70\uBD80\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
-
-agent.err.exportaddress.failed = \uAE30\uAE30 \uBC84\uD37C\uB85C JMX \uCEE4\uB125\uD130 \uC8FC\uC18C \uC775\uC2A4\uD3EC\uD2B8\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.
-
-agent.err.agentclass.notfound = \uAD00\uB9AC \uC5D0\uC774\uC804\uD2B8 \uD074\uB798\uC2A4\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
-agent.err.agentclass.failed = \uAD00\uB9AC \uC5D0\uC774\uC804\uD2B8 \uD074\uB798\uC2A4\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.
-agent.err.premain.notfound = \uC5D0\uC774\uC804\uD2B8 \uD074\uB798\uC2A4\uC5D0 premain(\uBB38\uC790\uC5F4)\uC774 \uC874\uC7AC\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
-agent.err.agentclass.access.denied = premain(\uBB38\uC790\uC5F4)\uC5D0 \uB300\uD55C \uC561\uC138\uC2A4\uAC00 \uAC70\uBD80\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
-agent.err.invalid.agentclass = com.sun.management.agent.class \uC18D\uC131 \uAC12\uC774 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4.
-agent.err.invalid.state = \uBD80\uC801\uD569\uD55C \uC5D0\uC774\uC804\uD2B8 \uC0C1\uD0DC: {0}
-agent.err.invalid.jmxremote.port = com.sun.management.jmxremote.port \uBC88\uD638\uAC00 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4.
-agent.err.invalid.jmxremote.rmi.port = \uBD80\uC801\uD569\uD55C com.sun.management.jmxremote.rmi.port \uBC88\uD638
-
-agent.err.file.not.set = \uD30C\uC77C\uC774 \uC9C0\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
-agent.err.file.not.readable = \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
-agent.err.file.read.failed = \uD30C\uC77C \uC77D\uAE30\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.
-agent.err.file.not.found = \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
-agent.err.file.access.not.restricted = \uD30C\uC77C \uC77D\uAE30 \uC561\uC138\uC2A4\uB294 \uC81C\uD55C\uB418\uC5B4\uC57C \uD569\uB2C8\uB2E4.
-
-agent.err.password.file.notset = \uBE44\uBC00\uBC88\uD638 \uD30C\uC77C\uC774 \uC9C0\uC815\uB418\uC9C0 \uC54A\uC558\uC9C0\uB9CC com.sun.management.jmxremote.authenticate=true\uC785\uB2C8\uB2E4.
-agent.err.password.file.not.readable = \uBE44\uBC00\uBC88\uD638 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
-agent.err.password.file.read.failed = \uBE44\uBC00\uBC88\uD638 \uD30C\uC77C \uC77D\uAE30\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.
-agent.err.password.file.notfound = \uBE44\uBC00\uBC88\uD638 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
-agent.err.password.file.access.notrestricted = \uBE44\uBC00\uBC88\uD638 \uD30C\uC77C \uC77D\uAE30 \uC561\uC138\uC2A4\uB294 \uC81C\uD55C\uB418\uC5B4\uC57C \uD569\uB2C8\uB2E4.
-
-agent.err.access.file.notset = \uC561\uC138\uC2A4 \uD30C\uC77C\uC774 \uC9C0\uC815\uB418\uC9C0 \uC54A\uC558\uC9C0\uB9CC com.sun.management.jmxremote.authenticate=true\uC785\uB2C8\uB2E4.
-agent.err.access.file.not.readable = \uC561\uC138\uC2A4 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
-agent.err.access.file.read.failed = \uC561\uC138\uC2A4 \uD30C\uC77C \uC77D\uAE30\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.
-agent.err.access.file.notfound = \uC561\uC138\uC2A4 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
-
-agent.err.connector.server.io.error = JMX \uCEE4\uB125\uD130 \uC11C\uBC84 \uD1B5\uC2E0 \uC624\uB958
-
-agent.err.invalid.option = \uBD80\uC801\uD569\uD55C \uC635\uC158\uC774 \uC9C0\uC815\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
-
-jmxremote.ConnectorBootstrap.starting = JMX \uCEE4\uB125\uD130 \uC11C\uBC84\uB97C \uC2DC\uC791\uD558\uB294 \uC911:
-jmxremote.ConnectorBootstrap.noAuthentication = \uC778\uC99D \uC5C6\uC74C
-jmxremote.ConnectorBootstrap.ready = {0}\uC5D0\uC11C JMX \uCEE4\uB125\uD130\uAC00 \uC900\uBE44\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
-jmxremote.ConnectorBootstrap.password.readonly = \uBE44\uBC00\uBC88\uD638 \uD30C\uC77C \uC77D\uAE30 \uC561\uC138\uC2A4\uB294 \uC81C\uD55C\uB418\uC5B4\uC57C \uD568: {0}
-jmxremote.ConnectorBootstrap.file.readonly = \uD30C\uC77C \uC77D\uAE30 \uC561\uC138\uC2A4\uB294 \uC81C\uD55C\uB418\uC5B4\uC57C \uD568: {0}
--- a/jdk/src/java.management/share/classes/sun/management/resources/agent_pt_BR.properties Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#
-# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-agent.err.error = Erro
-agent.err.exception = Exce\u00E7\u00E3o gerada pelo agente
-agent.err.warning = Advert\u00EAncia
-
-agent.err.configfile.notfound = Arquivo de configura\u00E7\u00E3o n\u00E3o encontrado
-agent.err.configfile.failed = Falha ao ler o arquivo de configura\u00E7\u00E3o
-agent.err.configfile.closed.failed = Falha ao fechar o arquivo de configura\u00E7\u00E3o
-agent.err.configfile.access.denied = Acesso negado ao arquivo de configura\u00E7\u00E3o
-
-agent.err.exportaddress.failed = Falha na exporta\u00E7\u00E3o do endere\u00E7o do conector JMX para o buffer de instrumenta\u00E7\u00E3o
-
-agent.err.agentclass.notfound = Classe do agente de gerenciamento n\u00E3o encontrada
-agent.err.agentclass.failed = Falha na classe do agente de gerenciamento
-agent.err.premain.notfound = premain(String) n\u00E3o existe na classe do agente
-agent.err.agentclass.access.denied = Acesso negado a premain(String)
-agent.err.invalid.agentclass = Valor inv\u00E1lido da propriedade com.sun.management.agent.class
-agent.err.invalid.state = Estado inv\u00E1lido do agente: {0}
-agent.err.invalid.jmxremote.port = N\u00FAmero inv\u00E1lido de com.sun.management.jmxremote.port
-agent.err.invalid.jmxremote.rmi.port = N\u00FAmero inv\u00E1lido do com.sun.management.jmxremote.rmi.port
-
-agent.err.file.not.set = Arquivo n\u00E3o especificado
-agent.err.file.not.readable = Arquivo ileg\u00EDvel
-agent.err.file.read.failed = Falha ao ler o arquivo
-agent.err.file.not.found = Arquivo n\u00E3o encontrado
-agent.err.file.access.not.restricted = O acesso de leitura do arquivo deve ser limitado
-
-agent.err.password.file.notset = O arquivo de senha n\u00E3o est\u00E1 especificado, mas com.sun.management.jmxremote.authenticate=true
-agent.err.password.file.not.readable = Arquivo de senha ileg\u00EDvel
-agent.err.password.file.read.failed = Falha ao ler o arquivo de senha
-agent.err.password.file.notfound = Arquivo de senha n\u00E3o encontrado
-agent.err.password.file.access.notrestricted = O acesso de leitura do arquivo de senha deve ser limitado
-
-agent.err.access.file.notset = O arquivo de acesso n\u00E3o est\u00E1 especificado, mas com.sun.management.jmxremote.authenticate=true
-agent.err.access.file.not.readable = Arquivo de acesso ileg\u00EDvel
-agent.err.access.file.read.failed = Falha ao ler o arquivo de acesso
-agent.err.access.file.notfound = Arquivo de acesso n\u00E3o encontrado
-
-agent.err.connector.server.io.error = Erro de comunica\u00E7\u00E3o do servidor do conector JMX
-
-agent.err.invalid.option = Op\u00E7\u00E3o especificada inv\u00E1lida
-
-jmxremote.ConnectorBootstrap.starting = Iniciando o Servidor do Conector JMX:
-jmxremote.ConnectorBootstrap.noAuthentication = Sem autentica\u00E7\u00E3o
-jmxremote.ConnectorBootstrap.ready = Conector JMX pronto em: {0}
-jmxremote.ConnectorBootstrap.password.readonly = O acesso de leitura do arquivo de senha deve ser limitado: {0}
-jmxremote.ConnectorBootstrap.file.readonly = O acesso de leitura do arquivo deve ser limitado: {0}
--- a/jdk/src/java.management/share/classes/sun/management/resources/agent_sv.properties Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#
-# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-agent.err.error = Fel
-agent.err.exception = Agenten orsakade ett undantag
-agent.err.warning = Varning
-
-agent.err.configfile.notfound = Konfigurationsfilen hittades inte
-agent.err.configfile.failed = Kunde inte l\u00E4sa konfigurationsfilen
-agent.err.configfile.closed.failed = Kunde inte st\u00E4nga konfigurationsfilen
-agent.err.configfile.access.denied = \u00C5tkomst till konfigurationsfilen nekad
-
-agent.err.exportaddress.failed = Kunde inte exportera JMX-anslutningsadressen till instrumentbufferten
-
-agent.err.agentclass.notfound = Administrationsagentklassen hittades inte
-agent.err.agentclass.failed = Administrationsagentklassen utf\u00F6rdes inte
-agent.err.premain.notfound = premain(String) finns inte i agentklassen
-agent.err.agentclass.access.denied = \u00C5tkomst till premain(String) nekad
-agent.err.invalid.agentclass = Ogiltigt egenskapsv\u00E4rde f\u00F6r com.sun.management.agent.class
-agent.err.invalid.state = Ogiltig agentstatus: {0}
-agent.err.invalid.jmxremote.port = Ogiltigt com.sun.management.jmxremote.port-nummer
-agent.err.invalid.jmxremote.rmi.port = Ogiltigt com.sun.management.jmxremote.rmi.port-nummer
-
-agent.err.file.not.set = Filen \u00E4r inte angiven
-agent.err.file.not.readable = Filen \u00E4r inte l\u00E4sbar
-agent.err.file.read.failed = Kunde inte l\u00E4sa filen
-agent.err.file.not.found = Filen hittades inte
-agent.err.file.access.not.restricted = Fill\u00E4snings\u00E5tkomst m\u00E5ste begr\u00E4nsas
-
-agent.err.password.file.notset = L\u00F6senordsfilen har inte angetts men com.sun.management.jmxremote.authenticate=true
-agent.err.password.file.not.readable = L\u00F6senordsfilen \u00E4r inte l\u00E4sbar
-agent.err.password.file.read.failed = Kunde inte l\u00E4sa l\u00F6senordsfilen
-agent.err.password.file.notfound = Hittar inte l\u00F6senordsfilen
-agent.err.password.file.access.notrestricted = L\u00E4sbeh\u00F6righeten f\u00F6r filen m\u00E5ste begr\u00E4nsas
-
-agent.err.access.file.notset = \u00C5tkomstfilen har inte angetts men com.sun.management.jmxremote.authenticate=true
-agent.err.access.file.not.readable = Access-filen \u00E4r inte l\u00E4sbar
-agent.err.access.file.read.failed = Kunde inte l\u00E4sa \u00E5tkomstfilen
-agent.err.access.file.notfound = Access-filen hittades inte
-
-agent.err.connector.server.io.error = Serverkommunikationsfel f\u00F6r JMX-anslutning
-
-agent.err.invalid.option = Det angivna alternativet \u00E4r ogiltigt
-
-jmxremote.ConnectorBootstrap.starting = Startar server f\u00F6r JMX-anslutning:
-jmxremote.ConnectorBootstrap.noAuthentication = Ingen autentisering
-jmxremote.ConnectorBootstrap.ready = JMX-anslutning redo p\u00E5: {0}
-jmxremote.ConnectorBootstrap.password.readonly = L\u00E4sbeh\u00F6righeten f\u00F6r l\u00F6senordsfilen m\u00E5ste begr\u00E4nsas: {0}
-jmxremote.ConnectorBootstrap.file.readonly = Fill\u00E4snings\u00E5tkomst m\u00E5ste begr\u00E4nsas {0}
--- a/jdk/src/java.management/share/classes/sun/management/resources/agent_zh_CN.properties Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#
-# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-agent.err.error = \u9519\u8BEF
-agent.err.exception = \u4EE3\u7406\u629B\u51FA\u5F02\u5E38\u9519\u8BEF
-agent.err.warning = \u8B66\u544A
-
-agent.err.configfile.notfound = \u627E\u4E0D\u5230\u914D\u7F6E\u6587\u4EF6
-agent.err.configfile.failed = \u672A\u80FD\u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6
-agent.err.configfile.closed.failed = \u672A\u80FD\u5173\u95ED\u914D\u7F6E\u6587\u4EF6
-agent.err.configfile.access.denied = \u62D2\u7EDD\u8BBF\u95EE\u914D\u7F6E\u6587\u4EF6
-
-agent.err.exportaddress.failed = \u672A\u80FD\u5C06 JMX \u8FDE\u63A5\u5668\u5730\u5740\u5BFC\u51FA\u5230\u68C0\u6D4B\u7F13\u51B2\u533A
-
-agent.err.agentclass.notfound = \u627E\u4E0D\u5230\u7BA1\u7406\u4EE3\u7406\u7C7B
-agent.err.agentclass.failed = \u7BA1\u7406\u4EE3\u7406\u7C7B\u5931\u8D25
-agent.err.premain.notfound = \u4EE3\u7406\u7C7B\u4E2D\u4E0D\u5B58\u5728 premain(String)
-agent.err.agentclass.access.denied = \u62D2\u7EDD\u8BBF\u95EE premain(String)
-agent.err.invalid.agentclass = com.sun.management.agent.class \u5C5E\u6027\u503C\u65E0\u6548
-agent.err.invalid.state = \u65E0\u6548\u7684\u4EE3\u7406\u72B6\u6001: {0}
-agent.err.invalid.jmxremote.port = com.sun.management.jmxremote.port \u7F16\u53F7\u65E0\u6548
-agent.err.invalid.jmxremote.rmi.port = com.sun.management.jmxremote.rmi.port \u7F16\u53F7\u65E0\u6548
-
-agent.err.file.not.set = \u672A\u6307\u5B9A\u6587\u4EF6
-agent.err.file.not.readable = \u6587\u4EF6\u4E0D\u53EF\u8BFB\u53D6
-agent.err.file.read.failed = \u672A\u80FD\u8BFB\u53D6\u6587\u4EF6
-agent.err.file.not.found = \u627E\u4E0D\u5230\u6587\u4EF6
-agent.err.file.access.not.restricted = \u5FC5\u987B\u9650\u5236\u6587\u4EF6\u8BFB\u53D6\u8BBF\u95EE\u6743\u9650
-
-agent.err.password.file.notset = \u672A\u6307\u5B9A\u53E3\u4EE4\u6587\u4EF6, \u4F46 com.sun.management.jmxremote.authenticate=true
-agent.err.password.file.not.readable = \u53E3\u4EE4\u6587\u4EF6\u4E0D\u53EF\u8BFB\u53D6
-agent.err.password.file.read.failed = \u8BFB\u53D6\u53E3\u4EE4\u6587\u4EF6\u5931\u8D25
-agent.err.password.file.notfound = \u627E\u4E0D\u5230\u53E3\u4EE4\u6587\u4EF6
-agent.err.password.file.access.notrestricted = \u5FC5\u987B\u9650\u5236\u53E3\u4EE4\u6587\u4EF6\u8BFB\u53D6\u8BBF\u95EE\u6743\u9650
-
-agent.err.access.file.notset = \u672A\u6307\u5B9A\u8BBF\u95EE\u6587\u4EF6, \u4F46 com.sun.management.jmxremote.authenticate=true
-agent.err.access.file.not.readable = \u8BBF\u95EE\u6587\u4EF6\u4E0D\u53EF\u8BFB\u53D6
-agent.err.access.file.read.failed = \u8BFB\u53D6\u8BBF\u95EE\u6587\u4EF6\u5931\u8D25
-agent.err.access.file.notfound = \u627E\u4E0D\u5230\u8BBF\u95EE\u6587\u4EF6
-
-agent.err.connector.server.io.error = JMX \u8FDE\u63A5\u5668\u670D\u52A1\u5668\u901A\u4FE1\u9519\u8BEF
-
-agent.err.invalid.option = \u6307\u5B9A\u7684\u9009\u9879\u65E0\u6548
-
-jmxremote.ConnectorBootstrap.starting = \u6B63\u5728\u542F\u52A8 JMX \u8FDE\u63A5\u5668\u670D\u52A1\u5668:
-jmxremote.ConnectorBootstrap.noAuthentication = \u65E0\u9A8C\u8BC1
-jmxremote.ConnectorBootstrap.ready = \u4F4D\u4E8E{0}\u7684 JMX \u8FDE\u63A5\u5668\u5DF2\u5C31\u7EEA
-jmxremote.ConnectorBootstrap.password.readonly = \u5FC5\u987B\u9650\u5236\u53E3\u4EE4\u6587\u4EF6\u8BFB\u53D6\u8BBF\u95EE\u6743\u9650: {0}
-jmxremote.ConnectorBootstrap.file.readonly = \u5FC5\u987B\u9650\u5236\u6587\u4EF6\u8BFB\u53D6\u8BBF\u95EE\u6743\u9650: {0}
--- a/jdk/src/java.management/share/classes/sun/management/resources/agent_zh_TW.properties Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-#
-# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-agent.err.error = \u932F\u8AA4
-agent.err.exception = \u4EE3\u7406\u7A0B\u5F0F\u767C\u751F\u7570\u5E38
-agent.err.warning = \u8B66\u544A
-
-agent.err.configfile.notfound = \u627E\u4E0D\u5230\u8A2D\u5B9A\u6A94\u6848
-agent.err.configfile.failed = \u7121\u6CD5\u8B80\u53D6\u8A2D\u5B9A\u6A94\u6848
-agent.err.configfile.closed.failed = \u7121\u6CD5\u95DC\u9589\u8A2D\u5B9A\u6A94\u6848
-agent.err.configfile.access.denied = \u5B58\u53D6\u8A2D\u5B9A\u6A94\u6848\u906D\u5230\u62D2\u7D55
-
-agent.err.exportaddress.failed = \u5C07 JMX \u9023\u63A5\u5668\u4F4D\u5740\u532F\u51FA\u81F3\u8A2D\u5099\u7DE9\u885D\u5340\u5931\u6557
-
-agent.err.agentclass.notfound = \u627E\u4E0D\u5230\u7BA1\u7406\u4EE3\u7406\u7A0B\u5F0F\u985E\u5225
-agent.err.agentclass.failed = \u7BA1\u7406\u4EE3\u7406\u7A0B\u5F0F\u985E\u5225\u5931\u6557
-agent.err.premain.notfound = \u4EE3\u7406\u7A0B\u5F0F\u985E\u5225\u4E2D\u4E0D\u5B58\u5728 premain(String)
-agent.err.agentclass.access.denied = \u5B58\u53D6 premain(String) \u906D\u5230\u62D2\u7D55
-agent.err.invalid.agentclass = com.sun.management.agent.class \u5C6C\u6027\u503C\u7121\u6548
-agent.err.invalid.state = \u7121\u6548\u7684\u4EE3\u7406\u7A0B\u5F0F\u72C0\u614B: {0}
-agent.err.invalid.jmxremote.port = com.sun.management.jmxremote.port \u865F\u78BC\u7121\u6548
-agent.err.invalid.jmxremote.rmi.port = com.sun.management.jmxremote.rmi.port \u865F\u78BC\u7121\u6548
-
-agent.err.file.not.set = \u672A\u6307\u5B9A\u6A94\u6848
-agent.err.file.not.readable = \u6A94\u6848\u7121\u6CD5\u8B80\u53D6
-agent.err.file.read.failed = \u7121\u6CD5\u8B80\u53D6\u6A94\u6848
-agent.err.file.not.found = \u627E\u4E0D\u5230\u6A94\u6848
-agent.err.file.access.not.restricted = \u5FC5\u9808\u9650\u5236\u6A94\u6848\u8B80\u53D6\u5B58\u53D6\u6B0A
-
-agent.err.password.file.notset = \u672A\u6307\u5B9A\u5BC6\u78BC\u6A94\u6848\uFF0C\u4F46 com.sun.management.jmxremote.authenticate=true
-agent.err.password.file.not.readable = \u5BC6\u78BC\u6A94\u6848\u7121\u6CD5\u8B80\u53D6
-agent.err.password.file.read.failed = \u7121\u6CD5\u8B80\u53D6\u5BC6\u78BC\u6A94\u6848
-agent.err.password.file.notfound = \u627E\u4E0D\u5230\u5BC6\u78BC\u6A94\u6848
-agent.err.password.file.access.notrestricted = \u5FC5\u9808\u9650\u5236\u5BC6\u78BC\u6A94\u6848\u8B80\u53D6\u5B58\u53D6
-
-agent.err.access.file.notset = \u672A\u6307\u5B9A\u5B58\u53D6\u6A94\u6848\uFF0C\u4F46 com.sun.management.jmxremote.authenticate=true
-agent.err.access.file.not.readable = \u5B58\u53D6\u6A94\u6848\u7121\u6CD5\u8B80\u53D6
-agent.err.access.file.read.failed = \u7121\u6CD5\u8B80\u53D6\u5B58\u53D6\u6A94\u6848
-agent.err.access.file.notfound = \u627E\u4E0D\u5230\u5B58\u53D6\u6A94\u6848
-
-agent.err.connector.server.io.error = JMX \u9023\u63A5\u5668\u4F3A\u670D\u5668\u901A\u8A0A\u932F\u8AA4
-
-agent.err.invalid.option = \u6307\u5B9A\u7684\u9078\u9805\u7121\u6548
-
-jmxremote.ConnectorBootstrap.starting = \u6B63\u5728\u555F\u52D5 JMX \u9023\u63A5\u5668\u4F3A\u670D\u5668:
-jmxremote.ConnectorBootstrap.noAuthentication = \u7121\u8A8D\u8B49
-jmxremote.ConnectorBootstrap.ready = JMX \u9023\u63A5\u5668\u5C31\u7DD2\uFF0C\u4F4D\u65BC: {0}
-jmxremote.ConnectorBootstrap.password.readonly = \u5FC5\u9808\u9650\u5236\u5BC6\u78BC\u6A94\u6848\u8B80\u53D6\u5B58\u53D6: {0}
-jmxremote.ConnectorBootstrap.file.readonly = \u5FC5\u9808\u9650\u5236\u6A94\u6848\u8B80\u53D6\u5B58\u53D6\u6B0A: {0}
--- a/jdk/src/java.management/share/classes/sun/management/spi/AgentProvider.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package sun.management.spi;
-
-import java.util.Properties;
-
-/**
- * Service interface for management agent
- */
-public abstract class AgentProvider {
-
- /**
- * Instantiates a new AgentProvider.
- *
- * @throws SecurityException if the subclass (and calling code) does not
- * have
- * {@code RuntimePermission("sun.management.spi.AgentProvider.subclass")}
- */
- protected AgentProvider() {
- this(checkSubclassPermission());
- }
-
- private AgentProvider(Void unused) {
- }
-
- private static Void checkSubclassPermission() {
- SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- sm.checkPermission(new RuntimePermission(AgentProvider.class.getName() + ".subclass"));
- }
- return null;
- }
-
- /**
- * Gets the name of the agent provider.
- *
- * @return name of agent provider
- */
- public abstract String getName();
-
- /**
- * Initializes and starts the agent.
- *
- * @throws IllegalStateException if this agent has already been started.
- */
- public abstract void startAgent();
-
- /**
- * Initializes and starts the agent at given port and with given properties
- *
- * @param props environment variables for agent
- *
- * @throws IllegalStateException if this agent has already been started.
- */
- public abstract void startAgent(Properties props);
-
- /**
- * Checks if agent is started and not terminated.
- *
- * @return true if agent is running, false otherwise.
- */
- public abstract boolean isActive();
-
- /**
- * Stops this agent.
- *
- * @throws IllegalStateException if this agent is not started.
- */
- public abstract void stopAgent();
-}
--- a/jdk/src/java.management/share/conf/jmxremote.access Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-######################################################################
-# Default Access Control File for Remote JMX(TM) Monitoring
-######################################################################
-#
-# Access control file for Remote JMX API access to monitoring.
-# This file defines the allowed access for different roles. The
-# password file (jmxremote.password by default) defines the roles and their
-# passwords. To be functional, a role must have an entry in
-# both the password and the access files.
-#
-# The default location of this file is $JRE/conf/management/jmxremote.access
-# You can specify an alternate location by specifying a property in
-# the management config file $JRE/conf/management/management.properties
-# (See that file for details)
-#
-# The file format for password and access files is syntactically the same
-# as the Properties file format. The syntax is described in the Javadoc
-# for java.util.Properties.load.
-# A typical access file has multiple lines, where each line is blank,
-# a comment (like this one), or an access control entry.
-#
-# An access control entry consists of a role name, and an
-# associated access level. The role name is any string that does not
-# itself contain spaces or tabs. It corresponds to an entry in the
-# password file (jmxremote.password). The access level is one of the
-# following:
-# "readonly" grants access to read attributes of MBeans.
-# For monitoring, this means that a remote client in this
-# role can read measurements but cannot perform any action
-# that changes the environment of the running program.
-# "readwrite" grants access to read and write attributes of MBeans,
-# to invoke operations on them, and optionally
-# to create or remove them. This access should be granted
-# only to trusted clients, since they can potentially
-# interfere with the smooth operation of a running program.
-#
-# The "readwrite" access level can optionally be followed by the "create" and/or
-# "unregister" keywords. The "unregister" keyword grants access to unregister
-# (delete) MBeans. The "create" keyword grants access to create MBeans of a
-# particular class or of any class matching a particular pattern. Access
-# should only be granted to create MBeans of known and trusted classes.
-#
-# For example, the following entry would grant readwrite access
-# to "controlRole", as well as access to create MBeans of the class
-# javax.management.monitor.CounterMonitor and to unregister any MBean:
-# controlRole readwrite \
-# create javax.management.monitor.CounterMonitorMBean \
-# unregister
-# or equivalently:
-# controlRole readwrite unregister create javax.management.monitor.CounterMBean
-#
-# The following entry would grant readwrite access as well as access to create
-# MBeans of any class in the packages javax.management.monitor and
-# javax.management.timer:
-# controlRole readwrite \
-# create javax.management.monitor.*,javax.management.timer.* \
-# unregister
-#
-# The \ character is defined in the Properties file syntax to allow continuation
-# lines as shown here. A * in a class pattern matches a sequence of characters
-# other than dot (.), so javax.management.monitor.* matches
-# javax.management.monitor.CounterMonitor but not
-# javax.management.monitor.foo.Bar.
-#
-# A given role should have at most one entry in this file. If a role
-# has no entry, it has no access.
-# If multiple entries are found for the same role name, then the last
-# access entry is used.
-#
-#
-# Default access control entries:
-# o The "monitorRole" role has readonly access.
-# o The "controlRole" role has readwrite access and can create the standard
-# Timer and Monitor MBeans defined by the JMX API.
-
-monitorRole readonly
-controlRole readwrite \
- create javax.management.monitor.*,javax.management.timer.* \
- unregister
--- a/jdk/src/java.management/share/conf/jmxremote.password.template Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-# ----------------------------------------------------------------------
-# Template for jmxremote.password
-#
-# o Copy this template to jmxremote.password
-# o Set the user/password entries in jmxremote.password
-# o Change the permission of jmxremote.password to read-only
-# by the owner.
-#
-# See below for the location of jmxremote.password file.
-# ----------------------------------------------------------------------
-
-##############################################################
-# Password File for Remote JMX Monitoring
-##############################################################
-#
-# Password file for Remote JMX API access to monitoring. This
-# file defines the different roles and their passwords. The access
-# control file (jmxremote.access by default) defines the allowed
-# access for each role. To be functional, a role must have an entry
-# in both the password and the access files.
-#
-# Default location of this file is $JRE/conf/management/jmxremote.password
-# You can specify an alternate location by specifying a property in
-# the management config file $JRE/conf/management/management.properties
-# or by specifying a system property (See that file for details).
-
-
-##############################################################
-# File permissions of the jmxremote.password file
-##############################################################
-# Since there are cleartext passwords stored in this file,
-# this file must be readable by ONLY the owner,
-# otherwise the program will exit with an error.
-#
-# The file format for password and access files is syntactically the same
-# as the Properties file format. The syntax is described in the Javadoc
-# for java.util.Properties.load.
-# Typical password file has multiple lines, where each line is blank,
-# a comment (like this one), or a password entry.
-#
-#
-# A password entry consists of a role name and an associated
-# password. The role name is any string that does not itself contain
-# spaces or tabs. The password is again any string that does not
-# contain spaces or tabs. Note that passwords appear in the clear in
-# this file, so it is a good idea not to use valuable passwords.
-#
-# A given role should have at most one entry in this file. If a role
-# has no entry, it has no access.
-# If multiple entries are found for the same role name, then the last one
-# is used.
-#
-# In a typical installation, this file can be read by anybody on the
-# local machine, and possibly by people on other machines.
-# For # security, you should either restrict the access to this file,
-# or specify another, less accessible file in the management config file
-# as described above.
-#
-# Following are two commented-out entries. The "measureRole" role has
-# password "QED". The "controlRole" role has password "R&D".
-#
-# monitorRole QED
-# controlRole R&D
-
--- a/jdk/src/java.management/share/conf/management.properties Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,331 +0,0 @@
-#####################################################################
-# Default Configuration File for Java Platform Management
-#####################################################################
-#
-# The Management Configuration file (in java.util.Properties format)
-# will be read if one of the following system properties is set:
-# -Dcom.sun.management.jmxremote.port=<port-number>
-# or -Dcom.sun.management.snmp.port=<port-number>
-# or -Dcom.sun.management.config.file=<this-file>
-#
-# The default Management Configuration file is:
-#
-# $JRE/conf/management/management.properties
-#
-# Another location for the Management Configuration File can be specified
-# by the following property on the Java command line:
-#
-# -Dcom.sun.management.config.file=<this-file>
-#
-# If -Dcom.sun.management.config.file=<this-file> is set, the port
-# number for the management agent can be specified in the config file
-# using the following lines:
-#
-# ################ Management Agent Port #########################
-#
-# For setting the JMX RMI agent port use the following line
-# com.sun.management.jmxremote.port=<port-number>
-#
-# For setting the SNMP agent port use the following line
-# com.sun.management.snmp.port=<port-number>
-
-#####################################################################
-# Optional Instrumentation
-#####################################################################
-#
-# By default only the basic instrumentation with low overhead is on.
-# The following properties allow to selectively turn on optional
-# instrumentation which are off by default and may have some
-# additional overhead.
-#
-# com.sun.management.enableThreadContentionMonitoring
-#
-# This option enables thread contention monitoring if the
-# Java virtual machine supports such instrumentation.
-# Refer to the specification for the java.lang.management.ThreadMBean
-# interface - see isThreadContentionMonitoringSupported() method.
-#
-
-# To enable thread contention monitoring, uncomment the following line
-# com.sun.management.enableThreadContentionMonitoring
-
-#####################################################################
-# SNMP Management Properties
-#####################################################################
-#
-# If the system property -Dcom.sun.management.snmp.port=<port-number>
-# is set then
-# - The SNMP agent (with the Java virtual machine MIB) is started
-# that listens on the specified port for incoming SNMP requests.
-# - the following properties for read for SNMP management.
-#
-# The configuration can be specified only at startup time.
-# Later changes to the above system property (e.g. via setProperty method), this
-# config file, or the ACL file has no effect to the running SNMP agent.
-#
-
-#
-# ##################### SNMP Trap Port #########################
-#
-# com.sun.management.snmp.trap=<trap-destination-port-number>
-# Specifies the remote port number at which managers are expected
-# to listen for trap. For each host defined in the ACL file,
-# the SNMP agent will send traps at <host>:<trap-destination-port-number>
-# Default for this property is 162.
-#
-
-# To set port for sending traps to a different port use the following line
-# com.sun.management.snmp.trap=<trap-destination-port-number>
-
-#
-# ################ SNMP listen interface #########################
-#
-# com.sun.management.snmp.interface=<InetAddress>
-# Specifies the local interface on which the SNMP agent will bind.
-# This is useful when running on machines which have several
-# interfaces defined. It makes it possible to listen to a specific
-# subnet accessible through that interface.
-# Default for this property is "localhost".
-#
-# The format of the value for that property is any string accepted
-# by java.net.InetAddress.getByName(String).
-#
-
-# For restricting the port on which SNMP agent listens use the following line
-# com.sun.management.snmp.interface=<InetAddress>
-
-#
-# #################### SNMP ACL file #########################
-#
-# com.sun.management.snmp.acl=true|false
-# Default for this property is true. (Case for true/false ignored)
-# If this property is specified as false then the ACL file
-# is not checked: all manager hosts are allowed all access.
-#
-
-# For SNMP without checking ACL file uncomment the following line
-# com.sun.management.snmp.acl=false
-
-#
-# com.sun.management.snmp.acl.file=filepath
-# Specifies location for ACL file
-# This is optional - default location is
-# $JRE/conf/management/snmp.acl
-#
-# If the property "com.sun.management.snmp.acl" is set to false,
-# then this property and the ACL file are ignored.
-# Otherwise the ACL file must exist and be in the valid format.
-# If the ACL file is empty or non existent then no access is allowed.
-#
-# The SNMP agent will read the ACL file at startup time.
-# Modification to the ACL file has no effect to any running SNMP
-# agents which read that ACL file at startup.
-#
-
-# For a non-default acl file location use the following line
-# com.sun.management.snmp.acl.file=filepath
-
-#####################################################################
-# RMI Management Properties
-#####################################################################
-#
-# If system property -Dcom.sun.management.jmxremote.port=<port-number>
-# is set then
-# - A MBean server is started
-# - JRE Platform MBeans are registered in the MBean server
-# - RMI connector is published in a private readonly registry at
-# specified port using a well known name, "jmxrmi"
-# - the following properties are read for JMX remote management.
-#
-# The configuration can be specified only at startup time.
-# Later changes to above system property (e.g. via setProperty method),
-# this config file, the password file, or the access file have no effect to the
-# running MBean server, the connector, or the registry.
-#
-
-#
-# ########## RMI connector settings for local management ##########
-#
-# com.sun.management.jmxremote.local.only=true|false
-# Default for this property is true. (Case for true/false ignored)
-# If this property is specified as true then the local JMX RMI connector
-# server will only accept connection requests from clients running on
-# the host where the out-of-the-box JMX management agent is running.
-# In order to ensure backwards compatibility this property could be
-# set to false. However, deploying the local management agent in this
-# way is discouraged because the local JMX RMI connector server will
-# accept connection requests from any client either local or remote.
-# For remote management the remote JMX RMI connector server should
-# be used instead with authentication and SSL/TLS encryption enabled.
-#
-
-# For allowing the local management agent accept local
-# and remote connection requests use the following line
-# com.sun.management.jmxremote.local.only=false
-
-#
-# ###################### RMI SSL #############################
-#
-# com.sun.management.jmxremote.ssl=true|false
-# Default for this property is true. (Case for true/false ignored)
-# If this property is specified as false then SSL is not used.
-#
-
-# For RMI monitoring without SSL use the following line
-# com.sun.management.jmxremote.ssl=false
-
-# com.sun.management.jmxremote.ssl.config.file=filepath
-# Specifies the location of the SSL configuration file. A properties
-# file can be used to supply the keystore and truststore location and
-# password settings thus avoiding to pass them as cleartext in the
-# command-line.
-#
-# The current implementation of the out-of-the-box management agent will
-# look up and use the properties specified below to configure the SSL
-# keystore and truststore, if present:
-# javax.net.ssl.keyStore=<keystore-location>
-# javax.net.ssl.keyStorePassword=<keystore-password>
-# javax.net.ssl.trustStore=<truststore-location>
-# javax.net.ssl.trustStorePassword=<truststore-password>
-# Any other properties in the file will be ignored. This will allow us
-# to extend the property set in the future if required by the default
-# SSL implementation.
-#
-# If the property "com.sun.management.jmxremote.ssl" is set to false,
-# then this property is ignored.
-#
-
-# For supplying the keystore settings in a file use the following line
-# com.sun.management.jmxremote.ssl.config.file=filepath
-
-# com.sun.management.jmxremote.ssl.enabled.cipher.suites=<cipher-suites>
-# The value of this property is a string that is a comma-separated list
-# of SSL/TLS cipher suites to enable. This property can be specified in
-# conjunction with the previous property "com.sun.management.jmxremote.ssl"
-# in order to control which particular SSL/TLS cipher suites are enabled
-# for use by accepted connections. If this property is not specified then
-# the SSL/TLS RMI Server Socket Factory uses the SSL/TLS cipher suites that
-# are enabled by default.
-#
-
-# com.sun.management.jmxremote.ssl.enabled.protocols=<protocol-versions>
-# The value of this property is a string that is a comma-separated list
-# of SSL/TLS protocol versions to enable. This property can be specified in
-# conjunction with the previous property "com.sun.management.jmxremote.ssl"
-# in order to control which particular SSL/TLS protocol versions are
-# enabled for use by accepted connections. If this property is not
-# specified then the SSL/TLS RMI Server Socket Factory uses the SSL/TLS
-# protocol versions that are enabled by default.
-#
-
-# com.sun.management.jmxremote.ssl.need.client.auth=true|false
-# Default for this property is false. (Case for true/false ignored)
-# If this property is specified as true in conjunction with the previous
-# property "com.sun.management.jmxremote.ssl" then the SSL/TLS RMI Server
-# Socket Factory will require client authentication.
-#
-
-# For RMI monitoring with SSL client authentication use the following line
-# com.sun.management.jmxremote.ssl.need.client.auth=true
-
-# com.sun.management.jmxremote.registry.ssl=true|false
-# Default for this property is false. (Case for true/false ignored)
-# If this property is specified as true then the RMI registry used
-# to bind the RMIServer remote object is protected with SSL/TLS
-# RMI Socket Factories that can be configured with the properties:
-# com.sun.management.jmxremote.ssl.config.file
-# com.sun.management.jmxremote.ssl.enabled.cipher.suites
-# com.sun.management.jmxremote.ssl.enabled.protocols
-# com.sun.management.jmxremote.ssl.need.client.auth
-# If the two properties below are true at the same time, i.e.
-# com.sun.management.jmxremote.ssl=true
-# com.sun.management.jmxremote.registry.ssl=true
-# then the RMIServer remote object and the RMI registry are
-# both exported with the same SSL/TLS RMI Socket Factories.
-#
-
-# For using an SSL/TLS protected RMI registry use the following line
-# com.sun.management.jmxremote.registry.ssl=true
-
-#
-# ################ RMI User authentication ################
-#
-# com.sun.management.jmxremote.authenticate=true|false
-# Default for this property is true. (Case for true/false ignored)
-# If this property is specified as false then no authentication is
-# performed and all users are allowed all access.
-#
-
-# For RMI monitoring without any checking use the following line
-# com.sun.management.jmxremote.authenticate=false
-
-#
-# ################ RMI Login configuration ###################
-#
-# com.sun.management.jmxremote.login.config=<config-name>
-# Specifies the name of a JAAS login configuration entry to use when
-# authenticating users of RMI monitoring.
-#
-# Setting this property is optional - the default login configuration
-# specifies a file-based authentication that uses the password file.
-#
-# When using this property to override the default login configuration
-# then the named configuration entry must be in a file that gets loaded
-# by JAAS. In addition, the login module(s) specified in the configuration
-# should use the name and/or password callbacks to acquire the user's
-# credentials. See the NameCallback and PasswordCallback classes in the
-# javax.security.auth.callback package for more details.
-#
-# If the property "com.sun.management.jmxremote.authenticate" is set to
-# false, then this property and the password & access files are ignored.
-#
-
-# For a non-default login configuration use the following line
-# com.sun.management.jmxremote.login.config=<config-name>
-
-#
-# ################ RMI Password file location ##################
-#
-# com.sun.management.jmxremote.password.file=filepath
-# Specifies location for password file
-# This is optional - default location is
-# $JRE/conf/management/jmxremote.password
-#
-# If the property "com.sun.management.jmxremote.authenticate" is set to
-# false, then this property and the password & access files are ignored.
-# Otherwise the password file must exist and be in the valid format.
-# If the password file is empty or non-existent then no access is allowed.
-#
-
-# For a non-default password file location use the following line
-# com.sun.management.jmxremote.password.file=filepath
-
-#
-# ################ RMI Access file location #####################
-#
-# com.sun.management.jmxremote.access.file=filepath
-# Specifies location for access file
-# This is optional - default location is
-# $JRE/conf/management/jmxremote.access
-#
-# If the property "com.sun.management.jmxremote.authenticate" is set to
-# false, then this property and the password & access files are ignored.
-# Otherwise, the access file must exist and be in the valid format.
-# If the access file is empty or non-existent then no access is allowed.
-#
-
-# For a non-default password file location use the following line
-# com.sun.management.jmxremote.access.file=filepath
-#
-
-# ################ Management agent listen interface #########################
-#
-# com.sun.management.jmxremote.host=<host-or-interface-name>
-# Specifies the local interface on which the JMX RMI agent will bind.
-# This is useful when running on machines which have several
-# interfaces defined. It makes it possible to listen to a specific
-# subnet accessible through that interface.
-#
-# The format of the value for that property is any string accepted
-# by java.net.InetAddress.getByName(String).
-#
--- a/jdk/src/java.management/share/conf/snmp.acl.template Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-# ----------------------------------------------------------------------
-# Template for SNMP Access Control List File
-#
-# o Copy this template to snmp.acl
-# o Set access control for SNMP support
-# o Change the permission of snmp.acl to be read-only
-# by the owner.
-#
-# See below for the location of snmp.acl file.
-# ----------------------------------------------------------------------
-
-############################################################
-# SNMP Access Control List File
-############################################################
-#
-# Default location of this file is $JRE/conf/management/snmp.acl.
-# You can specify an alternate location by specifying a property in
-# the management config file $JRE/conf/management/management.properties
-# or by specifying a system property (See that file for details).
-#
-
-
-##############################################################
-# File permissions of the snmp.acl file
-##############################################################
-#
-# Since there are cleartext community strings stored in this file,
-# this ACL file must be readable by ONLY the owner,
-# otherwise the program will exit with an error.
-#
-##############################################################
-# Format of the acl group
-##############################################################
-#
-# communities: a list of SNMP community strings to which the
-# access control applies separated by commas.
-#
-# access: either "read-only" or "read-write".
-#
-# managers: a list of hosts to be granted the access rights.
-# Each can be expressed as any one of the following:
-# - hostname: hubble
-# - ip v4 and v6 addresses: 123.456.789.12 , fe80::a00:20ff:fe9b:ea82
-# - ip v4 and v6 netmask prefix notation: 123.456.789.0/24,
-# fe80::a00:20ff:fe9b:ea82/64
-# see RFC 2373 (http://www.ietf.org/rfc/rfc2373.txt)
-#
-# An example of two community groups for multiple hosts:
-# acl = {
-# {
-# communities = public, private
-# access = read-only
-# managers = hubble, snowbell, nanak
-# }
-# {
-# communities = jerry
-# access = read-write
-# managers = hubble, telescope
-# }
-# }
-#
-##############################################################
-# Format of the trap group
-##############################################################
-#
-# trap-community: a single SNMP community string that will be included
-# in the traps sent to the hosts.
-#
-# hosts: a list of hosts to which the SNMP agent will send traps.
-#
-# An example of two trap community definitions for multiple hosts:
-# trap = {
-# {
-# trap-community = public
-# hosts = hubble, snowbell
-# }
-# {
-# trap-community = private
-# hosts = telescope
-# }
-# }
-#
-############################################################
-#
-# Update the community strings (public and private) below
-# before copying this template file
-#
-# Common SNMP ACL Example
-# ------------------------
-#
-# o Only localhost can connect, and access rights
-# are limited to read-only
-# o Traps are sent to localhost only
-#
-#
-# acl = {
-# {
-# communities = public, private
-# access = read-only
-# managers = localhost
-# }
-# }
-#
-#
-# trap = {
-# {
-# trap-community = public
-# hosts = localhost
-# }
-# }
--- a/jdk/src/java.management/unix/classes/sun/management/FileSystemImpl.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management;
-
-import java.io.File;
-import java.io.IOException;
-
-/*
- * Solaris/Linux implementation of sun.management.FileSystem
- */
-public class FileSystemImpl extends FileSystem {
-
- public boolean supportsFileSecurity(File f) throws IOException {
- return true;
- }
-
- public boolean isAccessUserOnly(File f) throws IOException {
- return isAccessUserOnly0(f.getPath());
- }
-
- // Native methods
-
- static native boolean isAccessUserOnly0(String path) throws IOException;
-
- // Initialization
-
- static {
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("management");
- return null;
- }
- });
- }
-}
--- a/jdk/src/java.management/unix/native/libmanagement/FileSystemImpl.c Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "jni.h"
-#include "jni_util.h"
-#include "sun_management_FileSystemImpl.h"
-
-#ifdef _ALLBSD_SOURCE
-#define stat64 stat
-#endif
-
-/*
- * Class: sun_management_FileSystemImpl
- * Method: isAccessUserOnly0
- * Signature: (Ljava/lang/String;)Z
- */
-JNIEXPORT jboolean JNICALL Java_sun_management_FileSystemImpl_isAccessUserOnly0
- (JNIEnv *env, jclass ignored, jstring str)
-{
- jboolean res = JNI_FALSE;
- jboolean isCopy;
- const char *path = JNU_GetStringPlatformChars(env, str, &isCopy);
- if (path != NULL) {
- struct stat64 sb;
- if (stat64(path, &sb) == 0) {
- res = ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) == 0) ? JNI_TRUE : JNI_FALSE;
- } else {
- JNU_ThrowIOExceptionWithLastError(env, "stat64 failed");
- }
- if (isCopy) {
- JNU_ReleaseStringPlatformChars(env, str, path);
- }
- }
- return res;
-}
--- a/jdk/src/java.management/windows/classes/sun/management/FileSystemImpl.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package sun.management;
-
-import java.io.File;
-import java.io.IOException;
-
-/*
- * Windows implementation of sun.management.FileSystem
- */
-public class FileSystemImpl extends FileSystem {
-
- public boolean supportsFileSecurity(File f) throws IOException {
- return isSecuritySupported0(f.getAbsolutePath());
- }
-
- public boolean isAccessUserOnly(File f) throws IOException {
- String path = f.getAbsolutePath();
- if (!isSecuritySupported0(path)) {
- throw new UnsupportedOperationException("File system does not support file security");
- }
- return isAccessUserOnly0(path);
- }
-
- // Native methods
-
- static native void init0();
-
- static native boolean isSecuritySupported0(String path) throws IOException;
-
- static native boolean isAccessUserOnly0(String path) throws IOException;
-
- // Initialization
-
- static {
- java.security.AccessController.doPrivileged(
- new java.security.PrivilegedAction<Void>() {
- public Void run() {
- System.loadLibrary("management");
- return null;
- }
- });
- init0();
- }
-}
--- a/jdk/src/java.management/windows/native/libmanagement/FileSystemImpl.c Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,314 +0,0 @@
-/*
- * Copyright (c) 2004, 2011, 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 <windows.h>
-#include <malloc.h>
-#include <string.h>
-
-#include "jni.h"
-#include "jni_util.h"
-#include "sun_management_FileSystemImpl.h"
-
-/*
- * Access mask to represent any file access
- */
-#define ANY_ACCESS (FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE)
-
-/*
- * Returns JNI_TRUE if the specified file is on a file system that supports
- * persistent ACLs (On NTFS file systems returns true, on FAT32 file systems
- * returns false).
- */
-static jboolean isSecuritySupported(JNIEnv* env, const char* path) {
- char* root;
- char* p;
- BOOL res;
- DWORD dwMaxComponentLength;
- DWORD dwFlags;
- char fsName[128];
- DWORD fsNameLength;
-
- /*
- * Get root directory. Assume that files are absolute paths. For UNCs
- * the slash after the share name is required.
- */
- root = strdup(path);
- if (*root == '\\') {
- /*
- * \\server\share\file ==> \\server\share\
- */
- int slashskip = 3;
- p = root;
- while ((*p == '\\') && (slashskip > 0)) {
- char* p2;
- p++;
- p2 = strchr(p, '\\');
- if ((p2 == NULL) || (*p2 != '\\')) {
- free(root);
- JNU_ThrowIOException(env, "Malformed UNC");
- return JNI_FALSE;
- }
- p = p2;
- slashskip--;
- }
- if (slashskip != 0) {
- free(root);
- JNU_ThrowIOException(env, "Malformed UNC");
- return JNI_FALSE;
- }
- p++;
- *p = '\0';
-
- } else {
- p = strchr(root, '\\');
- if (p == NULL) {
- free(root);
- JNU_ThrowIOException(env, "Absolute filename not specified");
- return JNI_FALSE;
- }
- p++;
- *p = '\0';
- }
-
-
- /*
- * Get the volume information - this gives us the file system file and
- * also tells us if the file system supports persistent ACLs.
- */
- fsNameLength = sizeof(fsName)-1;
- res = GetVolumeInformation(root,
- NULL, // address of name of the volume, can be NULL
- 0, // length of volume name
- NULL, // address of volume serial number, can be NULL
- &dwMaxComponentLength,
- &dwFlags,
- fsName,
- fsNameLength);
- if (res == 0) {
- free(root);
- JNU_ThrowIOExceptionWithLastError(env, "GetVolumeInformation failed");
- return JNI_FALSE;
- }
-
- free(root);
- return (dwFlags & FS_PERSISTENT_ACLS) ? JNI_TRUE : JNI_FALSE;
-}
-
-
-/*
- * Returns the security descriptor for a file.
- */
-static SECURITY_DESCRIPTOR* getFileSecurityDescriptor(JNIEnv* env, const char* path) {
- SECURITY_DESCRIPTOR* sd;
- DWORD len = 0;
- SECURITY_INFORMATION info =
- OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
-
- GetFileSecurityA(path, info , 0, 0, &len);
- if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
- JNU_ThrowIOExceptionWithLastError(env, "GetFileSecurity failed");
- return NULL;
- }
- sd = (SECURITY_DESCRIPTOR *)malloc(len);
- if (sd == NULL) {
- JNU_ThrowOutOfMemoryError(env, 0);
- } else {
- if (!(*GetFileSecurityA)(path, info, sd, len, &len)) {
- JNU_ThrowIOExceptionWithLastError(env, "GetFileSecurity failed");
- free(sd);
- return NULL;
- }
- }
- return sd;
-}
-
-/*
- * Returns pointer to the SID identifying the owner of the specified
- * file.
- */
-static SID* getFileOwner(JNIEnv* env, SECURITY_DESCRIPTOR* sd) {
- SID* owner;
- BOOL defaulted;
-
- if (!GetSecurityDescriptorOwner(sd, &owner, &defaulted)) {
- JNU_ThrowIOExceptionWithLastError(env, "GetSecurityDescriptorOwner failed");
- return NULL;
- }
- return owner;
-}
-
-/*
- * Returns pointer discretionary access-control list (ACL) from the security
- * descriptor of the specified file.
- */
-static ACL* getFileDACL(JNIEnv* env, SECURITY_DESCRIPTOR* sd) {
- ACL *acl;
- int defaulted, present;
-
- if (!GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted)) {
- JNU_ThrowIOExceptionWithLastError(env, "GetSecurityDescriptorDacl failed");
- return NULL;
- }
- if (!present) {
- JNU_ThrowInternalError(env, "Security descriptor does not contain a DACL");
- return NULL;
- }
- return acl;
-}
-
-/*
- * Returns JNI_TRUE if the specified owner is the only SID will access
- * to the file.
- */
-static jboolean isAccessUserOnly(JNIEnv* env, SID* owner, ACL* acl) {
- ACL_SIZE_INFORMATION acl_size_info;
- DWORD i;
-
- /*
- * If there's no DACL then there's no access to the file
- */
- if (acl == NULL) {
- return JNI_TRUE;
- }
-
- /*
- * Get the ACE count
- */
- if (!GetAclInformation(acl, (void *) &acl_size_info, sizeof(acl_size_info),
- AclSizeInformation)) {
- JNU_ThrowIOExceptionWithLastError(env, "GetAclInformation failed");
- return JNI_FALSE;
- }
-
- /*
- * Iterate over the ACEs. For each "allow" type check that the SID
- * matches the owner, and check that the access is read only.
- */
- for (i = 0; i < acl_size_info.AceCount; i++) {
- void* ace;
- ACCESS_ALLOWED_ACE *access;
- SID* sid;
-
- if (!GetAce(acl, i, &ace)) {
- JNU_ThrowIOExceptionWithLastError(env, "GetAce failed");
- return -1;
- }
- if (((ACCESS_ALLOWED_ACE *)ace)->Header.AceType != ACCESS_ALLOWED_ACE_TYPE) {
- continue;
- }
- access = (ACCESS_ALLOWED_ACE *)ace;
- sid = (SID *) &access->SidStart;
- if (!EqualSid(owner, sid)) {
- /*
- * If the ACE allows any access then the file is not secure.
- */
- if (access->Mask & ANY_ACCESS) {
- return JNI_FALSE;
- }
- }
- }
- return JNI_TRUE;
-}
-
-
-/*
- * Class: sun_management_FileSystemImpl
- * Method: init0
- * Signature: ()V
- */
-JNIEXPORT void JNICALL Java_sun_management_FileSystemImpl_init0
- (JNIEnv *env, jclass ignored)
-{
- /* nothing to do */
-}
-
-/*
- * Class: sun_management_FileSystemImpl
- * Method: isSecuritySupported0
- * Signature: (Ljava/lang/String;)Z
- */
-JNIEXPORT jboolean JNICALL Java_sun_management_FileSystemImpl_isSecuritySupported0
- (JNIEnv *env, jclass ignored, jstring str)
-{
- jboolean res;
- jboolean isCopy;
- const char* path;
-
- path = JNU_GetStringPlatformChars(env, str, &isCopy);
- if (path != NULL) {
- res = isSecuritySupported(env, path);
- if (isCopy) {
- JNU_ReleaseStringPlatformChars(env, str, path);
- }
- return res;
- } else {
- /* exception thrown - doesn't matter what we return */
- return JNI_TRUE;
- }
-}
-
-
-/*
- * Class: sun_management_FileSystemImpl
- * Method: isAccessUserOnly0
- * Signature: (Ljava/lang/String;)Z
- */
-JNIEXPORT jboolean JNICALL Java_sun_management_FileSystemImpl_isAccessUserOnly0
- (JNIEnv *env, jclass ignored, jstring str)
-{
- jboolean res = JNI_FALSE;
- jboolean isCopy;
- const char* path;
-
- path = JNU_GetStringPlatformChars(env, str, &isCopy);
- if (path != NULL) {
- /*
- * From the security descriptor get the file owner and
- * DACL. Then check if anybody but the owner has access
- * to the file.
- */
- SECURITY_DESCRIPTOR* sd = getFileSecurityDescriptor(env, path);
- if (sd != NULL) {
- SID *owner = getFileOwner(env, sd);
- if (owner != NULL) {
- ACL* acl = getFileDACL(env, sd);
- if (acl != NULL) {
- res = isAccessUserOnly(env, owner, acl);
- } else {
- /*
- * If acl is NULL it means that an exception was thrown
- * or there is "all acess" to the file.
- */
- res = JNI_FALSE;
- }
- }
- free(sd);
- }
- if (isCopy) {
- JNU_ReleaseStringPlatformChars(env, str, path);
- }
- }
- return res;
-}
--- a/jdk/src/java.rmi/share/classes/module-info.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.rmi/share/classes/module-info.java Thu Feb 02 21:55:34 2017 +0000
@@ -39,13 +39,14 @@
// accessible to the security manager at initialization time
exports com.sun.rmi.rmid to java.base;
exports sun.rmi.registry to
- java.management;
+ jdk.management.agent;
exports sun.rmi.server to
- java.management,
+ java.management.rmi,
+ jdk.management.agent,
jdk.jconsole;
exports sun.rmi.transport to
- java.management,
+ java.management.rmi,
+ jdk.management.agent,
jdk.jconsole;
uses java.rmi.server.RMIClassLoaderSpi;
}
-
--- a/jdk/src/java.se/share/classes/module-info.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/java.se/share/classes/module-info.java Thu Feb 02 21:55:34 2017 +0000
@@ -36,6 +36,7 @@
requires transitive java.instrument;
requires transitive java.logging;
requires transitive java.management;
+ requires transitive java.management.rmi;
requires transitive java.naming;
requires transitive java.prefs;
requires transitive java.rmi;
@@ -47,4 +48,3 @@
requires transitive java.xml;
requires transitive java.xml.crypto;
}
-
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar.properties Thu Feb 02 21:55:34 2017 +0000
@@ -202,7 +202,15 @@
\ jar --update --file foo.jar --main-class com.foo.Main --module-version 1.0\n\
\ -C foo/ module-info.class\n\
\ # Create a multi-release jar, placing some files in the META-INF/versions/9 directory:\n\
-\ jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes
+\ jar --create --file mr.jar -C foo classes --release 9 -C foo9 classes\n\
+\n\
+To shorten or simplify the jar command, you can specify arguments in a separate\n\
+text file and pass it to the jar command with the at sign (@) as a prefix.\n\
+\n\
+\ Examples:\n\
+\ # Read additional options and list of class files from the file classes.list\n\
+\ jar --create --file my.jar @classes.list\
+\n
main.help.opt.main=\
\ Main operation mode:\n
main.help.opt.main.create=\
@@ -224,7 +232,8 @@
\ -C DIR Change to the specified directory and include the\n\
\ following file
main.help.opt.any.file=\
-\ -f, --file=FILE The archive file name\n\
+\ -f, --file=FILE The archive file name. When omitted, either stdin or\n\
+\ stdout is used based on the operation\n\
\ --release VERSION Places all following files in a versioned directory\n\
\ of the jar (i.e. META-INF/versions/VERSION/)
main.help.opt.any.verbose=\
@@ -264,7 +273,7 @@
main.help.opt.other=\
\ Other options:\n
main.help.opt.other.help=\
-\ -?, --help[:compat] Give this, or optionally the compatibility, help
+\ -h, --help[:compat] Give this, or optionally the compatibility, help
main.help.opt.other.help-extra=\
\ --help-extra Give help on extra options
main.help.opt.other.version=\
--- a/jdk/src/jdk.jconsole/share/classes/module-info.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/jdk.jconsole/share/classes/module-info.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,12 +26,12 @@
module jdk.jconsole {
requires transitive java.desktop;
requires transitive java.management;
- requires java.logging;
+ requires java.management.rmi;
requires java.rmi;
requires jdk.attach;
requires jdk.jvmstat;
requires jdk.management;
+ requires jdk.management.agent;
exports com.sun.tools.jconsole;
uses com.sun.tools.jconsole.JConsolePlugin;
}
-
--- a/jdk/src/jdk.jconsole/share/classes/sun/tools/jconsole/LocalVirtualMachine.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/jdk.jconsole/share/classes/sun/tools/jconsole/LocalVirtualMachine.java Thu Feb 02 21:55:34 2017 +0000
@@ -29,13 +29,11 @@
import java.io.IOException;
import java.io.File;
-// Sun specific
import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor;
import com.sun.tools.attach.AttachNotSupportedException;
-// Sun private
-import sun.management.ConnectorAddressLink;
+import jdk.internal.agent.ConnectorAddressLink;
import sun.jvmstat.monitor.HostIdentifier;
import sun.jvmstat.monitor.MonitoredHost;
import sun.jvmstat.monitor.MonitoredVm;
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Thu Feb 02 21:55:34 2017 +0000
@@ -227,12 +227,6 @@
addOrderedPluginOptions(plugin, optionsSeen);
}
}
- mainOptions.add(new PluginOption(false,
- (task, opt, arg) -> {
- // This option is handled prior
- // to have the options parsed.
- },
- false, "--plugin-module-path"));
mainOptions.add(new PluginOption(true, (task, opt, arg) -> {
for (Plugin plugin : plugins) {
if (plugin.getName().equals(arg)) {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties Thu Feb 02 21:55:34 2017 +0000
@@ -28,7 +28,7 @@
\<path> use --help for a list of possible options
main.usage=\
-Usage: {0} <options> --module-path <modulepath> --add-modules <mods> --output
+Usage: {0} <options> --module-path <modulepath> --add-modules <mods> --output\n\
\<path> Possible options include:
error.prefix=Error:
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/Agent.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,739 @@
+/*
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.internal.agent;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.UnknownHostException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.text.MessageFormat;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.MissingResourceException;
+import java.util.Properties;
+import java.util.ResourceBundle;
+import java.util.ServiceLoader;
+import java.util.function.Function;
+import java.util.function.Predicate;
+
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXServiceURL;
+
+import static jdk.internal.agent.AgentConfigurationError.*;
+import jdk.internal.agent.spi.AgentProvider;
+import jdk.internal.vm.VMSupport;
+import sun.management.jdp.JdpController;
+import sun.management.jdp.JdpException;
+import sun.management.jmxremote.ConnectorBootstrap;
+
+/**
+ * This Agent is started by the VM when -Dcom.sun.management.snmp or
+ * -Dcom.sun.management.jmxremote is set. This class will be loaded by the
+ * system class loader. Also jmx framework could be started by jcmd
+ */
+public class Agent {
+ /**
+ * Agent status collector strategy class
+ */
+ private static abstract class StatusCollector {
+ protected static final Map<String, String> DEFAULT_PROPS = new HashMap<>();
+
+ static {
+ DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.PORT,
+ ConnectorBootstrap.DefaultValues.PORT);
+ DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.USE_LOCAL_ONLY,
+ ConnectorBootstrap.DefaultValues.USE_LOCAL_ONLY);
+ DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.USE_AUTHENTICATION,
+ ConnectorBootstrap.DefaultValues.USE_AUTHENTICATION);
+ DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.USE_SSL,
+ ConnectorBootstrap.DefaultValues.USE_SSL);
+ DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.USE_REGISTRY_SSL,
+ ConnectorBootstrap.DefaultValues.USE_REGISTRY_SSL);
+ DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.SSL_NEED_CLIENT_AUTH,
+ ConnectorBootstrap.DefaultValues.SSL_NEED_CLIENT_AUTH);
+ DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.CONFIG_FILE_NAME,
+ ConnectorBootstrap.DefaultValues.CONFIG_FILE_NAME);
+ DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.PASSWORD_FILE_NAME,
+ ConnectorBootstrap.DefaultValues.PASSWORD_FILE_NAME);
+ DEFAULT_PROPS.put(ConnectorBootstrap.PropertyNames.ACCESS_FILE_NAME,
+ ConnectorBootstrap.DefaultValues.ACCESS_FILE_NAME);
+
+ }
+
+ 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);
+ addConfigProperties();
+ appendConnectionFooter(remote);
+ }
+
+ private void addConfigProperties() {
+ appendConfigPropsHeader();
+
+ Properties remoteProps = configProps != null ?
+ configProps : getManagementProperties();
+ Map<Object, Object> props = new HashMap<>(DEFAULT_PROPS);
+
+ if (remoteProps == null) {
+ // local connector only
+ String loc_only = System.getProperty(
+ ConnectorBootstrap.PropertyNames.USE_LOCAL_ONLY
+ );
+
+ if (loc_only != null &&
+ !ConnectorBootstrap.DefaultValues.USE_LOCAL_ONLY.equals(loc_only)) {
+ props.put(
+ ConnectorBootstrap.PropertyNames.USE_LOCAL_ONLY,
+ loc_only
+ );
+ }
+ } else {
+ props.putAll(remoteProps);
+ }
+
+ props.entrySet().stream()
+ .filter(preprocess(Map.Entry::getKey, StatusCollector::isManagementProp))
+ .forEach(this::addConfigProp);
+
+ appendConfigPropsFooter();
+ }
+
+ private static boolean isManagementProp(Object pName) {
+ return pName != null && pName.toString().startsWith("com.sun.management.");
+ }
+
+ private static <T, V> Predicate<T> preprocess(Function<T, V> f, Predicate<V> p) {
+ return (T t) -> p.test(f.apply(t));
+ }
+
+ 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(Map.Entry<?, ?> prop);
+ }
+
+ /**
+ * 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(Map.Entry<?, ?> prop) {
+ sb.append(" ").append(prop.getKey()).append(" = ")
+ .append(prop.getValue());
+ Object defVal = DEFAULT_PROPS.get(prop.getKey());
+ if (defVal != null && defVal.equals(prop.getValue())) {
+ sb.append(" [default]");
+ }
+ sb.append("\n");
+ }
+
+ @Override
+ protected void appendConnectionsFooter() {}
+
+ @Override
+ protected void appendConnectionFooter(boolean remote) {
+ sb.append('\n');
+ }
+
+ @Override
+ protected void appendConfigPropsFooter() {}
+ }
+
+ // management properties
+
+ private static Properties mgmtProps;
+ private static ResourceBundle messageRB;
+ private static final String CONFIG_FILE =
+ "com.sun.management.config.file";
+ private static final String SNMP_PORT =
+ "com.sun.management.snmp.port";
+ private static final String JMXREMOTE =
+ "com.sun.management.jmxremote";
+ private static final String JMXREMOTE_PORT =
+ "com.sun.management.jmxremote.port";
+ private static final String RMI_PORT =
+ "com.sun.management.jmxremote.rmi.port";
+ private static final String ENABLE_THREAD_CONTENTION_MONITORING =
+ "com.sun.management.enableThreadContentionMonitoring";
+ private static final String LOCAL_CONNECTOR_ADDRESS_PROP =
+ "com.sun.management.jmxremote.localConnectorAddress";
+ private static final String SNMP_AGENT_NAME =
+ "SnmpAgent";
+
+ private static final String JDP_DEFAULT_ADDRESS = "224.0.23.178";
+ private static final int JDP_DEFAULT_PORT = 7095;
+
+ // 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
+ // return empty property set
+ private static Properties parseString(String args) {
+ Properties argProps = new Properties();
+ if (args != null && !args.trim().equals("")) {
+ for (String option : args.split(",")) {
+ String s[] = option.split("=", 2);
+ String name = s[0].trim();
+ String value = (s.length > 1) ? s[1].trim() : "";
+
+ if (!name.startsWith("com.sun.management.")) {
+ error(INVALID_OPTION, name);
+ }
+
+ argProps.setProperty(name, value);
+ }
+ }
+
+ return argProps;
+ }
+
+ // invoked by -javaagent or -Dcom.sun.management.agent.class
+ public static void premain(String args) throws Exception {
+ agentmain(args);
+ }
+
+ // invoked by attach mechanism
+ public static void agentmain(String args) throws Exception {
+ if (args == null || args.length() == 0) {
+ args = JMXREMOTE; // default to local management
+ }
+
+ Properties arg_props = parseString(args);
+
+ // Read properties from the config file
+ Properties config_props = new Properties();
+ String fname = arg_props.getProperty(CONFIG_FILE);
+ readConfiguration(fname, config_props);
+
+ // Arguments override config file
+ config_props.putAll(arg_props);
+ startAgent(config_props);
+ }
+
+ // jcmd ManagementAgent.start_local entry point
+ // Also called due to command-line via startAgent()
+ private static synchronized void startLocalManagementAgent() {
+ Properties agentProps = VMSupport.getAgentProperties();
+
+ // start local connector if not started
+ if (agentProps.get(LOCAL_CONNECTOR_ADDRESS_PROP) == null) {
+ JMXConnectorServer cs = ConnectorBootstrap.startLocalConnectorServer();
+ String address = cs.getAddress().toString();
+ // Add the local connector address to the agent properties
+ agentProps.put(LOCAL_CONNECTOR_ADDRESS_PROP, address);
+
+ try {
+ // export the address to the instrumentation buffer
+ ConnectorAddressLink.export(address);
+ } catch (Exception x) {
+ // Connector server started but unable to export address
+ // to instrumentation buffer - non-fatal error.
+ warning(EXPORT_ADDRESS_FAILED, x.getMessage());
+ }
+ }
+ }
+
+ // jcmd ManagementAgent.start entry point
+ // This method starts the remote JMX agent and starts neither
+ // the local JMX agent nor the SNMP agent
+ // @see #startLocalManagementAgent and also @see #startAgent.
+ private static synchronized void startRemoteManagementAgent(String args) throws Exception {
+ if (jmxServer != null) {
+ throw new RuntimeException(getText(INVALID_STATE, "Agent already started"));
+ }
+
+ try {
+ Properties argProps = parseString(args);
+ configProps = new Properties();
+
+ // Load the management properties from the config file
+ // if config file is not specified readConfiguration implicitly
+ // reads <java.home>/conf/management/management.properties
+
+ String fname = System.getProperty(CONFIG_FILE);
+ readConfiguration(fname, configProps);
+
+ // management properties can be overridden by system properties
+ // which take precedence
+ Properties sysProps = System.getProperties();
+ synchronized (sysProps) {
+ configProps.putAll(sysProps);
+ }
+
+ // if user specifies config file into command line for either
+ // jcmd utilities or attach command it overrides properties set in
+ // command line at the time of VM start
+ String fnameUser = argProps.getProperty(CONFIG_FILE);
+ if (fnameUser != null) {
+ readConfiguration(fnameUser, configProps);
+ }
+
+ // arguments specified in command line of jcmd utilities
+ // override both system properties and one set by config file
+ // specified in jcmd command line
+ configProps.putAll(argProps);
+
+ // jcmd doesn't allow to change ThreadContentionMonitoring, but user
+ // can specify this property inside config file, so enable optional
+ // monitoring functionality if this property is set
+ final String enableThreadContentionMonitoring =
+ configProps.getProperty(ENABLE_THREAD_CONTENTION_MONITORING);
+
+ if (enableThreadContentionMonitoring != null) {
+ ManagementFactory.getThreadMXBean().
+ setThreadContentionMonitoringEnabled(true);
+ }
+
+ String jmxremotePort = configProps.getProperty(JMXREMOTE_PORT);
+ if (jmxremotePort != null) {
+ jmxServer = ConnectorBootstrap.
+ startRemoteConnectorServer(jmxremotePort, configProps);
+
+ startDiscoveryService(configProps);
+ } else {
+ throw new AgentConfigurationError(INVALID_JMXREMOTE_PORT, "No port specified");
+ }
+ } catch (JdpException e) {
+ error(e);
+ } catch (AgentConfigurationError err) {
+ error(err.getError(), err.getParams());
+ }
+ }
+
+ private static synchronized void stopRemoteManagementAgent() throws Exception {
+
+ JdpController.stopDiscoveryService();
+
+ if (jmxServer != null) {
+ ConnectorBootstrap.unexportRegistry();
+ ConnectorAddressLink.unexportRemote();
+
+ // Attempt to stop already stopped 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);
+ String jmxremotePort = props.getProperty(JMXREMOTE_PORT);
+
+ // Enable optional monitoring functionality if requested
+ final String enableThreadContentionMonitoring =
+ props.getProperty(ENABLE_THREAD_CONTENTION_MONITORING);
+ if (enableThreadContentionMonitoring != null) {
+ ManagementFactory.getThreadMXBean().
+ setThreadContentionMonitoringEnabled(true);
+ }
+
+ try {
+ if (snmpPort != null) {
+ loadSnmpAgent(props);
+ }
+
+ /*
+ * If the jmxremote.port property is set then we start the
+ * RMIConnectorServer for remote M&M.
+ *
+ * If the jmxremote or jmxremote.port properties are set then
+ * we start a RMIConnectorServer for local M&M. The address
+ * of this "local" server is exported as a counter to the jstat
+ * instrumentation buffer.
+ */
+ if (jmxremote != null || jmxremotePort != null) {
+ if (jmxremotePort != null) {
+ jmxServer = ConnectorBootstrap.
+ startRemoteConnectorServer(jmxremotePort, props);
+ startDiscoveryService(props);
+ }
+ startLocalManagementAgent();
+ }
+
+ } catch (AgentConfigurationError e) {
+ error(e.getError(), e.getParams());
+ } catch (Exception e) {
+ error(e);
+ }
+ }
+
+ private static void startDiscoveryService(Properties props)
+ throws IOException, JdpException {
+ // Start discovery service if requested
+ String discoveryPort = props.getProperty("com.sun.management.jdp.port");
+ String discoveryAddress = props.getProperty("com.sun.management.jdp.address");
+ String discoveryShouldStart = props.getProperty("com.sun.management.jmxremote.autodiscovery");
+
+ // Decide whether we should start autodicovery service.
+ // To start autodiscovery following conditions should be met:
+ // autodiscovery==true OR (autodicovery==null AND jdp.port != NULL)
+
+ boolean shouldStart = false;
+ if (discoveryShouldStart == null){
+ shouldStart = (discoveryPort != null);
+ }
+ else{
+ try{
+ shouldStart = Boolean.parseBoolean(discoveryShouldStart);
+ } catch (NumberFormatException e) {
+ throw new AgentConfigurationError(AGENT_EXCEPTION, "Couldn't parse autodiscovery argument");
+ }
+ }
+
+ if (shouldStart) {
+ // port and address are required arguments and have no default values
+ InetAddress address;
+ try {
+ address = (discoveryAddress == null) ?
+ InetAddress.getByName(JDP_DEFAULT_ADDRESS) : InetAddress.getByName(discoveryAddress);
+ } catch (UnknownHostException e) {
+ throw new AgentConfigurationError(AGENT_EXCEPTION, e, "Unable to broadcast to requested address");
+ }
+
+ int port = JDP_DEFAULT_PORT;
+ if (discoveryPort != null) {
+ try {
+ port = Integer.parseInt(discoveryPort);
+ } catch (NumberFormatException e) {
+ throw new AgentConfigurationError(AGENT_EXCEPTION, "Couldn't parse JDP port argument");
+ }
+ }
+
+ // Rebuilding service URL to broadcast it
+ String jmxremotePort = props.getProperty(JMXREMOTE_PORT);
+ String rmiPort = props.getProperty(RMI_PORT);
+
+ JMXServiceURL url = jmxServer.getAddress();
+ String hostname = url.getHost();
+
+ String jmxUrlStr = (rmiPort != null)
+ ? String.format(
+ "service:jmx:rmi://%s:%s/jndi/rmi://%s:%s/jmxrmi",
+ hostname, rmiPort, hostname, jmxremotePort)
+ : String.format(
+ "service:jmx:rmi:///jndi/rmi://%s:%s/jmxrmi", hostname, jmxremotePort);
+
+ String instanceName = props.getProperty("com.sun.management.jdp.name");
+
+ JdpController.startDiscoveryService(address, port, instanceName, jmxUrlStr);
+ }
+ }
+
+ public static Properties loadManagementProperties() {
+ Properties props = new Properties();
+
+ // Load the management properties from the config file
+
+ String fname = System.getProperty(CONFIG_FILE);
+ readConfiguration(fname, props);
+
+ // management properties can be overridden by system properties
+ // which take precedence
+ Properties sysProps = System.getProperties();
+ synchronized (sysProps) {
+ props.putAll(sysProps);
+ }
+
+ return props;
+ }
+
+ public static synchronized Properties getManagementProperties() {
+ if (mgmtProps == null) {
+ String configFile = System.getProperty(CONFIG_FILE);
+ String snmpPort = System.getProperty(SNMP_PORT);
+ String jmxremote = System.getProperty(JMXREMOTE);
+ String jmxremotePort = System.getProperty(JMXREMOTE_PORT);
+
+ if (configFile == null && snmpPort == null
+ && jmxremote == null && jmxremotePort == null) {
+ // return if out-of-the-management option is not specified
+ return null;
+ }
+ mgmtProps = loadManagementProperties();
+ }
+ return mgmtProps;
+ }
+
+ private static void loadSnmpAgent(Properties props) {
+ /*
+ * Load the jdk.snmp service
+ */
+ AgentProvider provider = AccessController.doPrivileged(
+ (PrivilegedAction<AgentProvider>) () -> {
+ for (AgentProvider aProvider : ServiceLoader.loadInstalled(AgentProvider.class)) {
+ if (aProvider.getName().equals(SNMP_AGENT_NAME))
+ return aProvider;
+ }
+ return null;
+ }, null
+ );
+
+ if (provider != null) {
+ provider.startAgent(props);
+ } else { // snmp runtime doesn't exist - initialization fails
+ throw new UnsupportedOperationException("Unsupported management property: " + SNMP_PORT);
+ }
+ }
+
+ // read config file and initialize the properties
+ private static void readConfiguration(String fname, Properties p) {
+ if (fname == null) {
+ String home = System.getProperty("java.home");
+ if (home == null) {
+ throw new Error("Can't find java.home ??");
+ }
+ StringBuilder defaultFileName = new StringBuilder(home);
+ defaultFileName.append(File.separator).append("conf");
+ defaultFileName.append(File.separator).append("management");
+ defaultFileName.append(File.separator).append("management.properties");
+ // Set file name
+ fname = defaultFileName.toString();
+ }
+ final File configFile = new File(fname);
+ if (!configFile.exists()) {
+ error(CONFIG_FILE_NOT_FOUND, fname);
+ }
+
+ InputStream in = null;
+ try {
+ in = new FileInputStream(configFile);
+ BufferedInputStream bin = new BufferedInputStream(in);
+ p.load(bin);
+ } catch (FileNotFoundException e) {
+ error(CONFIG_FILE_OPEN_FAILED, e.getMessage());
+ } catch (IOException e) {
+ error(CONFIG_FILE_OPEN_FAILED, e.getMessage());
+ } catch (SecurityException e) {
+ error(CONFIG_FILE_ACCESS_DENIED, fname);
+ } finally {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e) {
+ error(CONFIG_FILE_CLOSE_FAILED, fname);
+ }
+ }
+ }
+ }
+
+ public static void startAgent() throws Exception {
+ String prop = System.getProperty("com.sun.management.agent.class");
+
+ // -Dcom.sun.management.agent.class not set so read management
+ // properties and start agent
+ if (prop == null) {
+ // initialize management properties
+ Properties props = getManagementProperties();
+ if (props != null) {
+ startAgent(props);
+ }
+ return;
+ }
+
+ // -Dcom.sun.management.agent.class=<agent classname>:<agent args>
+ String[] values = prop.split(":");
+ if (values.length < 1 || values.length > 2) {
+ error(AGENT_CLASS_INVALID, "\"" + prop + "\"");
+ }
+ String cname = values[0];
+ String args = (values.length == 2 ? values[1] : null);
+
+ if (cname == null || cname.length() == 0) {
+ error(AGENT_CLASS_INVALID, "\"" + prop + "\"");
+ }
+
+ if (cname != null) {
+ try {
+ // Instantiate the named class.
+ // invoke the premain(String args) method
+ Class<?> clz = ClassLoader.getSystemClassLoader().loadClass(cname);
+ Method premain = clz.getMethod("premain",
+ new Class<?>[]{String.class});
+ premain.invoke(null, /* static */
+ new Object[]{args});
+ } catch (ClassNotFoundException ex) {
+ error(AGENT_CLASS_NOT_FOUND, "\"" + cname + "\"");
+ } catch (NoSuchMethodException ex) {
+ error(AGENT_CLASS_PREMAIN_NOT_FOUND, "\"" + cname + "\"");
+ } catch (SecurityException ex) {
+ error(AGENT_CLASS_ACCESS_DENIED);
+ } catch (Exception ex) {
+ String msg = (ex.getCause() == null
+ ? ex.getMessage()
+ : ex.getCause().getMessage());
+ error(AGENT_CLASS_FAILED, msg);
+ }
+ }
+ }
+
+ public static void error(String key) {
+ String keyText = getText(key);
+ System.err.print(getText("agent.err.error") + ": " + keyText);
+ throw new RuntimeException(keyText);
+ }
+
+ public static void error(String key, String[] params) {
+ if (params == null || params.length == 0) {
+ error(key);
+ } else {
+ StringBuilder message = new StringBuilder(params[0]);
+ for (int i = 1; i < params.length; i++) {
+ message.append(' ').append(params[i]);
+ }
+ error(key, message.toString());
+ }
+ }
+
+ public static void error(String key, String message) {
+ String keyText = getText(key);
+ System.err.print(getText("agent.err.error") + ": " + keyText);
+ System.err.println(": " + message);
+ throw new RuntimeException(keyText + ": " + message);
+ }
+
+ public static void error(Exception e) {
+ e.printStackTrace();
+ System.err.println(getText(AGENT_EXCEPTION) + ": " + e.toString());
+ throw new RuntimeException(e);
+ }
+
+ public static void warning(String key, String message) {
+ System.err.print(getText("agent.err.warning") + ": " + getText(key));
+ System.err.println(": " + message);
+ }
+
+ private static void initResource() {
+ try {
+ messageRB =
+ ResourceBundle.getBundle("jdk.internal.agent.resources.agent");
+ } catch (MissingResourceException e) {
+ throw new Error("Fatal: Resource for management agent is missing");
+ }
+ }
+
+ public static String getText(String key) {
+ if (messageRB == null) {
+ initResource();
+ }
+ try {
+ return messageRB.getString(key);
+ } catch (MissingResourceException e) {
+ return "Missing management agent resource bundle: key = \"" + key + "\"";
+ }
+ }
+
+ public static String getText(String key, String... args) {
+ if (messageRB == null) {
+ initResource();
+ }
+ String format = messageRB.getString(key);
+ if (format == null) {
+ format = "missing resource key: key = \"" + key + "\", "
+ + "arguments = \"{0}\", \"{1}\", \"{2}\"";
+ }
+ return MessageFormat.format(format, (Object[]) args);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/AgentConfigurationError.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.agent;
+
+/**
+ * Configuration Error thrown by a management agent.
+ */
+public class AgentConfigurationError extends Error {
+ public static final String AGENT_EXCEPTION =
+ "agent.err.exception";
+ public static final String CONFIG_FILE_NOT_FOUND =
+ "agent.err.configfile.notfound";
+ public static final String CONFIG_FILE_OPEN_FAILED =
+ "agent.err.configfile.failed";
+ public static final String CONFIG_FILE_CLOSE_FAILED =
+ "agent.err.configfile.closed.failed";
+ public static final String CONFIG_FILE_ACCESS_DENIED =
+ "agent.err.configfile.access.denied";
+ public static final String EXPORT_ADDRESS_FAILED =
+ "agent.err.exportaddress.failed";
+ public static final String AGENT_CLASS_NOT_FOUND =
+ "agent.err.agentclass.notfound";
+ public static final String AGENT_CLASS_FAILED =
+ "agent.err.agentclass.failed";
+ public static final String AGENT_CLASS_PREMAIN_NOT_FOUND =
+ "agent.err.premain.notfound";
+ public static final String AGENT_CLASS_ACCESS_DENIED =
+ "agent.err.agentclass.access.denied";
+ public static final String AGENT_CLASS_INVALID =
+ "agent.err.invalid.agentclass";
+ public static final String INVALID_JMXREMOTE_PORT =
+ "agent.err.invalid.jmxremote.port";
+ public static final String INVALID_JMXREMOTE_RMI_PORT =
+ "agent.err.invalid.jmxremote.rmi.port";
+ public static final String PASSWORD_FILE_NOT_SET =
+ "agent.err.password.file.notset";
+ public static final String PASSWORD_FILE_NOT_READABLE =
+ "agent.err.password.file.not.readable";
+ public static final String PASSWORD_FILE_READ_FAILED =
+ "agent.err.password.file.read.failed";
+ public static final String PASSWORD_FILE_NOT_FOUND =
+ "agent.err.password.file.notfound";
+ public static final String ACCESS_FILE_NOT_SET =
+ "agent.err.access.file.notset";
+ public static final String ACCESS_FILE_NOT_READABLE =
+ "agent.err.access.file.not.readable";
+ public static final String ACCESS_FILE_READ_FAILED =
+ "agent.err.access.file.read.failed";
+ public static final String ACCESS_FILE_NOT_FOUND =
+ "agent.err.access.file.notfound";
+ public static final String PASSWORD_FILE_ACCESS_NOT_RESTRICTED =
+ "agent.err.password.file.access.notrestricted";
+ public static final String FILE_ACCESS_NOT_RESTRICTED =
+ "agent.err.file.access.not.restricted";
+ public static final String FILE_NOT_FOUND =
+ "agent.err.file.not.found";
+ public static final String FILE_NOT_READABLE =
+ "agent.err.file.not.readable";
+ public static final String FILE_NOT_SET =
+ "agent.err.file.not.set";
+ public static final String FILE_READ_FAILED =
+ "agent.err.file.read.failed";
+ public static final String CONNECTOR_SERVER_IO_ERROR =
+ "agent.err.connector.server.io.error";
+ public static final String INVALID_OPTION =
+ "agent.err.invalid.option";
+ public static final String INVALID_STATE =
+ "agent.err.invalid.state";
+
+ private final String error;
+ private final String[] params;
+
+ public AgentConfigurationError(String error) {
+ super();
+ this.error = error;
+ this.params = null;
+ }
+
+ public AgentConfigurationError(String error, Throwable cause) {
+ super(cause);
+ this.error = error;
+ this.params = null;
+ }
+
+ public AgentConfigurationError(String error, String... params) {
+ super();
+ this.error = error;
+ this.params = params.clone();
+ }
+
+ public AgentConfigurationError(String error, Throwable cause, String... params) {
+ super(cause);
+ this.error = error;
+ this.params = params.clone();
+ }
+
+ public String getError() {
+ return error;
+ }
+
+ public String[] getParams() {
+ return params.clone();
+ }
+
+ private static final long serialVersionUID = 1211605593516195475L;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/ConnectorAddressLink.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,218 @@
+/*
+ * 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
+ * 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 jdk.internal.agent;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jdk.internal.perf.Perf;
+import sun.management.counter.Units;
+import sun.management.counter.Counter;
+import sun.management.counter.perf.PerfInstrumentation;
+
+/**
+ * A utility class to support the exporting and importing of the address
+ * of a connector server using the instrumentation buffer.
+ *
+ * @since 1.5
+ */
+public class ConnectorAddressLink {
+ /**
+ * A simple wrapper for the perf-counter backing {@linkplain ByteBuffer}
+ */
+ private static final class PerfHandle {
+ private ByteBuffer bb;
+
+ private PerfHandle(ByteBuffer bb) {
+ this.bb = bb.order(ByteOrder.nativeOrder());
+ }
+
+ private void putLong(long l) {
+ this.bb = bb.clear();
+ this.bb.asLongBuffer().put(l);
+ }
+ }
+
+ private static final String CONNECTOR_ADDRESS_COUNTER =
+ "sun.management.JMXConnectorServer.address";
+ private static final String REMOTE_CONNECTOR_STATE_COUNTER =
+ "sun.management.JMXConnectorServer.remote.enabled";
+
+ /*
+ * The format of the jvmstat counters representing the properties of
+ * a given out-of-the-box JMX remote connector will be as follows:
+ *
+ * sun.management.JMXConnectorServer.<counter>.<key>=<value>
+ *
+ * where:
+ *
+ * counter = index computed by this class which uniquely identifies
+ * an out-of-the-box JMX remote connector running in this
+ * Java virtual machine.
+ * key/value = a given key/value pair in the map supplied to the
+ * exportRemote() method.
+ *
+ * For example,
+ *
+ * sun.management.JMXConnectorServer.0.remoteAddress=service:jmx:rmi:///jndi/rmi://myhost:5000/jmxrmi
+ * sun.management.JMXConnectorServer.0.authenticate=false
+ * sun.management.JMXConnectorServer.0.ssl=false
+ * sun.management.JMXConnectorServer.0.sslRegistry=false
+ * sun.management.JMXConnectorServer.0.sslNeedClientAuth=false
+ */
+ private static final String REMOTE_CONNECTOR_COUNTER_PREFIX =
+ "sun.management.JMXConnectorServer.";
+
+ /*
+ * JMX remote connector counter (it will be incremented every
+ * time a new out-of-the-box JMX remote connector is created).
+ */
+ private static final AtomicInteger counter = new AtomicInteger();
+
+ private static PerfHandle remotePerfHandle = null;
+
+ /**
+ * Exports the specified connector address to the instrumentation buffer
+ * so that it can be read by this or other Java virtual machines running
+ * on the same system.
+ *
+ * @param address The connector address.
+ */
+ public static void export(String address) {
+ if (address == null || address.length() == 0) {
+ throw new IllegalArgumentException("address not specified");
+ }
+ Perf perf = Perf.getPerf();
+ perf.createString(
+ CONNECTOR_ADDRESS_COUNTER, 1, Units.STRING.intValue(), address);
+ }
+
+ public static void unexportRemote() {
+ unexport(remotePerfHandle);
+ }
+
+ private static void unexport(PerfHandle ph) {
+ if (ph != null) {
+ ph.putLong(-1L);
+ }
+ }
+
+ /**
+ * Imports the connector address from the instrument buffer
+ * of the specified Java virtual machine.
+ *
+ * @param vmid an identifier that uniquely identifies a local Java virtual
+ * machine, or <code>0</code> to indicate the current Java virtual machine.
+ *
+ * @return the value of the connector address, or <code>null</code> if the
+ * target VM has not exported a connector address.
+ *
+ * @throws IOException An I/O error occurred while trying to acquire the
+ * instrumentation buffer.
+ */
+ public static String importFrom(int vmid) throws IOException {
+ Perf perf = Perf.getPerf();
+ ByteBuffer bb;
+ try {
+ bb = perf.attach(vmid, "r");
+ } catch (IllegalArgumentException iae) {
+ throw new IOException(iae.getMessage());
+ }
+ List<Counter> counters =
+ new PerfInstrumentation(bb).findByPattern(CONNECTOR_ADDRESS_COUNTER);
+ Iterator<Counter> i = counters.iterator();
+ if (i.hasNext()) {
+ Counter c = i.next();
+ return (String) c.getValue();
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Exports the specified remote connector address and associated
+ * configuration properties to the instrumentation buffer so that
+ * it can be read by this or other Java virtual machines running
+ * on the same system.
+ *
+ * @param properties The remote connector address properties.
+ */
+ public static void exportRemote(Map<String, String> properties) {
+ final int index = counter.getAndIncrement();
+ Perf perf = Perf.getPerf();
+ for (Map.Entry<String, String> entry : properties.entrySet()) {
+ perf.createString(REMOTE_CONNECTOR_COUNTER_PREFIX + index + "." +
+ entry.getKey(), 1, Units.STRING.intValue(), entry.getValue());
+ }
+ if (remotePerfHandle != null) {
+ remotePerfHandle.putLong(index);
+ } else {
+ remotePerfHandle = new PerfHandle(
+ perf.createLong(REMOTE_CONNECTOR_STATE_COUNTER, 1, Units.NONE.intValue(), (long)index)
+ );
+ }
+ }
+
+ /**
+ * Imports the remote connector address and associated
+ * configuration properties from the instrument buffer
+ * of the specified Java virtual machine.
+ *
+ * @param vmid an identifier that uniquely identifies a local Java virtual
+ * machine, or <code>0</code> to indicate the current Java virtual machine.
+ *
+ * @return a map containing the remote connector's properties, or an empty
+ * map if the target VM has not exported the remote connector's properties.
+ *
+ * @throws IOException An I/O error occurred while trying to acquire the
+ * instrumentation buffer.
+ */
+ public static Map<String, String> importRemoteFrom(int vmid) throws IOException {
+ Perf perf = Perf.getPerf();
+ ByteBuffer bb;
+ try {
+ bb = perf.attach(vmid, "r");
+ } catch (IllegalArgumentException iae) {
+ throw new IOException(iae.getMessage());
+ }
+ List<Counter> counters = new PerfInstrumentation(bb).getAllCounters();
+ Map<String, String> properties = new HashMap<>();
+ for (Counter c : counters) {
+ String name = c.getName();
+ if (name.startsWith(REMOTE_CONNECTOR_COUNTER_PREFIX) &&
+ !name.equals(CONNECTOR_ADDRESS_COUNTER)) {
+ properties.put(name, c.getValue().toString());
+ }
+ }
+ return properties;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/FileSystem.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2004, 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 jdk.internal.agent;
+
+import java.io.File;
+import java.io.IOException;
+
+/*
+ * Utility class to support file system operations
+ *
+ * @since 1.5
+ */
+public abstract class FileSystem {
+
+ private static final Object lock = new Object();
+ private static FileSystem fs;
+
+ protected FileSystem() { }
+
+ /**
+ * Opens the file system
+ */
+ public static FileSystem open() {
+ synchronized (lock) {
+ if (fs == null) {
+ fs = new FileSystemImpl();
+ }
+ return fs;
+ }
+ }
+
+ /**
+ * Tells whether or not the specified file is located on a
+ * file system that supports file security or not.
+ *
+ * @throws IOException if an I/O error occurs.
+ */
+ public abstract boolean supportsFileSecurity(File f) throws IOException;
+
+ /**
+ * Tell whether or not the specified file is accessible
+ * by anything other than the file owner.
+ *
+ * @throws IOException if an I/O error occurs.
+ *
+ * @throws UnsupportedOperationException
+ * If file is located on a file system that doesn't support
+ * file security.
+ */
+ public abstract boolean isAccessUserOnly(File f) throws IOException;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/resources/agent.properties Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,71 @@
+#
+# Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+agent.err.error = Error
+agent.err.exception = Exception thrown by the agent
+agent.err.warning = Warning
+
+agent.err.configfile.notfound = Config file not found
+agent.err.configfile.failed = Failed in reading the config file
+agent.err.configfile.closed.failed = Failed in closing the config file
+agent.err.configfile.access.denied = Access to the config file is denied
+
+agent.err.exportaddress.failed = Export of JMX connector address to instrumentation buffer failed
+
+agent.err.agentclass.notfound = Management agent class not found
+agent.err.agentclass.failed = Management agent class failed
+agent.err.premain.notfound = premain(String) does not exist in agent class
+agent.err.agentclass.access.denied = Access to premain(String) is denied
+agent.err.invalid.agentclass = Invalid com.sun.management.agent.class property value
+agent.err.invalid.state = Invalid agent state: {0}
+agent.err.invalid.jmxremote.port = Invalid com.sun.management.jmxremote.port number
+agent.err.invalid.jmxremote.rmi.port = Invalid com.sun.management.jmxremote.rmi.port number
+
+agent.err.file.not.set = File not specified
+agent.err.file.not.readable = File not readable
+agent.err.file.read.failed = Failed in reading the file
+agent.err.file.not.found = File not found
+agent.err.file.access.not.restricted = File read access must be restricted
+
+agent.err.password.file.notset = Password file is not specified but com.sun.management.jmxremote.authenticate=true
+agent.err.password.file.not.readable = Password file not readable
+agent.err.password.file.read.failed = Failed in reading the password file
+agent.err.password.file.notfound = Password file not found
+agent.err.password.file.access.notrestricted = Password file read access must be restricted
+
+agent.err.access.file.notset = Access file is not specified but com.sun.management.jmxremote.authenticate=true
+agent.err.access.file.not.readable = Access file not readable
+agent.err.access.file.read.failed = Failed in reading the access file
+agent.err.access.file.notfound = Access file not found
+
+agent.err.connector.server.io.error = JMX connector server communication error
+
+agent.err.invalid.option = Invalid option specified
+
+jmxremote.ConnectorBootstrap.starting = Starting JMX Connector Server:
+jmxremote.ConnectorBootstrap.noAuthentication = No Authentication
+jmxremote.ConnectorBootstrap.ready = JMX Connector ready at: {0}
+jmxremote.ConnectorBootstrap.password.readonly = Password file read access must be restricted: {0}
+jmxremote.ConnectorBootstrap.file.readonly = File read access must be restricted: {0}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/resources/agent_de.properties Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,71 @@
+#
+# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+agent.err.error = Fehler
+agent.err.exception = Ausnahme von Agent ausgel\u00F6st
+agent.err.warning = Warnung
+
+agent.err.configfile.notfound = Konfigurationsdatei wurde nicht gefunden
+agent.err.configfile.failed = Konfigurationsdatei konnte nicht gelesen werden
+agent.err.configfile.closed.failed = Konfigurationsdatei konnte nicht geschlossen werden
+agent.err.configfile.access.denied = Zugriff auf Konfigurationsdatei wurde abgelehnt
+
+agent.err.exportaddress.failed = Export der JMX-Connector-Adresse in Instrumentierungspuffer nicht erfolgreich
+
+agent.err.agentclass.notfound = Management Agent-Klasse nicht gefunden
+agent.err.agentclass.failed = Management Agent-Klasse nicht erfolgreich
+agent.err.premain.notfound = premain(String) ist in Agent-Klasse nicht vorhanden
+agent.err.agentclass.access.denied = Zugriff auf premain(String) wurde abgelehnt
+agent.err.invalid.agentclass = Ung\u00FCltiger Eigenschaftswert f\u00FCr com.sun.management.agent.class
+agent.err.invalid.state = Ung\u00FCltiger Agent-Zustand: {0}
+agent.err.invalid.jmxremote.port = Ung\u00FCltige Nummer f\u00FCr com.sun.management.jmxremote.port
+agent.err.invalid.jmxremote.rmi.port = Ung\u00FCltige Nummer f\u00FCr com.sun.management.jmxremote.rmi.port
+
+agent.err.file.not.set = Datei nicht angegeben
+agent.err.file.not.readable = Datei nicht lesbar
+agent.err.file.read.failed = Datei konnte nicht gelesen werden
+agent.err.file.not.found = Datei wurde nicht gefunden
+agent.err.file.access.not.restricted = Lesezugriff auf Datei muss eingeschr\u00E4nkt werden
+
+agent.err.password.file.notset = Es wurde keine Kennwortdatei angegeben, obwohl com.sun.management.jmxremote.authenticate auf "true" gesetzt ist
+agent.err.password.file.not.readable = Kennwortdatei nicht lesbar
+agent.err.password.file.read.failed = Kennwortdatei konnte nicht gelesen werden
+agent.err.password.file.notfound = Kennwortdatei nicht gefunden
+agent.err.password.file.access.notrestricted = Lesezugriff auf Kennwortdatei muss eingeschr\u00E4nkt werden
+
+agent.err.access.file.notset = Es wurde keine Zugriffsdatei angegeben, obwohl com.sun.management.jmxremote.authenticate auf "true" gesetzt ist
+agent.err.access.file.not.readable = Zugriffsdatei kann nicht gelesen werden
+agent.err.access.file.read.failed = Zugriffsdatei konnte nicht gelesen werden
+agent.err.access.file.notfound = Zugriffsdatei nicht gefunden
+
+agent.err.connector.server.io.error = Fehler bei JMX-Connector-Serverkommunikation
+
+agent.err.invalid.option = Ung\u00FCltige Option angegeben
+
+jmxremote.ConnectorBootstrap.starting = JMX-Connector-Server starten:
+jmxremote.ConnectorBootstrap.noAuthentication = Keine Authentifizierung
+jmxremote.ConnectorBootstrap.ready = JMX-Connector bereit unter: {0}
+jmxremote.ConnectorBootstrap.password.readonly = Lesezugriff auf Kennwortdatei muss eingeschr\u00E4nkt werden: {0}
+jmxremote.ConnectorBootstrap.file.readonly = Lesezugriff auf Datei muss eingeschr\u00E4nkt werden: {0}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/resources/agent_es.properties Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,71 @@
+#
+# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+agent.err.error = Error
+agent.err.exception = Excepci\u00F3n devuelta por el agente
+agent.err.warning = Advertencia
+
+agent.err.configfile.notfound = No se ha encontrado el archivo de configuraci\u00F3n
+agent.err.configfile.failed = Fallo al leer el archivo de configuraci\u00F3n
+agent.err.configfile.closed.failed = Fallo al cerrar el archivo de configuraci\u00F3n
+agent.err.configfile.access.denied = Acceso denegado al archivo de configuraci\u00F3n
+
+agent.err.exportaddress.failed = Fallo al exportar la direcci\u00F3n del conector JMX al buffer de instrumentaci\u00F3n
+
+agent.err.agentclass.notfound = Clase de agente de gesti\u00F3n no encontrada
+agent.err.agentclass.failed = Fallo de clase de agente de gesti\u00F3n
+agent.err.premain.notfound = premain(String) no existe en la clase del agente
+agent.err.agentclass.access.denied = Acceso denegado a premain(String)
+agent.err.invalid.agentclass = Valor de propiedad com.sun.management.agent.class no v\u00E1lido
+agent.err.invalid.state = Estado de agente no v\u00E1lido: {0}
+agent.err.invalid.jmxremote.port = N\u00FAmero com.sun.management.jmxremote.port no v\u00E1lido
+agent.err.invalid.jmxremote.rmi.port = N\u00FAmero com.sun.management.jmxremote.rmi.port no v\u00E1lido
+
+agent.err.file.not.set = Archivo no especificado
+agent.err.file.not.readable = Archivo ilegible
+agent.err.file.read.failed = Fallo al leer el archivo
+agent.err.file.not.found = Archivo no encontrado
+agent.err.file.access.not.restricted = El acceso de lectura al archivo debe ser restringido
+
+agent.err.password.file.notset = El archivo de contrase\u00F1as no se ha especificado, pero com.sun.management.jmxremote.authenticate=true
+agent.err.password.file.not.readable = No se puede leer el archivo de contrase\u00F1as
+agent.err.password.file.read.failed = Fallo al leer el archivo de contrase\u00F1as
+agent.err.password.file.notfound = Archivo de contrase\u00F1as no encontrado
+agent.err.password.file.access.notrestricted = Se debe restringir el acceso de lectura al archivo de contrase\u00F1as
+
+agent.err.access.file.notset = El archivo de acceso no se ha especificado, pero com.sun.management.jmxremote.authenticate=true
+agent.err.access.file.not.readable = No se puede leer el archivo de acceso
+agent.err.access.file.read.failed = Fallo al leer el archivo de acceso
+agent.err.access.file.notfound = Archivo de acceso no encontrado
+
+agent.err.connector.server.io.error = Error de comunicaci\u00F3n con el servidor de conector JMX
+
+agent.err.invalid.option = Opci\u00F3n especificada no v\u00E1lida
+
+jmxremote.ConnectorBootstrap.starting = Iniciando servidor de conector JMX:
+jmxremote.ConnectorBootstrap.noAuthentication = Sin autenticaci\u00F3n
+jmxremote.ConnectorBootstrap.ready = Conector JMX listo en: {0}
+jmxremote.ConnectorBootstrap.password.readonly = Se debe restringir el acceso de lectura al archivo de contrase\u00F1as: {0}
+jmxremote.ConnectorBootstrap.file.readonly = El acceso de lectura al archivo debe ser restringido: {0}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/resources/agent_fr.properties Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,71 @@
+#
+# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+agent.err.error = Erreur
+agent.err.exception = Exception envoy\u00E9e par l'agent
+agent.err.warning = Avertissement
+
+agent.err.configfile.notfound = Fichier de configuration introuvable
+agent.err.configfile.failed = Impossible de lire le fichier de configuration
+agent.err.configfile.closed.failed = Impossible de fermer le fichier de configuration
+agent.err.configfile.access.denied = Acc\u00E8s refus\u00E9 au fichier de configuration
+
+agent.err.exportaddress.failed = Impossible d'exporter l'adresse du connecteur JMX dans le tampon d'instrumentation
+
+agent.err.agentclass.notfound = Classe d'agents de gestion introuvable
+agent.err.agentclass.failed = Echec de la classe d'agents de gestion
+agent.err.premain.notfound = premain(String) n'existe pas dans la classe d'agents
+agent.err.agentclass.access.denied = Acc\u00E8s \u00E0 premain(String) refus\u00E9
+agent.err.invalid.agentclass = Valeur de propri\u00E9t\u00E9 com.sun.management.agent.class incorrecte
+agent.err.invalid.state = Etat de l''agent non valide : {0}
+agent.err.invalid.jmxremote.port = Num\u00E9ro com.sun.management.jmxremote.port incorrect
+agent.err.invalid.jmxremote.rmi.port = Num\u00E9ro com.sun.management.jmxremote.rmi.port non valide
+
+agent.err.file.not.set = Fichier non sp\u00E9cifi\u00E9
+agent.err.file.not.readable = Fichier illisible
+agent.err.file.read.failed = Impossible de lire le fichier
+agent.err.file.not.found = Fichier introuvable
+agent.err.file.access.not.restricted = L'acc\u00E8s en lecture au fichier doit \u00EAtre limit\u00E9
+
+agent.err.password.file.notset = Le fichier de mots de passe n'est pas sp\u00E9cifi\u00E9 mais com.sun.management.jmxremote.authenticate=true
+agent.err.password.file.not.readable = Fichier de mots de passe illisible
+agent.err.password.file.read.failed = Impossible de lire le fichier de mots de passe
+agent.err.password.file.notfound = Fichier de mots de passe introuvable
+agent.err.password.file.access.notrestricted = L'acc\u00E8s en lecture au fichier de mots de passe doit \u00EAtre limit\u00E9
+
+agent.err.access.file.notset = Le fichier d'acc\u00E8s n'est pas sp\u00E9cifi\u00E9 mais com.sun.management.jmxremote.authenticate=true
+agent.err.access.file.not.readable = Fichier d'acc\u00E8s illisible
+agent.err.access.file.read.failed = Impossible de lire le fichier d'acc\u00E8s
+agent.err.access.file.notfound = Fichier d'acc\u00E8s introuvable
+
+agent.err.connector.server.io.error = Erreur de communication avec le serveur du connecteur JMX
+
+agent.err.invalid.option = Option sp\u00E9cifi\u00E9e non valide
+
+jmxremote.ConnectorBootstrap.starting = D\u00E9marrage du serveur du connecteur JMX :
+jmxremote.ConnectorBootstrap.noAuthentication = Pas d'authentification
+jmxremote.ConnectorBootstrap.ready = Connecteur JMX pr\u00EAt \u00E0 : {0}
+jmxremote.ConnectorBootstrap.password.readonly = L''acc\u00E8s en lecture au fichier de mots de passe doit \u00EAtre limit\u00E9 : {0}
+jmxremote.ConnectorBootstrap.file.readonly = L''acc\u00E8s en lecture au fichier doit \u00EAtre limit\u00E9 : {0}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/resources/agent_it.properties Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,71 @@
+#
+# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+agent.err.error = Errore
+agent.err.exception = Eccezione dell'agente
+agent.err.warning = Avvertenza
+
+agent.err.configfile.notfound = File di configurazione non trovato
+agent.err.configfile.failed = Errore di lettura file di configurazione
+agent.err.configfile.closed.failed = Errore di chiusura file di configurazione
+agent.err.configfile.access.denied = Accesso negato al file di configurazione
+
+agent.err.exportaddress.failed = Errore di esportazione dell'indirizzo connettore JMX nel buffer strumenti
+
+agent.err.agentclass.notfound = Classe agente gestione non trovata
+agent.err.agentclass.failed = Errore classe agente gestione
+agent.err.premain.notfound = premain(String) non esiste nella classe agente
+agent.err.agentclass.access.denied = Accesso negato a premain(String)
+agent.err.invalid.agentclass = Valore propriet\u00E0 com.sun.management.agent.class non valido
+agent.err.invalid.state = Stato agente non valido: {0}
+agent.err.invalid.jmxremote.port = Numero com.sun.management.jmxremote.port non valido
+agent.err.invalid.jmxremote.rmi.port = Numero com.sun.management.jmxremote.rmi.port non valido
+
+agent.err.file.not.set = File non specificato
+agent.err.file.not.readable = File non leggibile
+agent.err.file.read.failed = Errore di lettura file
+agent.err.file.not.found = File non trovato
+agent.err.file.access.not.restricted = Limitare l'accesso in lettura al file
+
+agent.err.password.file.notset = Il password file non \u00E8 specificato ma com.sun.management.jmxremote.authenticate=true
+agent.err.password.file.not.readable = Password file non leggibile
+agent.err.password.file.read.failed = Errore di lettura password file
+agent.err.password.file.notfound = Password file non trovato
+agent.err.password.file.access.notrestricted = Limitare l'accesso in lettura al password file
+
+agent.err.access.file.notset = Il file di accesso non \u00E8 specificato ma com.sun.management.jmxremote.authenticate=true
+agent.err.access.file.not.readable = File di accesso non leggibile
+agent.err.access.file.read.failed = Errore di lettura file di accesso
+agent.err.access.file.notfound = File di accesso non trovato
+
+agent.err.connector.server.io.error = Errore di comunicazione server del connettore JMX
+
+agent.err.invalid.option = Specificata opzione non valida
+
+jmxremote.ConnectorBootstrap.starting = Avvio del server connettore JMX:
+jmxremote.ConnectorBootstrap.noAuthentication = Nessuna autenticazione
+jmxremote.ConnectorBootstrap.ready = Connettore JMX pronto in: {0}
+jmxremote.ConnectorBootstrap.password.readonly = Limitare l''accesso in lettura al password file: {0}
+jmxremote.ConnectorBootstrap.file.readonly = Limitare l''accesso in lettura al file: {0}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/resources/agent_ja.properties Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,71 @@
+#
+# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+agent.err.error = \u30A8\u30E9\u30FC
+agent.err.exception = \u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u304C\u4F8B\u5916\u3092\u30B9\u30ED\u30FC\u3057\u307E\u3057\u305F
+agent.err.warning = \u8B66\u544A
+
+agent.err.configfile.notfound = \u69CB\u6210\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
+agent.err.configfile.failed = \u69CB\u6210\u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u306B\u5931\u6557\u3057\u307E\u3057\u305F
+agent.err.configfile.closed.failed = \u69CB\u6210\u30D5\u30A1\u30A4\u30EB\u3092\u9589\u3058\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F
+agent.err.configfile.access.denied = \u69CB\u6210\u30D5\u30A1\u30A4\u30EB\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u304C\u62D2\u5426\u3055\u308C\u307E\u3057\u305F
+
+agent.err.exportaddress.failed = JMX\u30B3\u30CD\u30AF\u30BF\u30FB\u30A2\u30C9\u30EC\u30B9\u306E\u8A08\u6E2C\u30D0\u30C3\u30D5\u30A1\u3078\u306E\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u304C\u5931\u6557\u3057\u307E\u3057\u305F
+
+agent.err.agentclass.notfound = \u7BA1\u7406\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30AF\u30E9\u30B9\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
+agent.err.agentclass.failed = \u7BA1\u7406\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30AF\u30E9\u30B9\u304C\u5931\u6557\u3057\u307E\u3057\u305F
+agent.err.premain.notfound = premain(String)\u304C\u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u30FB\u30AF\u30E9\u30B9\u306B\u5B58\u5728\u3057\u307E\u305B\u3093
+agent.err.agentclass.access.denied = premain(String)\u3078\u306E\u30A2\u30AF\u30BB\u30B9\u304C\u62D2\u5426\u3055\u308C\u307E\u3057\u305F
+agent.err.invalid.agentclass = com.sun.management.agent.class\u30D7\u30ED\u30D1\u30C6\u30A3\u306E\u5024\u304C\u7121\u52B9\u3067\u3059
+agent.err.invalid.state = \u30A8\u30FC\u30B8\u30A7\u30F3\u30C8\u306E\u72B6\u614B\u304C\u7121\u52B9\u3067\u3059: {0}
+agent.err.invalid.jmxremote.port = com.sun.management.jmxremote.port\u306E\u756A\u53F7\u304C\u7121\u52B9\u3067\u3059
+agent.err.invalid.jmxremote.rmi.port = com.sun.management.jmxremote.rmi.port\u306E\u756A\u53F7\u304C\u7121\u52B9\u3067\u3059
+
+agent.err.file.not.set = \u30D5\u30A1\u30A4\u30EB\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093
+agent.err.file.not.readable = \u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u307F\u53D6\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u305B\u3093
+agent.err.file.read.failed = \u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u306B\u5931\u6557\u3057\u307E\u3057\u305F
+agent.err.file.not.found = \u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093\u3067\u3057\u305F
+agent.err.file.access.not.restricted = \u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u30A2\u30AF\u30BB\u30B9\u306F\u5236\u9650\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
+
+agent.err.password.file.notset = \u30D1\u30B9\u30EF\u30FC\u30C9\u30FB\u30D5\u30A1\u30A4\u30EB\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u304C\u3001com.sun.management.jmxremote.authenticate=true\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059
+agent.err.password.file.not.readable = \u30D1\u30B9\u30EF\u30FC\u30C9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u307F\u53D6\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u305B\u3093
+agent.err.password.file.read.failed = \u30D1\u30B9\u30EF\u30FC\u30C9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u306B\u5931\u6557\u3057\u307E\u3057\u305F
+agent.err.password.file.notfound = \u30D1\u30B9\u30EF\u30FC\u30C9\u30FB\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
+agent.err.password.file.access.notrestricted = \u30D1\u30B9\u30EF\u30FC\u30C9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u30A2\u30AF\u30BB\u30B9\u306F\u5236\u9650\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059
+
+agent.err.access.file.notset = \u30A2\u30AF\u30BB\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u304C\u6307\u5B9A\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u304C\u3001com.sun.management.jmxremote.authenticate=true\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u307E\u3059
+agent.err.access.file.not.readable = \u30A2\u30AF\u30BB\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u3092\u8AAD\u307F\u53D6\u308B\u3053\u3068\u304C\u3067\u304D\u307E\u305B\u3093
+agent.err.access.file.read.failed = \u30A2\u30AF\u30BB\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u306B\u5931\u6557\u3057\u307E\u3057\u305F
+agent.err.access.file.notfound = \u30A2\u30AF\u30BB\u30B9\u30FB\u30D5\u30A1\u30A4\u30EB\u304C\u898B\u3064\u304B\u308A\u307E\u305B\u3093
+
+agent.err.connector.server.io.error = JMX\u30B3\u30CD\u30AF\u30BF\u30FB\u30B5\u30FC\u30D0\u30FC\u306E\u901A\u4FE1\u30A8\u30E9\u30FC
+
+agent.err.invalid.option = \u7121\u52B9\u306A\u30AA\u30D7\u30B7\u30E7\u30F3\u304C\u6307\u5B9A\u3055\u308C\u307E\u3057\u305F
+
+jmxremote.ConnectorBootstrap.starting = JMX\u30B3\u30CD\u30AF\u30BF\u30FB\u30B5\u30FC\u30D0\u30FC\u3092\u8D77\u52D5\u3057\u3066\u3044\u307E\u3059:
+jmxremote.ConnectorBootstrap.noAuthentication = \u8A8D\u8A3C\u306A\u3057
+jmxremote.ConnectorBootstrap.ready = JMX\u30B3\u30CD\u30AF\u30BF\u306E\u6E96\u5099\u304C\u3067\u304D\u307E\u3057\u305F: {0}
+jmxremote.ConnectorBootstrap.password.readonly = \u30D1\u30B9\u30EF\u30FC\u30C9\u30FB\u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u30A2\u30AF\u30BB\u30B9\u306F\u5236\u9650\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059: {0}
+jmxremote.ConnectorBootstrap.file.readonly = \u30D5\u30A1\u30A4\u30EB\u306E\u8AAD\u53D6\u308A\u30A2\u30AF\u30BB\u30B9\u306F\u5236\u9650\u3059\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059: {0}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/resources/agent_ko.properties Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,71 @@
+#
+# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+agent.err.error = \uC624\uB958
+agent.err.exception = \uC5D0\uC774\uC804\uD2B8\uC5D0 \uC608\uC678\uC0AC\uD56D\uC774 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.
+agent.err.warning = \uACBD\uACE0
+
+agent.err.configfile.notfound = \uAD6C\uC131 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
+agent.err.configfile.failed = \uAD6C\uC131 \uD30C\uC77C \uC77D\uAE30\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.
+agent.err.configfile.closed.failed = \uAD6C\uC131 \uD30C\uC77C \uB2EB\uAE30\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.
+agent.err.configfile.access.denied = \uAD6C\uC131 \uD30C\uC77C\uC5D0 \uB300\uD55C \uC561\uC138\uC2A4\uAC00 \uAC70\uBD80\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
+
+agent.err.exportaddress.failed = \uAE30\uAE30 \uBC84\uD37C\uB85C JMX \uCEE4\uB125\uD130 \uC8FC\uC18C \uC775\uC2A4\uD3EC\uD2B8\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.
+
+agent.err.agentclass.notfound = \uAD00\uB9AC \uC5D0\uC774\uC804\uD2B8 \uD074\uB798\uC2A4\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
+agent.err.agentclass.failed = \uAD00\uB9AC \uC5D0\uC774\uC804\uD2B8 \uD074\uB798\uC2A4\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.
+agent.err.premain.notfound = \uC5D0\uC774\uC804\uD2B8 \uD074\uB798\uC2A4\uC5D0 premain(\uBB38\uC790\uC5F4)\uC774 \uC874\uC7AC\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.
+agent.err.agentclass.access.denied = premain(\uBB38\uC790\uC5F4)\uC5D0 \uB300\uD55C \uC561\uC138\uC2A4\uAC00 \uAC70\uBD80\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
+agent.err.invalid.agentclass = com.sun.management.agent.class \uC18D\uC131 \uAC12\uC774 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4.
+agent.err.invalid.state = \uBD80\uC801\uD569\uD55C \uC5D0\uC774\uC804\uD2B8 \uC0C1\uD0DC: {0}
+agent.err.invalid.jmxremote.port = com.sun.management.jmxremote.port \uBC88\uD638\uAC00 \uBD80\uC801\uD569\uD569\uB2C8\uB2E4.
+agent.err.invalid.jmxremote.rmi.port = \uBD80\uC801\uD569\uD55C com.sun.management.jmxremote.rmi.port \uBC88\uD638
+
+agent.err.file.not.set = \uD30C\uC77C\uC774 \uC9C0\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
+agent.err.file.not.readable = \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
+agent.err.file.read.failed = \uD30C\uC77C \uC77D\uAE30\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.
+agent.err.file.not.found = \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
+agent.err.file.access.not.restricted = \uD30C\uC77C \uC77D\uAE30 \uC561\uC138\uC2A4\uB294 \uC81C\uD55C\uB418\uC5B4\uC57C \uD569\uB2C8\uB2E4.
+
+agent.err.password.file.notset = \uBE44\uBC00\uBC88\uD638 \uD30C\uC77C\uC774 \uC9C0\uC815\uB418\uC9C0 \uC54A\uC558\uC9C0\uB9CC com.sun.management.jmxremote.authenticate=true\uC785\uB2C8\uB2E4.
+agent.err.password.file.not.readable = \uBE44\uBC00\uBC88\uD638 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
+agent.err.password.file.read.failed = \uBE44\uBC00\uBC88\uD638 \uD30C\uC77C \uC77D\uAE30\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.
+agent.err.password.file.notfound = \uBE44\uBC00\uBC88\uD638 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
+agent.err.password.file.access.notrestricted = \uBE44\uBC00\uBC88\uD638 \uD30C\uC77C \uC77D\uAE30 \uC561\uC138\uC2A4\uB294 \uC81C\uD55C\uB418\uC5B4\uC57C \uD569\uB2C8\uB2E4.
+
+agent.err.access.file.notset = \uC561\uC138\uC2A4 \uD30C\uC77C\uC774 \uC9C0\uC815\uB418\uC9C0 \uC54A\uC558\uC9C0\uB9CC com.sun.management.jmxremote.authenticate=true\uC785\uB2C8\uB2E4.
+agent.err.access.file.not.readable = \uC561\uC138\uC2A4 \uD30C\uC77C\uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
+agent.err.access.file.read.failed = \uC561\uC138\uC2A4 \uD30C\uC77C \uC77D\uAE30\uB97C \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.
+agent.err.access.file.notfound = \uC561\uC138\uC2A4 \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
+
+agent.err.connector.server.io.error = JMX \uCEE4\uB125\uD130 \uC11C\uBC84 \uD1B5\uC2E0 \uC624\uB958
+
+agent.err.invalid.option = \uBD80\uC801\uD569\uD55C \uC635\uC158\uC774 \uC9C0\uC815\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
+
+jmxremote.ConnectorBootstrap.starting = JMX \uCEE4\uB125\uD130 \uC11C\uBC84\uB97C \uC2DC\uC791\uD558\uB294 \uC911:
+jmxremote.ConnectorBootstrap.noAuthentication = \uC778\uC99D \uC5C6\uC74C
+jmxremote.ConnectorBootstrap.ready = {0}\uC5D0\uC11C JMX \uCEE4\uB125\uD130\uAC00 \uC900\uBE44\uB418\uC5C8\uC2B5\uB2C8\uB2E4.
+jmxremote.ConnectorBootstrap.password.readonly = \uBE44\uBC00\uBC88\uD638 \uD30C\uC77C \uC77D\uAE30 \uC561\uC138\uC2A4\uB294 \uC81C\uD55C\uB418\uC5B4\uC57C \uD568: {0}
+jmxremote.ConnectorBootstrap.file.readonly = \uD30C\uC77C \uC77D\uAE30 \uC561\uC138\uC2A4\uB294 \uC81C\uD55C\uB418\uC5B4\uC57C \uD568: {0}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/resources/agent_pt_BR.properties Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,71 @@
+#
+# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+agent.err.error = Erro
+agent.err.exception = Exce\u00E7\u00E3o gerada pelo agente
+agent.err.warning = Advert\u00EAncia
+
+agent.err.configfile.notfound = Arquivo de configura\u00E7\u00E3o n\u00E3o encontrado
+agent.err.configfile.failed = Falha ao ler o arquivo de configura\u00E7\u00E3o
+agent.err.configfile.closed.failed = Falha ao fechar o arquivo de configura\u00E7\u00E3o
+agent.err.configfile.access.denied = Acesso negado ao arquivo de configura\u00E7\u00E3o
+
+agent.err.exportaddress.failed = Falha na exporta\u00E7\u00E3o do endere\u00E7o do conector JMX para o buffer de instrumenta\u00E7\u00E3o
+
+agent.err.agentclass.notfound = Classe do agente de gerenciamento n\u00E3o encontrada
+agent.err.agentclass.failed = Falha na classe do agente de gerenciamento
+agent.err.premain.notfound = premain(String) n\u00E3o existe na classe do agente
+agent.err.agentclass.access.denied = Acesso negado a premain(String)
+agent.err.invalid.agentclass = Valor inv\u00E1lido da propriedade com.sun.management.agent.class
+agent.err.invalid.state = Estado inv\u00E1lido do agente: {0}
+agent.err.invalid.jmxremote.port = N\u00FAmero inv\u00E1lido de com.sun.management.jmxremote.port
+agent.err.invalid.jmxremote.rmi.port = N\u00FAmero inv\u00E1lido do com.sun.management.jmxremote.rmi.port
+
+agent.err.file.not.set = Arquivo n\u00E3o especificado
+agent.err.file.not.readable = Arquivo ileg\u00EDvel
+agent.err.file.read.failed = Falha ao ler o arquivo
+agent.err.file.not.found = Arquivo n\u00E3o encontrado
+agent.err.file.access.not.restricted = O acesso de leitura do arquivo deve ser limitado
+
+agent.err.password.file.notset = O arquivo de senha n\u00E3o est\u00E1 especificado, mas com.sun.management.jmxremote.authenticate=true
+agent.err.password.file.not.readable = Arquivo de senha ileg\u00EDvel
+agent.err.password.file.read.failed = Falha ao ler o arquivo de senha
+agent.err.password.file.notfound = Arquivo de senha n\u00E3o encontrado
+agent.err.password.file.access.notrestricted = O acesso de leitura do arquivo de senha deve ser limitado
+
+agent.err.access.file.notset = O arquivo de acesso n\u00E3o est\u00E1 especificado, mas com.sun.management.jmxremote.authenticate=true
+agent.err.access.file.not.readable = Arquivo de acesso ileg\u00EDvel
+agent.err.access.file.read.failed = Falha ao ler o arquivo de acesso
+agent.err.access.file.notfound = Arquivo de acesso n\u00E3o encontrado
+
+agent.err.connector.server.io.error = Erro de comunica\u00E7\u00E3o do servidor do conector JMX
+
+agent.err.invalid.option = Op\u00E7\u00E3o especificada inv\u00E1lida
+
+jmxremote.ConnectorBootstrap.starting = Iniciando o Servidor do Conector JMX:
+jmxremote.ConnectorBootstrap.noAuthentication = Sem autentica\u00E7\u00E3o
+jmxremote.ConnectorBootstrap.ready = Conector JMX pronto em: {0}
+jmxremote.ConnectorBootstrap.password.readonly = O acesso de leitura do arquivo de senha deve ser limitado: {0}
+jmxremote.ConnectorBootstrap.file.readonly = O acesso de leitura do arquivo deve ser limitado: {0}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/resources/agent_sv.properties Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,71 @@
+#
+# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+agent.err.error = Fel
+agent.err.exception = Agenten orsakade ett undantag
+agent.err.warning = Varning
+
+agent.err.configfile.notfound = Konfigurationsfilen hittades inte
+agent.err.configfile.failed = Kunde inte l\u00E4sa konfigurationsfilen
+agent.err.configfile.closed.failed = Kunde inte st\u00E4nga konfigurationsfilen
+agent.err.configfile.access.denied = \u00C5tkomst till konfigurationsfilen nekad
+
+agent.err.exportaddress.failed = Kunde inte exportera JMX-anslutningsadressen till instrumentbufferten
+
+agent.err.agentclass.notfound = Administrationsagentklassen hittades inte
+agent.err.agentclass.failed = Administrationsagentklassen utf\u00F6rdes inte
+agent.err.premain.notfound = premain(String) finns inte i agentklassen
+agent.err.agentclass.access.denied = \u00C5tkomst till premain(String) nekad
+agent.err.invalid.agentclass = Ogiltigt egenskapsv\u00E4rde f\u00F6r com.sun.management.agent.class
+agent.err.invalid.state = Ogiltig agentstatus: {0}
+agent.err.invalid.jmxremote.port = Ogiltigt com.sun.management.jmxremote.port-nummer
+agent.err.invalid.jmxremote.rmi.port = Ogiltigt com.sun.management.jmxremote.rmi.port-nummer
+
+agent.err.file.not.set = Filen \u00E4r inte angiven
+agent.err.file.not.readable = Filen \u00E4r inte l\u00E4sbar
+agent.err.file.read.failed = Kunde inte l\u00E4sa filen
+agent.err.file.not.found = Filen hittades inte
+agent.err.file.access.not.restricted = Fill\u00E4snings\u00E5tkomst m\u00E5ste begr\u00E4nsas
+
+agent.err.password.file.notset = L\u00F6senordsfilen har inte angetts men com.sun.management.jmxremote.authenticate=true
+agent.err.password.file.not.readable = L\u00F6senordsfilen \u00E4r inte l\u00E4sbar
+agent.err.password.file.read.failed = Kunde inte l\u00E4sa l\u00F6senordsfilen
+agent.err.password.file.notfound = Hittar inte l\u00F6senordsfilen
+agent.err.password.file.access.notrestricted = L\u00E4sbeh\u00F6righeten f\u00F6r filen m\u00E5ste begr\u00E4nsas
+
+agent.err.access.file.notset = \u00C5tkomstfilen har inte angetts men com.sun.management.jmxremote.authenticate=true
+agent.err.access.file.not.readable = Access-filen \u00E4r inte l\u00E4sbar
+agent.err.access.file.read.failed = Kunde inte l\u00E4sa \u00E5tkomstfilen
+agent.err.access.file.notfound = Access-filen hittades inte
+
+agent.err.connector.server.io.error = Serverkommunikationsfel f\u00F6r JMX-anslutning
+
+agent.err.invalid.option = Det angivna alternativet \u00E4r ogiltigt
+
+jmxremote.ConnectorBootstrap.starting = Startar server f\u00F6r JMX-anslutning:
+jmxremote.ConnectorBootstrap.noAuthentication = Ingen autentisering
+jmxremote.ConnectorBootstrap.ready = JMX-anslutning redo p\u00E5: {0}
+jmxremote.ConnectorBootstrap.password.readonly = L\u00E4sbeh\u00F6righeten f\u00F6r l\u00F6senordsfilen m\u00E5ste begr\u00E4nsas: {0}
+jmxremote.ConnectorBootstrap.file.readonly = Fill\u00E4snings\u00E5tkomst m\u00E5ste begr\u00E4nsas {0}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/resources/agent_zh_CN.properties Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,71 @@
+#
+# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+agent.err.error = \u9519\u8BEF
+agent.err.exception = \u4EE3\u7406\u629B\u51FA\u5F02\u5E38\u9519\u8BEF
+agent.err.warning = \u8B66\u544A
+
+agent.err.configfile.notfound = \u627E\u4E0D\u5230\u914D\u7F6E\u6587\u4EF6
+agent.err.configfile.failed = \u672A\u80FD\u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6
+agent.err.configfile.closed.failed = \u672A\u80FD\u5173\u95ED\u914D\u7F6E\u6587\u4EF6
+agent.err.configfile.access.denied = \u62D2\u7EDD\u8BBF\u95EE\u914D\u7F6E\u6587\u4EF6
+
+agent.err.exportaddress.failed = \u672A\u80FD\u5C06 JMX \u8FDE\u63A5\u5668\u5730\u5740\u5BFC\u51FA\u5230\u68C0\u6D4B\u7F13\u51B2\u533A
+
+agent.err.agentclass.notfound = \u627E\u4E0D\u5230\u7BA1\u7406\u4EE3\u7406\u7C7B
+agent.err.agentclass.failed = \u7BA1\u7406\u4EE3\u7406\u7C7B\u5931\u8D25
+agent.err.premain.notfound = \u4EE3\u7406\u7C7B\u4E2D\u4E0D\u5B58\u5728 premain(String)
+agent.err.agentclass.access.denied = \u62D2\u7EDD\u8BBF\u95EE premain(String)
+agent.err.invalid.agentclass = com.sun.management.agent.class \u5C5E\u6027\u503C\u65E0\u6548
+agent.err.invalid.state = \u65E0\u6548\u7684\u4EE3\u7406\u72B6\u6001: {0}
+agent.err.invalid.jmxremote.port = com.sun.management.jmxremote.port \u7F16\u53F7\u65E0\u6548
+agent.err.invalid.jmxremote.rmi.port = com.sun.management.jmxremote.rmi.port \u7F16\u53F7\u65E0\u6548
+
+agent.err.file.not.set = \u672A\u6307\u5B9A\u6587\u4EF6
+agent.err.file.not.readable = \u6587\u4EF6\u4E0D\u53EF\u8BFB\u53D6
+agent.err.file.read.failed = \u672A\u80FD\u8BFB\u53D6\u6587\u4EF6
+agent.err.file.not.found = \u627E\u4E0D\u5230\u6587\u4EF6
+agent.err.file.access.not.restricted = \u5FC5\u987B\u9650\u5236\u6587\u4EF6\u8BFB\u53D6\u8BBF\u95EE\u6743\u9650
+
+agent.err.password.file.notset = \u672A\u6307\u5B9A\u53E3\u4EE4\u6587\u4EF6, \u4F46 com.sun.management.jmxremote.authenticate=true
+agent.err.password.file.not.readable = \u53E3\u4EE4\u6587\u4EF6\u4E0D\u53EF\u8BFB\u53D6
+agent.err.password.file.read.failed = \u8BFB\u53D6\u53E3\u4EE4\u6587\u4EF6\u5931\u8D25
+agent.err.password.file.notfound = \u627E\u4E0D\u5230\u53E3\u4EE4\u6587\u4EF6
+agent.err.password.file.access.notrestricted = \u5FC5\u987B\u9650\u5236\u53E3\u4EE4\u6587\u4EF6\u8BFB\u53D6\u8BBF\u95EE\u6743\u9650
+
+agent.err.access.file.notset = \u672A\u6307\u5B9A\u8BBF\u95EE\u6587\u4EF6, \u4F46 com.sun.management.jmxremote.authenticate=true
+agent.err.access.file.not.readable = \u8BBF\u95EE\u6587\u4EF6\u4E0D\u53EF\u8BFB\u53D6
+agent.err.access.file.read.failed = \u8BFB\u53D6\u8BBF\u95EE\u6587\u4EF6\u5931\u8D25
+agent.err.access.file.notfound = \u627E\u4E0D\u5230\u8BBF\u95EE\u6587\u4EF6
+
+agent.err.connector.server.io.error = JMX \u8FDE\u63A5\u5668\u670D\u52A1\u5668\u901A\u4FE1\u9519\u8BEF
+
+agent.err.invalid.option = \u6307\u5B9A\u7684\u9009\u9879\u65E0\u6548
+
+jmxremote.ConnectorBootstrap.starting = \u6B63\u5728\u542F\u52A8 JMX \u8FDE\u63A5\u5668\u670D\u52A1\u5668:
+jmxremote.ConnectorBootstrap.noAuthentication = \u65E0\u9A8C\u8BC1
+jmxremote.ConnectorBootstrap.ready = \u4F4D\u4E8E{0}\u7684 JMX \u8FDE\u63A5\u5668\u5DF2\u5C31\u7EEA
+jmxremote.ConnectorBootstrap.password.readonly = \u5FC5\u987B\u9650\u5236\u53E3\u4EE4\u6587\u4EF6\u8BFB\u53D6\u8BBF\u95EE\u6743\u9650: {0}
+jmxremote.ConnectorBootstrap.file.readonly = \u5FC5\u987B\u9650\u5236\u6587\u4EF6\u8BFB\u53D6\u8BBF\u95EE\u6743\u9650: {0}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/resources/agent_zh_TW.properties Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,71 @@
+#
+# Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation. Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+agent.err.error = \u932F\u8AA4
+agent.err.exception = \u4EE3\u7406\u7A0B\u5F0F\u767C\u751F\u7570\u5E38
+agent.err.warning = \u8B66\u544A
+
+agent.err.configfile.notfound = \u627E\u4E0D\u5230\u8A2D\u5B9A\u6A94\u6848
+agent.err.configfile.failed = \u7121\u6CD5\u8B80\u53D6\u8A2D\u5B9A\u6A94\u6848
+agent.err.configfile.closed.failed = \u7121\u6CD5\u95DC\u9589\u8A2D\u5B9A\u6A94\u6848
+agent.err.configfile.access.denied = \u5B58\u53D6\u8A2D\u5B9A\u6A94\u6848\u906D\u5230\u62D2\u7D55
+
+agent.err.exportaddress.failed = \u5C07 JMX \u9023\u63A5\u5668\u4F4D\u5740\u532F\u51FA\u81F3\u8A2D\u5099\u7DE9\u885D\u5340\u5931\u6557
+
+agent.err.agentclass.notfound = \u627E\u4E0D\u5230\u7BA1\u7406\u4EE3\u7406\u7A0B\u5F0F\u985E\u5225
+agent.err.agentclass.failed = \u7BA1\u7406\u4EE3\u7406\u7A0B\u5F0F\u985E\u5225\u5931\u6557
+agent.err.premain.notfound = \u4EE3\u7406\u7A0B\u5F0F\u985E\u5225\u4E2D\u4E0D\u5B58\u5728 premain(String)
+agent.err.agentclass.access.denied = \u5B58\u53D6 premain(String) \u906D\u5230\u62D2\u7D55
+agent.err.invalid.agentclass = com.sun.management.agent.class \u5C6C\u6027\u503C\u7121\u6548
+agent.err.invalid.state = \u7121\u6548\u7684\u4EE3\u7406\u7A0B\u5F0F\u72C0\u614B: {0}
+agent.err.invalid.jmxremote.port = com.sun.management.jmxremote.port \u865F\u78BC\u7121\u6548
+agent.err.invalid.jmxremote.rmi.port = com.sun.management.jmxremote.rmi.port \u865F\u78BC\u7121\u6548
+
+agent.err.file.not.set = \u672A\u6307\u5B9A\u6A94\u6848
+agent.err.file.not.readable = \u6A94\u6848\u7121\u6CD5\u8B80\u53D6
+agent.err.file.read.failed = \u7121\u6CD5\u8B80\u53D6\u6A94\u6848
+agent.err.file.not.found = \u627E\u4E0D\u5230\u6A94\u6848
+agent.err.file.access.not.restricted = \u5FC5\u9808\u9650\u5236\u6A94\u6848\u8B80\u53D6\u5B58\u53D6\u6B0A
+
+agent.err.password.file.notset = \u672A\u6307\u5B9A\u5BC6\u78BC\u6A94\u6848\uFF0C\u4F46 com.sun.management.jmxremote.authenticate=true
+agent.err.password.file.not.readable = \u5BC6\u78BC\u6A94\u6848\u7121\u6CD5\u8B80\u53D6
+agent.err.password.file.read.failed = \u7121\u6CD5\u8B80\u53D6\u5BC6\u78BC\u6A94\u6848
+agent.err.password.file.notfound = \u627E\u4E0D\u5230\u5BC6\u78BC\u6A94\u6848
+agent.err.password.file.access.notrestricted = \u5FC5\u9808\u9650\u5236\u5BC6\u78BC\u6A94\u6848\u8B80\u53D6\u5B58\u53D6
+
+agent.err.access.file.notset = \u672A\u6307\u5B9A\u5B58\u53D6\u6A94\u6848\uFF0C\u4F46 com.sun.management.jmxremote.authenticate=true
+agent.err.access.file.not.readable = \u5B58\u53D6\u6A94\u6848\u7121\u6CD5\u8B80\u53D6
+agent.err.access.file.read.failed = \u7121\u6CD5\u8B80\u53D6\u5B58\u53D6\u6A94\u6848
+agent.err.access.file.notfound = \u627E\u4E0D\u5230\u5B58\u53D6\u6A94\u6848
+
+agent.err.connector.server.io.error = JMX \u9023\u63A5\u5668\u4F3A\u670D\u5668\u901A\u8A0A\u932F\u8AA4
+
+agent.err.invalid.option = \u6307\u5B9A\u7684\u9078\u9805\u7121\u6548
+
+jmxremote.ConnectorBootstrap.starting = \u6B63\u5728\u555F\u52D5 JMX \u9023\u63A5\u5668\u4F3A\u670D\u5668:
+jmxremote.ConnectorBootstrap.noAuthentication = \u7121\u8A8D\u8B49
+jmxremote.ConnectorBootstrap.ready = JMX \u9023\u63A5\u5668\u5C31\u7DD2\uFF0C\u4F4D\u65BC: {0}
+jmxremote.ConnectorBootstrap.password.readonly = \u5FC5\u9808\u9650\u5236\u5BC6\u78BC\u6A94\u6848\u8B80\u53D6\u5B58\u53D6: {0}
+jmxremote.ConnectorBootstrap.file.readonly = \u5FC5\u9808\u9650\u5236\u6A94\u6848\u8B80\u53D6\u5B58\u53D6\u6B0A: {0}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/jdk/internal/agent/spi/AgentProvider.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.internal.agent.spi;
+
+import java.util.Properties;
+
+/**
+ * Service interface for management agent
+ */
+public abstract class AgentProvider {
+
+ /**
+ * Instantiates a new AgentProvider.
+ *
+ * @throws SecurityException if the subclass (and calling code) does not
+ * have
+ * {@code RuntimePermission("sun.management.spi.AgentProvider.subclass")}
+ */
+ protected AgentProvider() {
+ this(checkSubclassPermission());
+ }
+
+ private AgentProvider(Void unused) {
+ }
+
+ private static Void checkSubclassPermission() {
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new RuntimePermission(AgentProvider.class.getName() + ".subclass"));
+ }
+ return null;
+ }
+
+ /**
+ * Gets the name of the agent provider.
+ *
+ * @return name of agent provider
+ */
+ public abstract String getName();
+
+ /**
+ * Initializes and starts the agent.
+ *
+ * @throws IllegalStateException if this agent has already been started.
+ */
+ public abstract void startAgent();
+
+ /**
+ * Initializes and starts the agent at given port and with given properties
+ *
+ * @param props environment variables for agent
+ *
+ * @throws IllegalStateException if this agent has already been started.
+ */
+ public abstract void startAgent(Properties props);
+
+ /**
+ * Checks if agent is started and not terminated.
+ *
+ * @return true if agent is running, false otherwise.
+ */
+ public abstract boolean isActive();
+
+ /**
+ * Stops this agent.
+ *
+ * @throws IllegalStateException if this agent is not started.
+ */
+ public abstract void stopAgent();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/module-info.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+module jdk.management.agent {
+ requires java.management;
+ requires java.management.rmi;
+
+ exports jdk.internal.agent to jdk.jconsole;
+
+ uses jdk.internal.agent.spi.AgentProvider;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/sun/management/jdp/JdpBroadcaster.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.management.jdp;
+
+import java.io.IOException;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.NetworkInterface;
+import java.net.ProtocolFamily;
+import java.net.StandardProtocolFamily;
+import java.net.StandardSocketOptions;
+import java.nio.ByteBuffer;
+import java.nio.channels.DatagramChannel;
+import java.nio.channels.UnsupportedAddressTypeException;
+import java.util.Enumeration;
+
+/**
+ * JdpBroadcaster is responsible for sending pre-built JDP packet across a Net
+ *
+ * <p> Multicast group address, port number and ttl have to be chosen on upper
+ * level and passed to broadcaster constructor. Also it's possible to specify
+ * source address to broadcast from. </p>
+ *
+ * <p>JdpBradcaster doesn't perform any validation on a supplied {@code port} and {@code ttl} because
+ * the allowed values depend on an operating system setup</p>
+ *
+ */
+public final class JdpBroadcaster {
+
+ private final InetAddress addr;
+ private final int port;
+ private final DatagramChannel channel;
+
+ /**
+ * Create a new broadcaster
+ *
+ * @param address - multicast group address
+ * @param srcAddress - address of interface we should use to broadcast.
+ * @param port - udp port to use
+ * @param ttl - packet ttl
+ * @throws IOException
+ */
+ public JdpBroadcaster(InetAddress address, InetAddress srcAddress, int port, int ttl)
+ throws IOException, JdpException {
+ this.addr = address;
+ this.port = port;
+
+ ProtocolFamily family = (address instanceof Inet6Address)
+ ? StandardProtocolFamily.INET6 : StandardProtocolFamily.INET;
+
+ channel = DatagramChannel.open(family);
+ channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
+ channel.setOption(StandardSocketOptions.IP_MULTICAST_TTL, ttl);
+
+ // with srcAddress equal to null, this constructor do exactly the same as
+ // if srcAddress is not passed
+ if (srcAddress != null) {
+ // User requests particular interface to bind to
+ NetworkInterface interf = NetworkInterface.getByInetAddress(srcAddress);
+
+ if (interf == null) {
+ throw new JdpException("Unable to get network interface for " + srcAddress.toString());
+ }
+
+ if (!interf.isUp()) {
+ throw new JdpException(interf.getName() + " is not up.");
+ }
+
+ if (!interf.supportsMulticast()) {
+ throw new JdpException(interf.getName() + " does not support multicast.");
+ }
+
+ try {
+ channel.bind(new InetSocketAddress(srcAddress, 0));
+ } catch (UnsupportedAddressTypeException ex) {
+ throw new JdpException("Unable to bind to source address");
+ }
+ channel.setOption(StandardSocketOptions.IP_MULTICAST_IF, interf);
+ }
+ }
+
+ /**
+ * Create a new broadcaster
+ *
+ * @param address - multicast group address
+ * @param port - udp port to use
+ * @param ttl - packet ttl
+ * @throws IOException
+ */
+ public JdpBroadcaster(InetAddress address, int port, int ttl)
+ throws IOException, JdpException {
+ this(address, null, port, ttl);
+ }
+
+ /**
+ * Broadcast pre-built packet
+ *
+ * @param packet - instance of JdpPacket
+ * @throws IOException
+ */
+ public void sendPacket(JdpPacket packet)
+ throws IOException {
+ byte[] data = packet.getPacketData();
+ // Unlike allocate/put wrap don't need a flip afterward
+ ByteBuffer b = ByteBuffer.wrap(data);
+ channel.send(b, new InetSocketAddress(addr, port));
+ }
+
+ /**
+ * Shutdown broadcaster and close underlying socket channel
+ *
+ * @throws IOException
+ */
+ public void shutdown() throws IOException {
+ channel.close();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/sun/management/jdp/JdpController.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.management.jdp;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.UUID;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import sun.management.VMManagement;
+
+/**
+ * JdpController is responsible to create and manage a broadcast loop.
+ *
+ * <p> Other part of code has no access to broadcast loop and have to use
+ * provided static methods
+ * {@link #startDiscoveryService(InetAddress,int,String,String) startDiscoveryService}
+ * and {@link #stopDiscoveryService() stopDiscoveryService}
+ * <p>{@link #startDiscoveryService(InetAddress,int,String,String) startDiscoveryService} could be called multiple
+ * times as it stops the running service if it is necessary.
+ * Call to {@link #stopDiscoveryService() stopDiscoveryService}
+ * ignored if service isn't run.
+ *
+ *
+ * <p> System properties below could be used to control broadcast loop behavior.
+ * Property below have to be set explicitly in command line. It's not possible to
+ * set it in management.config file. Careless changes of these properties could
+ * lead to security or network issues.
+ * <ul>
+ * <li>com.sun.management.jdp.ttl - set ttl for broadcast packet</li>
+ * <li>com.sun.management.jdp.pause - set broadcast interval in seconds</li>
+ * <li>com.sun.management.jdp.source_addr - an address of interface to use for broadcast</li>
+ * </ul>
+ *
+ * <p>null parameters values are filtered out on {@link JdpPacketWriter} level and
+ * corresponding keys are not placed to packet.
+ */
+public final class JdpController {
+
+ private static class JDPControllerRunner implements Runnable {
+
+ private final JdpJmxPacket packet;
+ private final JdpBroadcaster bcast;
+ private final int pause;
+ private volatile boolean shutdown = false;
+
+ private JDPControllerRunner(JdpBroadcaster bcast, JdpJmxPacket packet, int pause) {
+ this.bcast = bcast;
+ this.packet = packet;
+ this.pause = pause;
+ }
+
+ @Override
+ public void run() {
+ try {
+ while (!shutdown) {
+ bcast.sendPacket(packet);
+ try {
+ Thread.sleep(this.pause);
+ } catch (InterruptedException e) {
+ // pass
+ }
+ }
+
+ } catch (IOException e) {
+ // pass;
+ }
+
+ // It's not possible to re-use controller,
+ // nevertheless reset shutdown variable
+ try {
+ stop();
+ bcast.shutdown();
+ } catch (IOException ex) {
+ // pass - ignore IOException during shutdown
+ }
+ }
+
+ public void stop() {
+ shutdown = true;
+ }
+ }
+ private static JDPControllerRunner controller = null;
+
+ private JdpController(){
+ // Don't allow to instantiate this class.
+ }
+
+ // Utility to handle optional system properties
+ // Parse an integer from string or return default if provided string is null
+ private static int getInteger(String val, int dflt, String msg) throws JdpException {
+ try {
+ return (val == null) ? dflt : Integer.parseInt(val);
+ } catch (NumberFormatException ex) {
+ throw new JdpException(msg);
+ }
+ }
+
+ // Parse an inet address from string or return default if provided string is null
+ private static InetAddress getInetAddress(String val, InetAddress dflt, String msg) throws JdpException {
+ try {
+ return (val == null) ? dflt : InetAddress.getByName(val);
+ } catch (UnknownHostException ex) {
+ throw new JdpException(msg);
+ }
+ }
+
+ // Get the process id of the current running Java process
+ private static Integer getProcessId() {
+ try {
+ // Get the current process id using a reflection hack
+ RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
+ Field jvm = runtime.getClass().getDeclaredField("jvm");
+ jvm.setAccessible(true);
+
+ VMManagement mgmt = (sun.management.VMManagement) jvm.get(runtime);
+ Method pid_method = mgmt.getClass().getDeclaredMethod("getProcessId");
+ pid_method.setAccessible(true);
+ Integer pid = (Integer) pid_method.invoke(mgmt);
+ return pid;
+ } catch(Exception ex) {
+ return null;
+ }
+ }
+
+
+ /**
+ * Starts discovery service
+ *
+ * @param address - multicast group address
+ * @param port - udp port to use
+ * @param instanceName - name of running JVM instance
+ * @param url - JMX service url
+ * @throws IOException
+ */
+ public static synchronized void startDiscoveryService(InetAddress address, int port, String instanceName, String url)
+ throws IOException, JdpException {
+
+ // Limit packet to local subnet by default
+ int ttl = getInteger(
+ System.getProperty("com.sun.management.jdp.ttl"), 1,
+ "Invalid jdp packet ttl");
+
+ // Broadcast once a 5 seconds by default
+ int pause = getInteger(
+ System.getProperty("com.sun.management.jdp.pause"), 5,
+ "Invalid jdp pause");
+
+ // Converting seconds to milliseconds
+ pause = pause * 1000;
+
+ // Allow OS to choose broadcast source
+ InetAddress sourceAddress = getInetAddress(
+ System.getProperty("com.sun.management.jdp.source_addr"), null,
+ "Invalid source address provided");
+
+ // Generate session id
+ UUID id = UUID.randomUUID();
+
+ JdpJmxPacket packet = new JdpJmxPacket(id, url);
+
+ // Don't broadcast whole command line for security reason.
+ // Strip everything after first space
+ String javaCommand = System.getProperty("sun.java.command");
+ if (javaCommand != null) {
+ String[] arr = javaCommand.split(" ", 2);
+ packet.setMainClass(arr[0]);
+ }
+
+ // Put optional explicit java instance name to packet, if user doesn't specify
+ // it the key is skipped. PacketWriter is responsible to skip keys having null value.
+ packet.setInstanceName(instanceName);
+
+ // Set rmi server hostname if it explicitly specified by user with
+ // java.rmi.server.hostname
+ String rmiHostname = System.getProperty("java.rmi.server.hostname");
+ packet.setRmiHostname(rmiHostname);
+
+ // Set broadcast interval
+ packet.setBroadcastInterval(Integer.toString(pause));
+
+ // Set process id
+ Integer pid = getProcessId();
+ if (pid != null) {
+ packet.setProcessId(pid.toString());
+ }
+
+ JdpBroadcaster bcast = new JdpBroadcaster(address, sourceAddress, port, ttl);
+
+ // Stop discovery service if it's already running
+ stopDiscoveryService();
+
+ controller = new JDPControllerRunner(bcast, packet, pause);
+
+ Thread t = new Thread(null, controller, "JDP broadcaster", 0, false);
+ t.setDaemon(true);
+ t.start();
+ }
+
+ /**
+ * Stop running discovery service,
+ * it's safe to attempt to stop not started service
+ */
+ public static synchronized void stopDiscoveryService() {
+ if ( controller != null ){
+ controller.stop();
+ controller = null;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/sun/management/jdp/JdpException.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.management.jdp;
+
+/**
+ * An Exception thrown if a JDP implementation encounters a problem.
+ */
+public final class JdpException extends Exception {
+
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Construct a new JDP exception with a meaningful message
+ *
+ * @param msg - message
+ */
+ public JdpException(String msg) {
+ super(msg);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/sun/management/jdp/JdpGenericPacket.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.management.jdp;
+
+/**
+ * JdpGenericPacket responsible to provide fields
+ * common for all Jdp packets
+ */
+public abstract class JdpGenericPacket implements JdpPacket {
+
+ /**
+ * JDP protocol magic. Magic allows a reader to quickly select
+ * JDP packets from a bunch of broadcast packets addressed to the same port
+ * and broadcast group. Any packet intended to be parsed by JDP client
+ * has to start from this magic.
+ */
+ private static final int MAGIC = 0xC0FFEE42;
+
+ /**
+ * Current version of protocol. Any implementation of this protocol has to
+ * conform with the packet structure and the flow described in JEP-168
+ */
+ private static final short PROTOCOL_VERSION = 1;
+
+ /**
+ * Default do-nothing constructor
+ */
+ protected JdpGenericPacket(){
+ // do nothing
+ }
+
+
+ /**
+ * Validate protocol header magic field
+ *
+ * @param magic - value to validate
+ * @throws JdpException
+ */
+ public static void checkMagic(int magic)
+ throws JdpException {
+ if (magic != MAGIC) {
+ throw new JdpException("Invalid JDP magic header: " + magic);
+ }
+ }
+
+ /**
+ * Validate protocol header version field
+ *
+ * @param version - value to validate
+ * @throws JdpException
+ */
+ public static void checkVersion(short version)
+ throws JdpException {
+
+ if (version > PROTOCOL_VERSION) {
+ throw new JdpException("Unsupported protocol version: " + version);
+ }
+ }
+
+ /**
+ *
+ * @return protocol magic
+ */
+ public static int getMagic() {
+ return MAGIC;
+ }
+
+ /**
+ *
+ * @return current protocol version
+ */
+ public static short getVersion() {
+ return PROTOCOL_VERSION;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/sun/management/jdp/JdpJmxPacket.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,245 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.management.jdp;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * A packet to broadcasts JMX URL
+ *
+ * Fields:
+ *
+ * <ul>
+ * <li>UUID - broadcast session ID, changed every time when we start/stop
+ * discovery service</li>
+ * <li>JMX_URL - URL to connect to JMX service</li>
+ * <li>MAIN_CLASS - optional name of main class, filled from sun.java.command stripped for
+ * security reason to first space</li>
+ * <li>INSTANCE_NAME - optional custom name of particular instance as provided by customer</li>
+ * </ul>
+ */
+public final class JdpJmxPacket
+ extends JdpGenericPacket
+ implements JdpPacket {
+
+ /**
+ * Session ID
+ */
+ public final static String UUID_KEY = "DISCOVERABLE_SESSION_UUID";
+ /**
+ * Name of main class
+ */
+ public final static String MAIN_CLASS_KEY = "MAIN_CLASS";
+ /**
+ * JMX service URL
+ */
+ public final static String JMX_SERVICE_URL_KEY = "JMX_SERVICE_URL";
+ /**
+ * Name of Java instance
+ */
+ public final static String INSTANCE_NAME_KEY = "INSTANCE_NAME";
+ /**
+ * PID of java process, optional presented if it could be obtained
+ */
+ public final static String PROCESS_ID_KEY = "PROCESS_ID";
+ /**
+ * Hostname of rmi server, optional presented if user overrides rmi server
+ * hostname by java.rmi.server.hostname property
+ */
+ public final static String RMI_HOSTNAME_KEY = "RMI_HOSTNAME";
+ /**
+ * Configured broadcast interval, optional
+ */
+ public final static String BROADCAST_INTERVAL_KEY = "BROADCAST_INTERVAL";
+
+ private UUID id;
+ private String mainClass;
+ private String jmxServiceUrl;
+ private String instanceName;
+ private String processId;
+ private String rmiHostname;
+ private String broadcastInterval;
+
+ /**
+ * Create new instance from user provided data. Set mandatory fields
+ *
+ * @param id - java instance id
+ * @param jmxServiceUrl - JMX service url
+ */
+ public JdpJmxPacket(UUID id, String jmxServiceUrl) {
+ this.id = id;
+ this.jmxServiceUrl = jmxServiceUrl;
+ }
+
+ /**
+ * Create new instance from network data Parse packet and set fields.
+ *
+ * @param data - raw packet data as it came from a Net
+ * @throws JdpException
+ */
+ public JdpJmxPacket(byte[] data)
+ throws JdpException {
+ JdpPacketReader reader;
+
+ reader = new JdpPacketReader(data);
+ Map<String, String> p = reader.getDiscoveryDataAsMap();
+
+ String sId = p.get(UUID_KEY);
+ this.id = (sId == null) ? null : UUID.fromString(sId);
+ this.jmxServiceUrl = p.get(JMX_SERVICE_URL_KEY);
+ this.mainClass = p.get(MAIN_CLASS_KEY);
+ this.instanceName = p.get(INSTANCE_NAME_KEY);
+ this.processId = p.get(PROCESS_ID_KEY);
+ this.rmiHostname = p.get(RMI_HOSTNAME_KEY);
+ this.broadcastInterval = p.get(BROADCAST_INTERVAL_KEY);
+ }
+
+ /**
+ * Set main class field
+ *
+ * @param mainClass - main class of running app
+ */
+ public void setMainClass(String mainClass) {
+ this.mainClass = mainClass;
+ }
+
+ /**
+ * Set instance name field
+ *
+ * @param instanceName - name of instance as provided by customer
+ */
+ public void setInstanceName(String instanceName) {
+ this.instanceName = instanceName;
+ }
+
+ /**
+ * @return id of discovery session
+ */
+ public UUID getId() {
+ return id;
+ }
+
+ /**
+ *
+ * @return main class field
+ */
+ public String getMainClass() {
+ return mainClass;
+ }
+
+ /**
+ *
+ * @return JMX service URL
+ */
+ public String getJmxServiceUrl() {
+ return jmxServiceUrl;
+ }
+
+ /**
+ *
+ * @return instance name
+ */
+ public String getInstanceName() {
+ return instanceName;
+ }
+
+ public String getProcessId() {
+ return processId;
+ }
+
+ public void setProcessId(String processId) {
+ this.processId = processId;
+ }
+
+ public String getRmiHostname() {
+ return rmiHostname;
+ }
+
+ public void setRmiHostname(String rmiHostname) {
+ this.rmiHostname = rmiHostname;
+ }
+
+ public String getBroadcastInterval() {
+ return broadcastInterval;
+ }
+
+ public void setBroadcastInterval(String broadcastInterval) {
+ this.broadcastInterval = broadcastInterval;
+ }
+
+ /**
+ *
+ * @return assembled packet ready to be sent across a Net
+ * @throws IOException
+ */
+ @Override
+ public byte[] getPacketData() throws IOException {
+ // Assemble packet from fields to byte array
+ JdpPacketWriter writer;
+ writer = new JdpPacketWriter();
+ writer.addEntry(UUID_KEY, (id == null) ? null : id.toString());
+ writer.addEntry(MAIN_CLASS_KEY, mainClass);
+ writer.addEntry(JMX_SERVICE_URL_KEY, jmxServiceUrl);
+ writer.addEntry(INSTANCE_NAME_KEY, instanceName);
+ writer.addEntry(PROCESS_ID_KEY, processId);
+ writer.addEntry(RMI_HOSTNAME_KEY, rmiHostname);
+ writer.addEntry(BROADCAST_INTERVAL_KEY, broadcastInterval);
+
+ return writer.getPacketBytes();
+ }
+
+ /**
+ *
+ * @return packet hash code
+ */
+ @Override
+ public int hashCode() {
+ int hash = 1;
+ hash = hash * 31 + id.hashCode();
+ hash = hash * 31 + jmxServiceUrl.hashCode();
+ return hash;
+ }
+
+ /**
+ * Compare two packets
+ *
+ * @param o - packet to compare
+ * @return either packet equals or not
+ */
+ @Override
+ public boolean equals(Object o) {
+
+ if (o == null || ! (o instanceof JdpJmxPacket) ){
+ return false;
+ }
+
+ JdpJmxPacket p = (JdpJmxPacket) o;
+ return Objects.equals(id, p.getId()) && Objects.equals(jmxServiceUrl, p.getJmxServiceUrl());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/sun/management/jdp/JdpPacket.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.management.jdp;
+
+import java.io.IOException;
+
+/**
+ * Packet to broadcast
+ *
+ * <p>Each packet have to contain MAGIC and PROTOCOL_VERSION in order to be
+ * recognized as a valid JDP packet.</p>
+ *
+ * <p>Default implementation build packet as a set of UTF-8 encoded Key/Value pairs
+ * are stored as an ordered list of values, and are sent to the server
+ * in that order.</p>
+ *
+ * <p>
+ * Packet structure:
+ *
+ * 4 bytes JDP magic (0xC0FFE42)
+ * 2 bytes JDP protocol version (01)
+ *
+ * 2 bytes size of key
+ * x bytes key (UTF-8 encoded)
+ * 2 bytes size of value
+ * x bytes value (UTF-8 encoded)
+ *
+ * repeat as many times as necessary ...
+ * </p>
+ */
+public interface JdpPacket {
+
+ /**
+ * This method responsible to assemble packet and return a byte array
+ * ready to be sent across a Net.
+ *
+ * @return assembled packet as an array of bytes
+ * @throws IOException
+ */
+ public byte[] getPacketData() throws IOException;
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/sun/management/jdp/JdpPacketReader.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.management.jdp;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * JdpPacketReader responsible for reading a packet <p>This class gets a byte
+ * array as it came from a Net, validates it and breaks a part </p>
+ */
+public final class JdpPacketReader {
+
+ private final DataInputStream pkt;
+ private Map<String, String> pmap = null;
+
+ /**
+ * Create packet reader, extract and check magic and version
+ *
+ * @param packet - packet received from a Net
+ * @throws JdpException
+ */
+ public JdpPacketReader(byte[] packet)
+ throws JdpException {
+ ByteArrayInputStream bais = new ByteArrayInputStream(packet);
+ pkt = new DataInputStream(bais);
+
+ try {
+ int magic = pkt.readInt();
+ JdpGenericPacket.checkMagic(magic);
+ } catch (IOException e) {
+ throw new JdpException("Invalid JDP packet received, bad magic");
+ }
+
+ try {
+ short version = pkt.readShort();
+ JdpGenericPacket.checkVersion(version);
+ } catch (IOException e) {
+ throw new JdpException("Invalid JDP packet received, bad protocol version");
+ }
+ }
+
+ /**
+ * Get next entry from packet
+ *
+ * @return the entry
+ * @throws EOFException
+ * @throws JdpException
+ */
+ public String getEntry()
+ throws EOFException, JdpException {
+
+ try {
+ short len = pkt.readShort();
+ // Artificial setting the "len" field to Short.MAX_VALUE may cause a reader to allocate
+ // to much memory. Prevent this possible DOS attack.
+ if (len < 1 && len > pkt.available()) {
+ throw new JdpException("Broken JDP packet. Invalid entry length field.");
+ }
+
+ byte[] b = new byte[len];
+ if (pkt.read(b) != len) {
+ throw new JdpException("Broken JDP packet. Unable to read entry.");
+ }
+ return new String(b, "UTF-8");
+
+ } catch (EOFException e) {
+ throw e;
+ } catch (UnsupportedEncodingException ex) {
+ throw new JdpException("Broken JDP packet. Unable to decode entry.");
+ } catch (IOException e) {
+ throw new JdpException("Broken JDP packet. Unable to read entry.");
+ }
+
+
+ }
+
+ /**
+ * return packet content as a key/value map
+ *
+ * @return map containing packet entries pair of entries treated as
+ * key,value
+ * @throws IOException
+ * @throws JdpException
+ */
+ public Map<String, String> getDiscoveryDataAsMap()
+ throws JdpException {
+ // return cached map if possible
+ if (pmap != null) {
+ return pmap;
+ }
+
+ String key = null, value = null;
+
+ final Map<String, String> tmpMap = new HashMap<>();
+ try {
+ while (true) {
+ key = getEntry();
+ value = getEntry();
+ tmpMap.put(key, value);
+ }
+ } catch (EOFException e) {
+ // EOF reached on reading value, report broken packet
+ // otherwise ignore it.
+ if (value == null) {
+ throw new JdpException("Broken JDP packet. Key without value." + key);
+ }
+ }
+
+ pmap = Collections.unmodifiableMap(tmpMap);
+ return pmap;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/sun/management/jdp/JdpPacketWriter.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.management.jdp;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * JdpPacketWriter responsible for writing a packet
+ * <p>This class assembles a set of key/value pairs to valid JDP packet,
+ * ready to be sent across a Net</p>
+ */
+public final class JdpPacketWriter {
+
+ private final ByteArrayOutputStream baos;
+ private final DataOutputStream pkt;
+
+ /**
+ * Create a JDP packet, add mandatory magic and version headers
+ *
+ * @throws IOException
+ */
+ public JdpPacketWriter()
+ throws IOException {
+ baos = new ByteArrayOutputStream();
+ pkt = new DataOutputStream(baos);
+
+ pkt.writeInt(JdpGenericPacket.getMagic());
+ pkt.writeShort(JdpGenericPacket.getVersion());
+ }
+
+ /**
+ * Put string entry to packet
+ *
+ * @param entry - string to put (utf-8 encoded)
+ * @throws IOException
+ */
+ public void addEntry(String entry)
+ throws IOException {
+ /* DataOutputStream.writeUTF() do essentially
+ * the same as:
+ * pkt.writeShort(entry.getBytes("UTF-8").length);
+ * pkt.write(entry.getBytes("UTF-8"));
+ */
+ pkt.writeUTF(entry);
+ }
+
+ /**
+ * Put key/value pair to packet
+ *
+ * @param key - key to put (utf-8 encoded)
+ * @param val - value to put (utf-8 encoded)
+ * @throws IOException
+ */
+ public void addEntry(String key, String val)
+ throws IOException {
+ /* Silently skip key if value is null.
+ * We don't need to distinguish between key missing
+ * and key has no value cases
+ */
+ if (val != null) {
+ addEntry(key);
+ addEntry(val);
+ }
+ }
+
+ /**
+ * Return assembled packet as a byte array
+ *
+ * @return packet bytes
+ */
+ public byte[] getPacketBytes() {
+ return baos.toByteArray();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/sun/management/jdp/package-info.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+/**
+ * Summary
+ * -------
+ *
+ * Define a lightweight network protocol for discovering running and
+ * manageable Java processes within a network subnet.
+ *
+ *
+ * Description
+ * -----------
+ *
+ * The protocol is lightweight multicast based, and works like a beacon,
+ * broadcasting the JMXService URL needed to connect to the external JMX
+ * agent if an application is started with appropriate parameters.
+ *
+ * The payload is structured like this:
+ *
+ * 4 bytes JDP magic (0xC0FFEE42)
+ * 2 bytes JDP protocol version (1)
+ * 2 bytes size of the next entry
+ * x bytes next entry (UTF-8 encoded)
+ * 2 bytes size of next entry
+ * ... Rinse and repeat...
+ *
+ * The payload will be parsed as even entries being keys, odd entries being
+ * values.
+ *
+ * The standard JDP packet contains four entries:
+ *
+ * - `DISCOVERABLE_SESSION_UUID` -- Unique id of the instance; this id changes every time
+ * the discovery protocol starts and stops
+ *
+ * - `MAIN_CLASS` -- The value of the `sun.java.command` property
+ *
+ * - `JMX_SERVICE_URL` -- The URL to connect to the JMX agent
+ *
+ * - `INSTANCE_NAME` -- The user-provided name of the running instance
+ *
+ * The protocol sends packets to 224.0.23.178:7095 by default.
+ *
+ * The protocol uses system properties to control it's behaviour:
+ * - `com.sun.management.jdp.port` -- override default port
+ *
+ * - `com.sun.management.jdp.address` -- override default address
+ *
+ * - `com.sun.management.jmxremote.autodiscovery` -- whether we should start autodiscovery or
+ * not. Autodiscovery starts if and only if following conditions are met: (autodiscovery is
+ * true OR (autodiscovery is not set AND jdp.port is set))
+ *
+ * - `com.sun.management.jdp.ttl` -- set ttl for broadcast packet, default is 1
+ * - `com.sun.management.jdp.pause` -- set broadcast interval in seconds default is 5
+ * - `com.sun.management.jdp.source_addr` -- an address of interface to use for broadcast
+ */
+
+package sun.management.jdp;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/sun/management/jmxremote/ConnectorBootstrap.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,1027 @@
+/*
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.management.jmxremote;
+
+import java.lang.System.Logger;
+import java.lang.System.Logger.Level;
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Serializable;
+import java.lang.management.ManagementFactory;
+import java.net.InetAddress;
+import java.net.MalformedURLException;
+import java.net.Socket;
+import java.net.ServerSocket;
+import java.net.UnknownHostException;
+import java.rmi.NoSuchObjectException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.registry.Registry;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+import java.rmi.server.RMISocketFactory;
+import java.rmi.server.RemoteObject;
+import java.rmi.server.UnicastRemoteObject;
+import java.security.KeyStore;
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import javax.management.MBeanServer;
+import javax.management.remote.JMXAuthenticator;
+import javax.management.remote.JMXConnectorServer;
+import javax.management.remote.JMXConnectorServerFactory;
+import javax.management.remote.JMXServiceURL;
+import javax.management.remote.rmi.RMIConnectorServer;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManagerFactory;
+import javax.rmi.ssl.SslRMIClientSocketFactory;
+import javax.rmi.ssl.SslRMIServerSocketFactory;
+import javax.security.auth.Subject;
+
+import com.sun.jmx.remote.internal.rmi.RMIExporter;
+import com.sun.jmx.remote.security.JMXPluggableAuthenticator;
+
+import jdk.internal.agent.Agent;
+import jdk.internal.agent.AgentConfigurationError;
+import static jdk.internal.agent.AgentConfigurationError.*;
+import jdk.internal.agent.ConnectorAddressLink;
+import jdk.internal.agent.FileSystem;
+import sun.rmi.server.UnicastRef;
+import sun.rmi.server.UnicastServerRef;
+import sun.rmi.server.UnicastServerRef2;
+
+/**
+ * This class initializes and starts the RMIConnectorServer for JSR 163
+ * JMX Monitoring.
+ **/
+public final class ConnectorBootstrap {
+
+ /**
+ * Default values for JMX configuration properties.
+ **/
+ public static interface DefaultValues {
+
+ public static final String PORT = "0";
+ public static final String CONFIG_FILE_NAME = "management.properties";
+ public static final String USE_SSL = "true";
+ public static final String USE_LOCAL_ONLY = "true";
+ public static final String USE_REGISTRY_SSL = "false";
+ public static final String USE_AUTHENTICATION = "true";
+ public static final String PASSWORD_FILE_NAME = "jmxremote.password";
+ public static final String ACCESS_FILE_NAME = "jmxremote.access";
+ public static final String SSL_NEED_CLIENT_AUTH = "false";
+ }
+
+ /**
+ * Names of JMX configuration properties.
+ **/
+ public static interface PropertyNames {
+
+ public static final String PORT =
+ "com.sun.management.jmxremote.port";
+ public static final String HOST =
+ "com.sun.management.jmxremote.host";
+ public static final String RMI_PORT =
+ "com.sun.management.jmxremote.rmi.port";
+ public static final String CONFIG_FILE_NAME =
+ "com.sun.management.config.file";
+ public static final String USE_LOCAL_ONLY =
+ "com.sun.management.jmxremote.local.only";
+ public static final String USE_SSL =
+ "com.sun.management.jmxremote.ssl";
+ public static final String USE_REGISTRY_SSL =
+ "com.sun.management.jmxremote.registry.ssl";
+ public static final String USE_AUTHENTICATION =
+ "com.sun.management.jmxremote.authenticate";
+ public static final String PASSWORD_FILE_NAME =
+ "com.sun.management.jmxremote.password.file";
+ public static final String ACCESS_FILE_NAME =
+ "com.sun.management.jmxremote.access.file";
+ public static final String LOGIN_CONFIG_NAME =
+ "com.sun.management.jmxremote.login.config";
+ public static final String SSL_ENABLED_CIPHER_SUITES =
+ "com.sun.management.jmxremote.ssl.enabled.cipher.suites";
+ public static final String SSL_ENABLED_PROTOCOLS =
+ "com.sun.management.jmxremote.ssl.enabled.protocols";
+ public static final String SSL_NEED_CLIENT_AUTH =
+ "com.sun.management.jmxremote.ssl.need.client.auth";
+ public static final String SSL_CONFIG_FILE_NAME =
+ "com.sun.management.jmxremote.ssl.config.file";
+ }
+
+ /**
+ * JMXConnectorServer associated data.
+ */
+ private static class JMXConnectorServerData {
+
+ public JMXConnectorServerData(
+ JMXConnectorServer jmxConnectorServer,
+ JMXServiceURL jmxRemoteURL) {
+ this.jmxConnectorServer = jmxConnectorServer;
+ this.jmxRemoteURL = jmxRemoteURL;
+ }
+ JMXConnectorServer jmxConnectorServer;
+ JMXServiceURL jmxRemoteURL;
+ }
+
+ /**
+ * <p>Prevents our RMI server objects from keeping the JVM alive.</p>
+ *
+ * <p>We use a private interface in Sun's JMX Remote API implementation
+ * that allows us to specify how to export RMI objects. We do so using
+ * UnicastServerRef, a class in Sun's RMI implementation. This is all
+ * non-portable, of course, so this is only valid because we are inside
+ * Sun's JRE.</p>
+ *
+ * <p>Objects are exported using {@link
+ * UnicastServerRef#exportObject(Remote, Object, boolean)}. The
+ * boolean parameter is called <code>permanent</code> and means
+ * both that the object is not eligible for Distributed Garbage
+ * Collection, and that its continued existence will not prevent
+ * the JVM from exiting. It is the latter semantics we want (we
+ * already have the former because of the way the JMX Remote API
+ * works). Hence the somewhat misleading name of this class.</p>
+ */
+ private static class PermanentExporter implements RMIExporter {
+
+ public Remote exportObject(Remote obj,
+ int port,
+ RMIClientSocketFactory csf,
+ RMIServerSocketFactory ssf)
+ throws RemoteException {
+
+ synchronized (this) {
+ if (firstExported == null) {
+ firstExported = obj;
+ }
+ }
+
+ final UnicastServerRef ref;
+ if (csf == null && ssf == null) {
+ ref = new UnicastServerRef(port);
+ } else {
+ ref = new UnicastServerRef2(port, csf, ssf);
+ }
+ return ref.exportObject(obj, null, true);
+ }
+
+ // Nothing special to be done for this case
+ public boolean unexportObject(Remote obj, boolean force)
+ throws NoSuchObjectException {
+ return UnicastRemoteObject.unexportObject(obj, force);
+ }
+ Remote firstExported;
+ }
+
+ /**
+ * This JMXAuthenticator wraps the JMXPluggableAuthenticator and verifies
+ * that at least one of the principal names contained in the authenticated
+ * Subject is present in the access file.
+ */
+ private static class AccessFileCheckerAuthenticator
+ implements JMXAuthenticator {
+
+ public AccessFileCheckerAuthenticator(Map<String, Object> env) throws IOException {
+ environment = env;
+ accessFile = (String) env.get("jmx.remote.x.access.file");
+ properties = propertiesFromFile(accessFile);
+ }
+
+ public Subject authenticate(Object credentials) {
+ final JMXAuthenticator authenticator =
+ new JMXPluggableAuthenticator(environment);
+ final Subject subject = authenticator.authenticate(credentials);
+ checkAccessFileEntries(subject);
+ return subject;
+ }
+
+ private void checkAccessFileEntries(Subject subject) {
+ if (subject == null) {
+ throw new SecurityException(
+ "Access denied! No matching entries found in " +
+ "the access file [" + accessFile + "] as the " +
+ "authenticated Subject is null");
+ }
+ final Set<Principal> principals = subject.getPrincipals();
+ for (Principal p1: principals) {
+ if (properties.containsKey(p1.getName())) {
+ return;
+ }
+ }
+
+ final Set<String> principalsStr = new HashSet<>();
+ for (Principal p2: principals) {
+ principalsStr.add(p2.getName());
+ }
+ throw new SecurityException(
+ "Access denied! No entries found in the access file [" +
+ accessFile + "] for any of the authenticated identities " +
+ principalsStr);
+ }
+
+ private static Properties propertiesFromFile(String fname)
+ throws IOException {
+ Properties p = new Properties();
+ if (fname == null) {
+ return p;
+ }
+ try (FileInputStream fin = new FileInputStream(fname)) {
+ p.load(fin);
+ }
+ return p;
+ }
+ private final Map<String, Object> environment;
+ private final Properties properties;
+ private final String accessFile;
+ }
+
+ // The variable below is here to support stop functionality
+ // It would be overriten if you call startRemoteCommectionServer second
+ // time. It's OK for now as logic in Agent.java forbids mutiple agents
+ private static Registry registry = null;
+
+ public static void unexportRegistry() {
+ // Remove the entry from registry
+ try {
+ if (registry != null) {
+ UnicastRemoteObject.unexportObject(registry, true);
+ registry = null;
+ }
+ } catch(NoSuchObjectException ex) {
+ // This exception can appears only if we attempt
+ // to unexportRegistry second time. So it's safe
+ // to ignore it without additional messages.
+ }
+ }
+
+ /**
+ * Initializes and starts the JMX Connector Server.
+ * If the com.sun.management.jmxremote.port property is not defined,
+ * simply return. Otherwise, attempts to load the config file, and
+ * then calls {@link #startRemoteConnectorServer
+ * (java.lang.String, java.util.Properties)}.
+ *
+ * This method is used by some jtreg tests.
+ **/
+ public static synchronized JMXConnectorServer initialize() {
+
+ // Load a new management properties
+ final Properties props = Agent.loadManagementProperties();
+ if (props == null) {
+ return null;
+ }
+
+ final String portStr = props.getProperty(PropertyNames.PORT);
+ return startRemoteConnectorServer(portStr, props);
+ }
+
+ /**
+ * This method is used by some jtreg tests.
+ *
+ * @see #startRemoteConnectorServer
+ * (String portStr, Properties props)
+ */
+ public static synchronized JMXConnectorServer initialize(String portStr, Properties props) {
+ return startRemoteConnectorServer(portStr, props);
+ }
+
+ /**
+ * Initializes and starts a JMX Connector Server for remote
+ * monitoring and management.
+ **/
+ public static synchronized JMXConnectorServer startRemoteConnectorServer(String portStr, Properties props) {
+
+ // Get port number
+ final int port;
+ try {
+ port = Integer.parseInt(portStr);
+ } catch (NumberFormatException x) {
+ throw new AgentConfigurationError(INVALID_JMXREMOTE_PORT, x, portStr);
+ }
+ if (port < 0) {
+ throw new AgentConfigurationError(INVALID_JMXREMOTE_PORT, portStr);
+ }
+
+ // User can specify a port to be used to export rmi object,
+ // in order to simplify firewall rules
+ // if port is not specified random one will be allocated.
+ int rmiPort = 0;
+ String rmiPortStr = props.getProperty(PropertyNames.RMI_PORT);
+ try {
+ if (rmiPortStr != null) {
+ rmiPort = Integer.parseInt(rmiPortStr);
+ }
+ } catch (NumberFormatException x) {
+ throw new AgentConfigurationError(INVALID_JMXREMOTE_RMI_PORT, x, rmiPortStr);
+ }
+ if (rmiPort < 0) {
+ throw new AgentConfigurationError(INVALID_JMXREMOTE_RMI_PORT, rmiPortStr);
+ }
+
+ // Do we use authentication?
+ final String useAuthenticationStr =
+ props.getProperty(PropertyNames.USE_AUTHENTICATION,
+ DefaultValues.USE_AUTHENTICATION);
+ final boolean useAuthentication =
+ Boolean.valueOf(useAuthenticationStr).booleanValue();
+
+ // Do we use SSL?
+ final String useSslStr =
+ props.getProperty(PropertyNames.USE_SSL,
+ DefaultValues.USE_SSL);
+ final boolean useSsl =
+ Boolean.valueOf(useSslStr).booleanValue();
+
+ // Do we use RMI Registry SSL?
+ final String useRegistrySslStr =
+ props.getProperty(PropertyNames.USE_REGISTRY_SSL,
+ DefaultValues.USE_REGISTRY_SSL);
+ final boolean useRegistrySsl =
+ Boolean.valueOf(useRegistrySslStr).booleanValue();
+
+ final String enabledCipherSuites =
+ props.getProperty(PropertyNames.SSL_ENABLED_CIPHER_SUITES);
+ String enabledCipherSuitesList[] = null;
+ if (enabledCipherSuites != null) {
+ StringTokenizer st = new StringTokenizer(enabledCipherSuites, ",");
+ int tokens = st.countTokens();
+ enabledCipherSuitesList = new String[tokens];
+ for (int i = 0; i < tokens; i++) {
+ enabledCipherSuitesList[i] = st.nextToken();
+ }
+ }
+
+ final String enabledProtocols =
+ props.getProperty(PropertyNames.SSL_ENABLED_PROTOCOLS);
+ String enabledProtocolsList[] = null;
+ if (enabledProtocols != null) {
+ StringTokenizer st = new StringTokenizer(enabledProtocols, ",");
+ int tokens = st.countTokens();
+ enabledProtocolsList = new String[tokens];
+ for (int i = 0; i < tokens; i++) {
+ enabledProtocolsList[i] = st.nextToken();
+ }
+ }
+
+ final String sslNeedClientAuthStr =
+ props.getProperty(PropertyNames.SSL_NEED_CLIENT_AUTH,
+ DefaultValues.SSL_NEED_CLIENT_AUTH);
+ final boolean sslNeedClientAuth =
+ Boolean.valueOf(sslNeedClientAuthStr).booleanValue();
+
+ // Read SSL config file name
+ final String sslConfigFileName =
+ props.getProperty(PropertyNames.SSL_CONFIG_FILE_NAME);
+
+ String loginConfigName = null;
+ String passwordFileName = null;
+ String accessFileName = null;
+
+ // Initialize settings when authentication is active
+ if (useAuthentication) {
+
+ // Get non-default login configuration
+ loginConfigName =
+ props.getProperty(PropertyNames.LOGIN_CONFIG_NAME);
+
+ if (loginConfigName == null) {
+ // Get password file
+ passwordFileName =
+ props.getProperty(PropertyNames.PASSWORD_FILE_NAME,
+ getDefaultFileName(DefaultValues.PASSWORD_FILE_NAME));
+ checkPasswordFile(passwordFileName);
+ }
+
+ // Get access file
+ accessFileName = props.getProperty(PropertyNames.ACCESS_FILE_NAME,
+ getDefaultFileName(DefaultValues.ACCESS_FILE_NAME));
+ checkAccessFile(accessFileName);
+ }
+
+ final String bindAddress =
+ props.getProperty(PropertyNames.HOST);
+
+ if (logger.isLoggable(Level.DEBUG)) {
+ logger.log(Level.DEBUG, "startRemoteConnectorServer",
+ Agent.getText("jmxremote.ConnectorBootstrap.starting") +
+ "\n\t" + PropertyNames.PORT + "=" + port +
+ (bindAddress == null ? "" : "\n\t" + PropertyNames.HOST + "=" + bindAddress) +
+ "\n\t" + PropertyNames.RMI_PORT + "=" + rmiPort +
+ "\n\t" + PropertyNames.USE_SSL + "=" + useSsl +
+ "\n\t" + PropertyNames.USE_REGISTRY_SSL + "=" + useRegistrySsl +
+ "\n\t" + PropertyNames.SSL_CONFIG_FILE_NAME + "=" + sslConfigFileName +
+ "\n\t" + PropertyNames.SSL_ENABLED_CIPHER_SUITES + "=" +
+ enabledCipherSuites +
+ "\n\t" + PropertyNames.SSL_ENABLED_PROTOCOLS + "=" +
+ enabledProtocols +
+ "\n\t" + PropertyNames.SSL_NEED_CLIENT_AUTH + "=" +
+ sslNeedClientAuth +
+ "\n\t" + PropertyNames.USE_AUTHENTICATION + "=" +
+ useAuthentication +
+ (useAuthentication ? (loginConfigName == null ? ("\n\t" + PropertyNames.PASSWORD_FILE_NAME + "=" +
+ passwordFileName) : ("\n\t" + PropertyNames.LOGIN_CONFIG_NAME + "=" +
+ loginConfigName)) : "\n\t" +
+ Agent.getText("jmxremote.ConnectorBootstrap.noAuthentication")) +
+ (useAuthentication ? ("\n\t" + PropertyNames.ACCESS_FILE_NAME + "=" +
+ accessFileName) : "") +
+ "");
+ }
+
+ final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ JMXConnectorServer cs = null;
+ JMXServiceURL url = null;
+ try {
+ final JMXConnectorServerData data = exportMBeanServer(
+ mbs, port, rmiPort, useSsl, useRegistrySsl,
+ sslConfigFileName, enabledCipherSuitesList,
+ enabledProtocolsList, sslNeedClientAuth,
+ useAuthentication, loginConfigName,
+ passwordFileName, accessFileName, bindAddress);
+ cs = data.jmxConnectorServer;
+ url = data.jmxRemoteURL;
+ config("startRemoteConnectorServer",
+ Agent.getText("jmxremote.ConnectorBootstrap.ready",
+ url.toString()));
+ } catch (Exception e) {
+ throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString());
+ }
+ try {
+ // Export remote connector address and associated configuration
+ // properties to the instrumentation buffer.
+ Map<String, String> properties = new HashMap<>();
+ properties.put("remoteAddress", url.toString());
+ properties.put("authenticate", useAuthenticationStr);
+ properties.put("ssl", useSslStr);
+ properties.put("sslRegistry", useRegistrySslStr);
+ properties.put("sslNeedClientAuth", sslNeedClientAuthStr);
+ ConnectorAddressLink.exportRemote(properties);
+ } catch (Exception e) {
+ // Remote connector server started but unable to export remote
+ // connector address and associated configuration properties to
+ // the instrumentation buffer - non-fatal error.
+ config("startRemoteConnectorServer", e);
+ }
+ return cs;
+ }
+
+ /*
+ * Creates and starts a RMI Connector Server for "local" monitoring
+ * and management.
+ */
+ public static JMXConnectorServer startLocalConnectorServer() {
+ // Ensure cryptographically strong random number generater used
+ // to choose the object number - see java.rmi.server.ObjID
+ System.setProperty("java.rmi.server.randomIDs", "true");
+
+ // This RMI server should not keep the VM alive
+ Map<String, Object> env = new HashMap<>();
+ env.put(RMIExporter.EXPORTER_ATTRIBUTE, new PermanentExporter());
+ env.put(RMIConnectorServer.CREDENTIAL_TYPES, new String[]{
+ String[].class.getName(), String.class.getName()
+ });
+
+ // The local connector server need only be available via the
+ // loopback connection.
+ String localhost = "localhost";
+ InetAddress lh = null;
+ try {
+ lh = InetAddress.getByName(localhost);
+ localhost = lh.getHostAddress();
+ } catch (UnknownHostException x) {
+ }
+
+ // localhost unknown or (somehow) didn't resolve to
+ // a loopback address.
+ if (lh == null || !lh.isLoopbackAddress()) {
+ localhost = "127.0.0.1";
+ }
+
+ MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+ try {
+ JMXServiceURL url = new JMXServiceURL("rmi", localhost, 0);
+ // Do we accept connections from local interfaces only?
+ Properties props = Agent.getManagementProperties();
+ if (props == null) {
+ props = new Properties();
+ }
+ String useLocalOnlyStr = props.getProperty(
+ PropertyNames.USE_LOCAL_ONLY, DefaultValues.USE_LOCAL_ONLY);
+ boolean useLocalOnly = Boolean.valueOf(useLocalOnlyStr).booleanValue();
+ if (useLocalOnly) {
+ env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,
+ new LocalRMIServerSocketFactory());
+ }
+ JMXConnectorServer server =
+ JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
+ server.start();
+ return server;
+ } catch (Exception e) {
+ throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString());
+ }
+ }
+
+ private static void checkPasswordFile(String passwordFileName) {
+ if (passwordFileName == null || passwordFileName.length() == 0) {
+ throw new AgentConfigurationError(PASSWORD_FILE_NOT_SET);
+ }
+ File file = new File(passwordFileName);
+ if (!file.exists()) {
+ throw new AgentConfigurationError(PASSWORD_FILE_NOT_FOUND, passwordFileName);
+ }
+
+ if (!file.canRead()) {
+ throw new AgentConfigurationError(PASSWORD_FILE_NOT_READABLE, passwordFileName);
+ }
+
+ FileSystem fs = FileSystem.open();
+ try {
+ if (fs.supportsFileSecurity(file)) {
+ if (!fs.isAccessUserOnly(file)) {
+ final String msg = Agent.getText("jmxremote.ConnectorBootstrap.password.readonly",
+ passwordFileName);
+ config("startRemoteConnectorServer", msg);
+ throw new AgentConfigurationError(PASSWORD_FILE_ACCESS_NOT_RESTRICTED,
+ passwordFileName);
+ }
+ }
+ } catch (IOException e) {
+ throw new AgentConfigurationError(PASSWORD_FILE_READ_FAILED,
+ e, passwordFileName);
+ }
+ }
+
+ private static void checkAccessFile(String accessFileName) {
+ if (accessFileName == null || accessFileName.length() == 0) {
+ throw new AgentConfigurationError(ACCESS_FILE_NOT_SET);
+ }
+ File file = new File(accessFileName);
+ if (!file.exists()) {
+ throw new AgentConfigurationError(ACCESS_FILE_NOT_FOUND, accessFileName);
+ }
+
+ if (!file.canRead()) {
+ throw new AgentConfigurationError(ACCESS_FILE_NOT_READABLE, accessFileName);
+ }
+ }
+
+ private static void checkRestrictedFile(String restrictedFileName) {
+ if (restrictedFileName == null || restrictedFileName.length() == 0) {
+ throw new AgentConfigurationError(FILE_NOT_SET);
+ }
+ File file = new File(restrictedFileName);
+ if (!file.exists()) {
+ throw new AgentConfigurationError(FILE_NOT_FOUND, restrictedFileName);
+ }
+ if (!file.canRead()) {
+ throw new AgentConfigurationError(FILE_NOT_READABLE, restrictedFileName);
+ }
+ FileSystem fs = FileSystem.open();
+ try {
+ if (fs.supportsFileSecurity(file)) {
+ if (!fs.isAccessUserOnly(file)) {
+ final String msg = Agent.getText(
+ "jmxremote.ConnectorBootstrap.file.readonly",
+ restrictedFileName);
+ config("startRemoteConnectorServer", msg);
+ throw new AgentConfigurationError(
+ FILE_ACCESS_NOT_RESTRICTED, restrictedFileName);
+ }
+ }
+ } catch (IOException e) {
+ throw new AgentConfigurationError(
+ FILE_READ_FAILED, e, restrictedFileName);
+ }
+ }
+
+ /**
+ * Compute the full path name for a default file.
+ * @param basename basename (with extension) of the default file.
+ * @return ${JRE}/conf/management/${basename}
+ **/
+ private static String getDefaultFileName(String basename) {
+ final String fileSeparator = File.separator;
+ return System.getProperty("java.home") + fileSeparator + "conf" +
+ fileSeparator + "management" + fileSeparator +
+ basename;
+ }
+
+ private static SslRMIServerSocketFactory createSslRMIServerSocketFactory(
+ String sslConfigFileName,
+ String[] enabledCipherSuites,
+ String[] enabledProtocols,
+ boolean sslNeedClientAuth,
+ String bindAddress) {
+ if (sslConfigFileName == null) {
+ return new HostAwareSslSocketFactory(
+ enabledCipherSuites,
+ enabledProtocols,
+ sslNeedClientAuth, bindAddress);
+ } else {
+ checkRestrictedFile(sslConfigFileName);
+ try {
+ // Load the SSL keystore properties from the config file
+ Properties p = new Properties();
+ try (InputStream in = new FileInputStream(sslConfigFileName)) {
+ BufferedInputStream bin = new BufferedInputStream(in);
+ p.load(bin);
+ }
+ String keyStore =
+ p.getProperty("javax.net.ssl.keyStore");
+ String keyStorePassword =
+ p.getProperty("javax.net.ssl.keyStorePassword", "");
+ String trustStore =
+ p.getProperty("javax.net.ssl.trustStore");
+ String trustStorePassword =
+ p.getProperty("javax.net.ssl.trustStorePassword", "");
+
+ char[] keyStorePasswd = null;
+ if (keyStorePassword.length() != 0) {
+ keyStorePasswd = keyStorePassword.toCharArray();
+ }
+
+ char[] trustStorePasswd = null;
+ if (trustStorePassword.length() != 0) {
+ trustStorePasswd = trustStorePassword.toCharArray();
+ }
+
+ KeyStore ks = null;
+ if (keyStore != null) {
+ ks = KeyStore.getInstance(KeyStore.getDefaultType());
+ try (FileInputStream ksfis = new FileInputStream(keyStore)) {
+ ks.load(ksfis, keyStorePasswd);
+ }
+ }
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance(
+ KeyManagerFactory.getDefaultAlgorithm());
+ kmf.init(ks, keyStorePasswd);
+
+ KeyStore ts = null;
+ if (trustStore != null) {
+ ts = KeyStore.getInstance(KeyStore.getDefaultType());
+ try (FileInputStream tsfis = new FileInputStream(trustStore)) {
+ ts.load(tsfis, trustStorePasswd);
+ }
+ }
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance(
+ TrustManagerFactory.getDefaultAlgorithm());
+ tmf.init(ts);
+
+ SSLContext ctx = SSLContext.getInstance("SSL");
+ ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+ return new HostAwareSslSocketFactory(
+ ctx,
+ enabledCipherSuites,
+ enabledProtocols,
+ sslNeedClientAuth, bindAddress);
+ } catch (Exception e) {
+ throw new AgentConfigurationError(AGENT_EXCEPTION, e, e.toString());
+ }
+ }
+ }
+
+ private static JMXConnectorServerData exportMBeanServer(
+ MBeanServer mbs,
+ int port,
+ int rmiPort,
+ boolean useSsl,
+ boolean useRegistrySsl,
+ String sslConfigFileName,
+ String[] enabledCipherSuites,
+ String[] enabledProtocols,
+ boolean sslNeedClientAuth,
+ boolean useAuthentication,
+ String loginConfigName,
+ String passwordFileName,
+ String accessFileName,
+ String bindAddress)
+ throws IOException, MalformedURLException {
+
+ /* Make sure we use non-guessable RMI object IDs. Otherwise
+ * attackers could hijack open connections by guessing their
+ * IDs. */
+ System.setProperty("java.rmi.server.randomIDs", "true");
+
+ JMXServiceURL url = new JMXServiceURL("rmi", bindAddress, rmiPort);
+
+ Map<String, Object> env = new HashMap<>();
+
+ PermanentExporter exporter = new PermanentExporter();
+
+ env.put(RMIExporter.EXPORTER_ATTRIBUTE, exporter);
+ env.put(RMIConnectorServer.CREDENTIAL_TYPES, new String[]{
+ String[].class.getName(), String.class.getName()
+ });
+
+ boolean useSocketFactory = bindAddress != null && !useSsl;
+
+ if (useAuthentication) {
+ if (loginConfigName != null) {
+ env.put("jmx.remote.x.login.config", loginConfigName);
+ }
+ if (passwordFileName != null) {
+ env.put("jmx.remote.x.password.file", passwordFileName);
+ }
+
+ env.put("jmx.remote.x.access.file", accessFileName);
+
+ if (env.get("jmx.remote.x.password.file") != null ||
+ env.get("jmx.remote.x.login.config") != null) {
+ env.put(JMXConnectorServer.AUTHENTICATOR,
+ new AccessFileCheckerAuthenticator(env));
+ }
+ }
+
+ RMIClientSocketFactory csf = null;
+ RMIServerSocketFactory ssf = null;
+
+ if (useSsl || useRegistrySsl) {
+ csf = new SslRMIClientSocketFactory();
+ ssf = createSslRMIServerSocketFactory(
+ sslConfigFileName, enabledCipherSuites,
+ enabledProtocols, sslNeedClientAuth, bindAddress);
+ }
+
+ if (useSsl) {
+ env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE,
+ csf);
+ env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,
+ ssf);
+ }
+
+ if (useSocketFactory) {
+ ssf = new HostAwareSocketFactory(bindAddress);
+ env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE,
+ ssf);
+ }
+
+ JMXConnectorServer connServer = null;
+ try {
+ connServer =
+ JMXConnectorServerFactory.newJMXConnectorServer(url, env, mbs);
+ connServer.start();
+ } catch (IOException e) {
+ if (connServer == null || connServer.getAddress() == null) {
+ throw new AgentConfigurationError(CONNECTOR_SERVER_IO_ERROR,
+ e, url.toString());
+ } else {
+ throw new AgentConfigurationError(CONNECTOR_SERVER_IO_ERROR,
+ e, connServer.getAddress().toString());
+ }
+ }
+
+ if (useRegistrySsl) {
+ registry =
+ new SingleEntryRegistry(port, csf, ssf,
+ "jmxrmi", exporter.firstExported);
+ } else if (useSocketFactory) {
+ registry =
+ new SingleEntryRegistry(port, csf, ssf,
+ "jmxrmi", exporter.firstExported);
+ } else {
+ registry =
+ new SingleEntryRegistry(port,
+ "jmxrmi", exporter.firstExported);
+ }
+
+
+ int registryPort =
+ ((UnicastRef) ((RemoteObject) registry).getRef()).getLiveRef().getPort();
+ String jmxUrlStr = String.format("service:jmx:rmi:///jndi/rmi://%s:%d/jmxrmi",
+ url.getHost(), registryPort);
+ JMXServiceURL remoteURL = new JMXServiceURL(jmxUrlStr);
+
+ /* Our exporter remembers the first object it was asked to
+ export, which will be an RMIServerImpl appropriate for
+ publication in our special registry. We could
+ alternatively have constructed the RMIServerImpl explicitly
+ and then constructed an RMIConnectorServer passing it as a
+ parameter, but that's quite a bit more verbose and pulls in
+ lots of knowledge of the RMI connector. */
+
+ return new JMXConnectorServerData(connServer, remoteURL);
+ }
+
+ /**
+ * This class cannot be instantiated.
+ **/
+ private ConnectorBootstrap() {
+ }
+
+ private static final Logger logger =
+ System.getLogger(ConnectorBootstrap.class.getPackageName());
+ private static void config(String func, String msg) {
+ logger.log(Level.DEBUG, msg);
+ }
+
+ private static void config(String func, Throwable t) {
+ logger.log(Level.DEBUG, "ConnectorBootstrap::" + func, t);
+ }
+
+ private static void config(String func, String msg, Throwable t) {
+ logger.log(Level.DEBUG, msg, t);
+ }
+
+ private static class HostAwareSocketFactory implements RMIServerSocketFactory {
+
+ private final String bindAddress;
+
+ private HostAwareSocketFactory(String bindAddress) {
+ this.bindAddress = bindAddress;
+ }
+
+ @Override
+ public ServerSocket createServerSocket(int port) throws IOException {
+ if (bindAddress == null) {
+ return new ServerSocket(port);
+ } else {
+ try {
+ InetAddress addr = InetAddress.getByName(bindAddress);
+ return new ServerSocket(port, 0, addr);
+ } catch (UnknownHostException e) {
+ return new ServerSocket(port);
+ }
+ }
+ }
+ }
+
+ private static class HostAwareSslSocketFactory extends SslRMIServerSocketFactory {
+
+ private final String bindAddress;
+ private final String[] enabledCipherSuites;
+ private final String[] enabledProtocols;
+ private final boolean needClientAuth;
+ private final SSLContext context;
+
+ private HostAwareSslSocketFactory(String[] enabledCipherSuites,
+ String[] enabledProtocols,
+ boolean sslNeedClientAuth,
+ String bindAddress) throws IllegalArgumentException {
+ this(null, enabledCipherSuites, enabledProtocols, sslNeedClientAuth, bindAddress);
+ }
+
+ private HostAwareSslSocketFactory(SSLContext ctx,
+ String[] enabledCipherSuites,
+ String[] enabledProtocols,
+ boolean sslNeedClientAuth,
+ String bindAddress) throws IllegalArgumentException {
+ this.context = ctx;
+ this.bindAddress = bindAddress;
+ this.enabledProtocols = enabledProtocols;
+ this.enabledCipherSuites = enabledCipherSuites;
+ this.needClientAuth = sslNeedClientAuth;
+ checkValues(ctx, enabledCipherSuites, enabledProtocols);
+ }
+
+ @Override
+ public ServerSocket createServerSocket(int port) throws IOException {
+ if (bindAddress != null) {
+ try {
+ InetAddress addr = InetAddress.getByName(bindAddress);
+ return new SslServerSocket(port, 0, addr, context,
+ enabledCipherSuites, enabledProtocols, needClientAuth);
+ } catch (UnknownHostException e) {
+ return new SslServerSocket(port, context,
+ enabledCipherSuites, enabledProtocols, needClientAuth);
+ }
+ } else {
+ return new SslServerSocket(port, context,
+ enabledCipherSuites, enabledProtocols, needClientAuth);
+ }
+ }
+
+ private static void checkValues(SSLContext context,
+ String[] enabledCipherSuites,
+ String[] enabledProtocols) throws IllegalArgumentException {
+ // Force the initialization of the default at construction time,
+ // rather than delaying it to the first time createServerSocket()
+ // is called.
+ //
+ final SSLSocketFactory sslSocketFactory =
+ context == null ?
+ (SSLSocketFactory)SSLSocketFactory.getDefault() : context.getSocketFactory();
+ SSLSocket sslSocket = null;
+ if (enabledCipherSuites != null || enabledProtocols != null) {
+ try {
+ sslSocket = (SSLSocket) sslSocketFactory.createSocket();
+ } catch (Exception e) {
+ final String msg = "Unable to check if the cipher suites " +
+ "and protocols to enable are supported";
+ throw (IllegalArgumentException)
+ new IllegalArgumentException(msg).initCause(e);
+ }
+ }
+
+ // Check if all the cipher suites and protocol versions to enable
+ // are supported by the underlying SSL/TLS implementation and if
+ // true create lists from arrays.
+ //
+ if (enabledCipherSuites != null) {
+ sslSocket.setEnabledCipherSuites(enabledCipherSuites);
+ }
+ if (enabledProtocols != null) {
+ sslSocket.setEnabledProtocols(enabledProtocols);
+ }
+ }
+ }
+
+ private static class SslServerSocket extends ServerSocket {
+
+ private static SSLSocketFactory defaultSSLSocketFactory;
+ private final String[] enabledCipherSuites;
+ private final String[] enabledProtocols;
+ private final boolean needClientAuth;
+ private final SSLContext context;
+
+ private SslServerSocket(int port,
+ SSLContext ctx,
+ String[] enabledCipherSuites,
+ String[] enabledProtocols,
+ boolean needClientAuth) throws IOException {
+ super(port);
+ this.enabledProtocols = enabledProtocols;
+ this.enabledCipherSuites = enabledCipherSuites;
+ this.needClientAuth = needClientAuth;
+ this.context = ctx;
+ }
+
+ private SslServerSocket(int port,
+ int backlog,
+ InetAddress bindAddr,
+ SSLContext ctx,
+ String[] enabledCipherSuites,
+ String[] enabledProtocols,
+ boolean needClientAuth) throws IOException {
+ super(port, backlog, bindAddr);
+ this.enabledProtocols = enabledProtocols;
+ this.enabledCipherSuites = enabledCipherSuites;
+ this.needClientAuth = needClientAuth;
+ this.context = ctx;
+ }
+
+ @Override
+ public Socket accept() throws IOException {
+ final SSLSocketFactory sslSocketFactory =
+ context == null ?
+ getDefaultSSLSocketFactory() : context.getSocketFactory();
+ Socket socket = super.accept();
+ SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(
+ socket, socket.getInetAddress().getHostName(),
+ socket.getPort(), true);
+ sslSocket.setUseClientMode(false);
+ if (enabledCipherSuites != null) {
+ sslSocket.setEnabledCipherSuites(enabledCipherSuites);
+ }
+ if (enabledProtocols != null) {
+ sslSocket.setEnabledProtocols(enabledProtocols);
+ }
+ sslSocket.setNeedClientAuth(needClientAuth);
+ return sslSocket;
+ }
+
+ private static synchronized SSLSocketFactory getDefaultSSLSocketFactory() {
+ if (defaultSSLSocketFactory == null) {
+ defaultSSLSocketFactory = (SSLSocketFactory)SSLSocketFactory.getDefault();
+ return defaultSSLSocketFactory;
+ } else {
+ return defaultSSLSocketFactory;
+ }
+ }
+
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/sun/management/jmxremote/LocalRMIServerSocketFactory.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.management.jmxremote;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.rmi.server.RMIServerSocketFactory;
+import java.util.Enumeration;
+
+/**
+ * This RMI server socket factory creates server sockets that
+ * will only accept connection requests from clients running
+ * on the host where the RMI remote objects have been exported.
+ */
+public final class LocalRMIServerSocketFactory implements RMIServerSocketFactory {
+ /**
+ * Creates a server socket that only accepts connection requests from
+ * clients running on the host where the RMI remote objects have been
+ * exported.
+ */
+ public ServerSocket createServerSocket(int port) throws IOException {
+ return new ServerSocket(port) {
+ @Override
+ public Socket accept() throws IOException {
+ final Socket socket = super.accept();
+ final InetAddress remoteAddr = socket.getInetAddress();
+ final String msg = "The server sockets created using the " +
+ "LocalRMIServerSocketFactory only accept connections " +
+ "from clients running on the host where the RMI " +
+ "remote objects have been exported.";
+
+ if (remoteAddr == null) {
+ // Though unlikeky, the socket could be already
+ // closed... Send a more detailed message in
+ // this case. Also avoid throwing NullPointerExceptiion
+ //
+ String details = "";
+ if (socket.isClosed()) {
+ details = " Socket is closed.";
+ } else if (!socket.isConnected()) {
+ details = " Socket is not connected";
+ }
+ try {
+ socket.close();
+ } catch (Exception ok) {
+ // ok - this is just cleanup before throwing detailed
+ // exception.
+ }
+ throw new IOException(msg +
+ " Couldn't determine client address." +
+ details);
+ } else if (remoteAddr.isLoopbackAddress()) {
+ // local address: accept the connection.
+ return socket;
+ }
+ // Retrieve all the network interfaces on this host.
+ Enumeration<NetworkInterface> nis;
+ try {
+ nis = NetworkInterface.getNetworkInterfaces();
+ } catch (SocketException e) {
+ try {
+ socket.close();
+ } catch (IOException ioe) {
+ // Ignore...
+ }
+ throw new IOException(msg, e);
+ }
+ // Walk through the network interfaces to see
+ // if any of them matches the client's address.
+ // If true, then the client's address is local.
+ while (nis.hasMoreElements()) {
+ NetworkInterface ni = nis.nextElement();
+ Enumeration<InetAddress> addrs = ni.getInetAddresses();
+ while (addrs.hasMoreElements()) {
+ InetAddress localAddr = addrs.nextElement();
+ if (localAddr.equals(remoteAddr)) {
+ return socket;
+ }
+ }
+ }
+ // The client's address is remote so refuse the connection.
+ try {
+ socket.close();
+ } catch (IOException ioe) {
+ // Ignore...
+ }
+ throw new IOException(msg);
+ }
+ };
+ }
+
+ /**
+ * Two LocalRMIServerSocketFactory objects
+ * are equal if they are of the same type.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ return (obj instanceof LocalRMIServerSocketFactory);
+ }
+
+ /**
+ * Returns a hash code value for this LocalRMIServerSocketFactory.
+ */
+ @Override
+ public int hashCode() {
+ return getClass().hashCode();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/sun/management/jmxremote/SingleEntryRegistry.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2003, 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.
+ */
+
+/*
+ * @author Sun Microsystems, Inc.
+ * @build @BUILD_TAG_PLACEHOLDER@
+ *
+ * @COPYRIGHT_MINI_LEGAL_NOTICE_PLACEHOLDER@
+ */
+
+package sun.management.jmxremote;
+
+import java.rmi.AccessException;
+import java.rmi.NotBoundException;
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.server.RMIClientSocketFactory;
+import java.rmi.server.RMIServerSocketFactory;
+
+import sun.rmi.registry.RegistryImpl;
+
+/** A Registry that consists of a single entry that never changes. */
+public class SingleEntryRegistry extends RegistryImpl {
+ SingleEntryRegistry(int port, String name, Remote object)
+ throws RemoteException {
+ super(port);
+ this.name = name;
+ this.object = object;
+ }
+
+ SingleEntryRegistry(int port,
+ RMIClientSocketFactory csf,
+ RMIServerSocketFactory ssf,
+ String name,
+ Remote object)
+ throws RemoteException {
+ super(port, csf, ssf);
+ this.name = name;
+ this.object = object;
+ }
+
+ public String[] list() {
+ return new String[] {name};
+ }
+
+ public Remote lookup(String name) throws NotBoundException {
+ if (name.equals(this.name))
+ return object;
+ throw new NotBoundException("Not bound: \"" + name + "\" (only " +
+ "bound name is \"" + this.name + "\")");
+ }
+
+ public void bind(String name, Remote obj) throws AccessException {
+ throw new AccessException("Cannot modify this registry");
+ }
+
+ public void rebind(String name, Remote obj) throws AccessException {
+ throw new AccessException("Cannot modify this registry");
+ }
+
+ public void unbind(String name) throws AccessException {
+ throw new AccessException("Cannot modify this registry");
+ }
+
+ private final String name;
+ private final Remote object;
+
+ private static final long serialVersionUID = -4897238949499730950L;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/classes/sun/management/jmxremote/package.html Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<head>
+<!--
+
+ Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ This code is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 only, as
+ published by the Free Software Foundation. Oracle designates this
+ particular file as subject to the "Classpath" exception as provided
+ by Oracle in the LICENSE file that accompanied this code.
+
+ This code is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ version 2 for more details (a copy is included in the LICENSE file that
+ accompanied this code).
+
+ You should have received a copy of the GNU General Public License version
+ 2 along with this work; if not, write to the Free Software Foundation,
+ Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+
+ Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ or visit www.oracle.com if you need additional information or have any
+ questions.
+
+-->
+
+</head>
+<body bgcolor="white">
+
+Provides classes that make it possible to create a JMX RMI Connector Server
+at bootstrap for the JSR 163 instrumentation.
+
+@since 1.5
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/conf/jmxremote.access Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,79 @@
+######################################################################
+# Default Access Control File for Remote JMX(TM) Monitoring
+######################################################################
+#
+# Access control file for Remote JMX API access to monitoring.
+# This file defines the allowed access for different roles. The
+# password file (jmxremote.password by default) defines the roles and their
+# passwords. To be functional, a role must have an entry in
+# both the password and the access files.
+#
+# The default location of this file is $JRE/conf/management/jmxremote.access
+# You can specify an alternate location by specifying a property in
+# the management config file $JRE/conf/management/management.properties
+# (See that file for details)
+#
+# The file format for password and access files is syntactically the same
+# as the Properties file format. The syntax is described in the Javadoc
+# for java.util.Properties.load.
+# A typical access file has multiple lines, where each line is blank,
+# a comment (like this one), or an access control entry.
+#
+# An access control entry consists of a role name, and an
+# associated access level. The role name is any string that does not
+# itself contain spaces or tabs. It corresponds to an entry in the
+# password file (jmxremote.password). The access level is one of the
+# following:
+# "readonly" grants access to read attributes of MBeans.
+# For monitoring, this means that a remote client in this
+# role can read measurements but cannot perform any action
+# that changes the environment of the running program.
+# "readwrite" grants access to read and write attributes of MBeans,
+# to invoke operations on them, and optionally
+# to create or remove them. This access should be granted
+# only to trusted clients, since they can potentially
+# interfere with the smooth operation of a running program.
+#
+# The "readwrite" access level can optionally be followed by the "create" and/or
+# "unregister" keywords. The "unregister" keyword grants access to unregister
+# (delete) MBeans. The "create" keyword grants access to create MBeans of a
+# particular class or of any class matching a particular pattern. Access
+# should only be granted to create MBeans of known and trusted classes.
+#
+# For example, the following entry would grant readwrite access
+# to "controlRole", as well as access to create MBeans of the class
+# javax.management.monitor.CounterMonitor and to unregister any MBean:
+# controlRole readwrite \
+# create javax.management.monitor.CounterMonitorMBean \
+# unregister
+# or equivalently:
+# controlRole readwrite unregister create javax.management.monitor.CounterMBean
+#
+# The following entry would grant readwrite access as well as access to create
+# MBeans of any class in the packages javax.management.monitor and
+# javax.management.timer:
+# controlRole readwrite \
+# create javax.management.monitor.*,javax.management.timer.* \
+# unregister
+#
+# The \ character is defined in the Properties file syntax to allow continuation
+# lines as shown here. A * in a class pattern matches a sequence of characters
+# other than dot (.), so javax.management.monitor.* matches
+# javax.management.monitor.CounterMonitor but not
+# javax.management.monitor.foo.Bar.
+#
+# A given role should have at most one entry in this file. If a role
+# has no entry, it has no access.
+# If multiple entries are found for the same role name, then the last
+# access entry is used.
+#
+#
+# Default access control entries:
+# o The "monitorRole" role has readonly access.
+# o The "controlRole" role has readwrite access and can create the standard
+# Timer and Monitor MBeans defined by the JMX API.
+
+monitorRole readonly
+controlRole readwrite \
+ create javax.management.monitor.*,javax.management.timer.* \
+ unregister
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/conf/jmxremote.password.template Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,64 @@
+# ----------------------------------------------------------------------
+# Template for jmxremote.password
+#
+# o Copy this template to jmxremote.password
+# o Set the user/password entries in jmxremote.password
+# o Change the permission of jmxremote.password to read-only
+# by the owner.
+#
+# See below for the location of jmxremote.password file.
+# ----------------------------------------------------------------------
+
+##############################################################
+# Password File for Remote JMX Monitoring
+##############################################################
+#
+# Password file for Remote JMX API access to monitoring. This
+# file defines the different roles and their passwords. The access
+# control file (jmxremote.access by default) defines the allowed
+# access for each role. To be functional, a role must have an entry
+# in both the password and the access files.
+#
+# Default location of this file is $JRE/conf/management/jmxremote.password
+# You can specify an alternate location by specifying a property in
+# the management config file $JRE/conf/management/management.properties
+# or by specifying a system property (See that file for details).
+
+
+##############################################################
+# File permissions of the jmxremote.password file
+##############################################################
+# Since there are cleartext passwords stored in this file,
+# this file must be readable by ONLY the owner,
+# otherwise the program will exit with an error.
+#
+# The file format for password and access files is syntactically the same
+# as the Properties file format. The syntax is described in the Javadoc
+# for java.util.Properties.load.
+# Typical password file has multiple lines, where each line is blank,
+# a comment (like this one), or a password entry.
+#
+#
+# A password entry consists of a role name and an associated
+# password. The role name is any string that does not itself contain
+# spaces or tabs. The password is again any string that does not
+# contain spaces or tabs. Note that passwords appear in the clear in
+# this file, so it is a good idea not to use valuable passwords.
+#
+# A given role should have at most one entry in this file. If a role
+# has no entry, it has no access.
+# If multiple entries are found for the same role name, then the last one
+# is used.
+#
+# In a typical installation, this file can be read by anybody on the
+# local machine, and possibly by people on other machines.
+# For # security, you should either restrict the access to this file,
+# or specify another, less accessible file in the management config file
+# as described above.
+#
+# Following are two commented-out entries. The "measureRole" role has
+# password "QED". The "controlRole" role has password "R&D".
+#
+# monitorRole QED
+# controlRole R&D
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/share/conf/management.properties Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,331 @@
+#####################################################################
+# Default Configuration File for Java Platform Management
+#####################################################################
+#
+# The Management Configuration file (in java.util.Properties format)
+# will be read if one of the following system properties is set:
+# -Dcom.sun.management.jmxremote.port=<port-number>
+# or -Dcom.sun.management.snmp.port=<port-number>
+# or -Dcom.sun.management.config.file=<this-file>
+#
+# The default Management Configuration file is:
+#
+# $JRE/conf/management/management.properties
+#
+# Another location for the Management Configuration File can be specified
+# by the following property on the Java command line:
+#
+# -Dcom.sun.management.config.file=<this-file>
+#
+# If -Dcom.sun.management.config.file=<this-file> is set, the port
+# number for the management agent can be specified in the config file
+# using the following lines:
+#
+# ################ Management Agent Port #########################
+#
+# For setting the JMX RMI agent port use the following line
+# com.sun.management.jmxremote.port=<port-number>
+#
+# For setting the SNMP agent port use the following line
+# com.sun.management.snmp.port=<port-number>
+
+#####################################################################
+# Optional Instrumentation
+#####################################################################
+#
+# By default only the basic instrumentation with low overhead is on.
+# The following properties allow to selectively turn on optional
+# instrumentation which are off by default and may have some
+# additional overhead.
+#
+# com.sun.management.enableThreadContentionMonitoring
+#
+# This option enables thread contention monitoring if the
+# Java virtual machine supports such instrumentation.
+# Refer to the specification for the java.lang.management.ThreadMBean
+# interface - see isThreadContentionMonitoringSupported() method.
+#
+
+# To enable thread contention monitoring, uncomment the following line
+# com.sun.management.enableThreadContentionMonitoring
+
+#####################################################################
+# SNMP Management Properties
+#####################################################################
+#
+# If the system property -Dcom.sun.management.snmp.port=<port-number>
+# is set then
+# - The SNMP agent (with the Java virtual machine MIB) is started
+# that listens on the specified port for incoming SNMP requests.
+# - the following properties for read for SNMP management.
+#
+# The configuration can be specified only at startup time.
+# Later changes to the above system property (e.g. via setProperty method), this
+# config file, or the ACL file has no effect to the running SNMP agent.
+#
+
+#
+# ##################### SNMP Trap Port #########################
+#
+# com.sun.management.snmp.trap=<trap-destination-port-number>
+# Specifies the remote port number at which managers are expected
+# to listen for trap. For each host defined in the ACL file,
+# the SNMP agent will send traps at <host>:<trap-destination-port-number>
+# Default for this property is 162.
+#
+
+# To set port for sending traps to a different port use the following line
+# com.sun.management.snmp.trap=<trap-destination-port-number>
+
+#
+# ################ SNMP listen interface #########################
+#
+# com.sun.management.snmp.interface=<InetAddress>
+# Specifies the local interface on which the SNMP agent will bind.
+# This is useful when running on machines which have several
+# interfaces defined. It makes it possible to listen to a specific
+# subnet accessible through that interface.
+# Default for this property is "localhost".
+#
+# The format of the value for that property is any string accepted
+# by java.net.InetAddress.getByName(String).
+#
+
+# For restricting the port on which SNMP agent listens use the following line
+# com.sun.management.snmp.interface=<InetAddress>
+
+#
+# #################### SNMP ACL file #########################
+#
+# com.sun.management.snmp.acl=true|false
+# Default for this property is true. (Case for true/false ignored)
+# If this property is specified as false then the ACL file
+# is not checked: all manager hosts are allowed all access.
+#
+
+# For SNMP without checking ACL file uncomment the following line
+# com.sun.management.snmp.acl=false
+
+#
+# com.sun.management.snmp.acl.file=filepath
+# Specifies location for ACL file
+# This is optional - default location is
+# $JRE/conf/management/snmp.acl
+#
+# If the property "com.sun.management.snmp.acl" is set to false,
+# then this property and the ACL file are ignored.
+# Otherwise the ACL file must exist and be in the valid format.
+# If the ACL file is empty or non existent then no access is allowed.
+#
+# The SNMP agent will read the ACL file at startup time.
+# Modification to the ACL file has no effect to any running SNMP
+# agents which read that ACL file at startup.
+#
+
+# For a non-default acl file location use the following line
+# com.sun.management.snmp.acl.file=filepath
+
+#####################################################################
+# RMI Management Properties
+#####################################################################
+#
+# If system property -Dcom.sun.management.jmxremote.port=<port-number>
+# is set then
+# - A MBean server is started
+# - JRE Platform MBeans are registered in the MBean server
+# - RMI connector is published in a private readonly registry at
+# specified port using a well known name, "jmxrmi"
+# - the following properties are read for JMX remote management.
+#
+# The configuration can be specified only at startup time.
+# Later changes to above system property (e.g. via setProperty method),
+# this config file, the password file, or the access file have no effect to the
+# running MBean server, the connector, or the registry.
+#
+
+#
+# ########## RMI connector settings for local management ##########
+#
+# com.sun.management.jmxremote.local.only=true|false
+# Default for this property is true. (Case for true/false ignored)
+# If this property is specified as true then the local JMX RMI connector
+# server will only accept connection requests from clients running on
+# the host where the out-of-the-box JMX management agent is running.
+# In order to ensure backwards compatibility this property could be
+# set to false. However, deploying the local management agent in this
+# way is discouraged because the local JMX RMI connector server will
+# accept connection requests from any client either local or remote.
+# For remote management the remote JMX RMI connector server should
+# be used instead with authentication and SSL/TLS encryption enabled.
+#
+
+# For allowing the local management agent accept local
+# and remote connection requests use the following line
+# com.sun.management.jmxremote.local.only=false
+
+#
+# ###################### RMI SSL #############################
+#
+# com.sun.management.jmxremote.ssl=true|false
+# Default for this property is true. (Case for true/false ignored)
+# If this property is specified as false then SSL is not used.
+#
+
+# For RMI monitoring without SSL use the following line
+# com.sun.management.jmxremote.ssl=false
+
+# com.sun.management.jmxremote.ssl.config.file=filepath
+# Specifies the location of the SSL configuration file. A properties
+# file can be used to supply the keystore and truststore location and
+# password settings thus avoiding to pass them as cleartext in the
+# command-line.
+#
+# The current implementation of the out-of-the-box management agent will
+# look up and use the properties specified below to configure the SSL
+# keystore and truststore, if present:
+# javax.net.ssl.keyStore=<keystore-location>
+# javax.net.ssl.keyStorePassword=<keystore-password>
+# javax.net.ssl.trustStore=<truststore-location>
+# javax.net.ssl.trustStorePassword=<truststore-password>
+# Any other properties in the file will be ignored. This will allow us
+# to extend the property set in the future if required by the default
+# SSL implementation.
+#
+# If the property "com.sun.management.jmxremote.ssl" is set to false,
+# then this property is ignored.
+#
+
+# For supplying the keystore settings in a file use the following line
+# com.sun.management.jmxremote.ssl.config.file=filepath
+
+# com.sun.management.jmxremote.ssl.enabled.cipher.suites=<cipher-suites>
+# The value of this property is a string that is a comma-separated list
+# of SSL/TLS cipher suites to enable. This property can be specified in
+# conjunction with the previous property "com.sun.management.jmxremote.ssl"
+# in order to control which particular SSL/TLS cipher suites are enabled
+# for use by accepted connections. If this property is not specified then
+# the SSL/TLS RMI Server Socket Factory uses the SSL/TLS cipher suites that
+# are enabled by default.
+#
+
+# com.sun.management.jmxremote.ssl.enabled.protocols=<protocol-versions>
+# The value of this property is a string that is a comma-separated list
+# of SSL/TLS protocol versions to enable. This property can be specified in
+# conjunction with the previous property "com.sun.management.jmxremote.ssl"
+# in order to control which particular SSL/TLS protocol versions are
+# enabled for use by accepted connections. If this property is not
+# specified then the SSL/TLS RMI Server Socket Factory uses the SSL/TLS
+# protocol versions that are enabled by default.
+#
+
+# com.sun.management.jmxremote.ssl.need.client.auth=true|false
+# Default for this property is false. (Case for true/false ignored)
+# If this property is specified as true in conjunction with the previous
+# property "com.sun.management.jmxremote.ssl" then the SSL/TLS RMI Server
+# Socket Factory will require client authentication.
+#
+
+# For RMI monitoring with SSL client authentication use the following line
+# com.sun.management.jmxremote.ssl.need.client.auth=true
+
+# com.sun.management.jmxremote.registry.ssl=true|false
+# Default for this property is false. (Case for true/false ignored)
+# If this property is specified as true then the RMI registry used
+# to bind the RMIServer remote object is protected with SSL/TLS
+# RMI Socket Factories that can be configured with the properties:
+# com.sun.management.jmxremote.ssl.config.file
+# com.sun.management.jmxremote.ssl.enabled.cipher.suites
+# com.sun.management.jmxremote.ssl.enabled.protocols
+# com.sun.management.jmxremote.ssl.need.client.auth
+# If the two properties below are true at the same time, i.e.
+# com.sun.management.jmxremote.ssl=true
+# com.sun.management.jmxremote.registry.ssl=true
+# then the RMIServer remote object and the RMI registry are
+# both exported with the same SSL/TLS RMI Socket Factories.
+#
+
+# For using an SSL/TLS protected RMI registry use the following line
+# com.sun.management.jmxremote.registry.ssl=true
+
+#
+# ################ RMI User authentication ################
+#
+# com.sun.management.jmxremote.authenticate=true|false
+# Default for this property is true. (Case for true/false ignored)
+# If this property is specified as false then no authentication is
+# performed and all users are allowed all access.
+#
+
+# For RMI monitoring without any checking use the following line
+# com.sun.management.jmxremote.authenticate=false
+
+#
+# ################ RMI Login configuration ###################
+#
+# com.sun.management.jmxremote.login.config=<config-name>
+# Specifies the name of a JAAS login configuration entry to use when
+# authenticating users of RMI monitoring.
+#
+# Setting this property is optional - the default login configuration
+# specifies a file-based authentication that uses the password file.
+#
+# When using this property to override the default login configuration
+# then the named configuration entry must be in a file that gets loaded
+# by JAAS. In addition, the login module(s) specified in the configuration
+# should use the name and/or password callbacks to acquire the user's
+# credentials. See the NameCallback and PasswordCallback classes in the
+# javax.security.auth.callback package for more details.
+#
+# If the property "com.sun.management.jmxremote.authenticate" is set to
+# false, then this property and the password & access files are ignored.
+#
+
+# For a non-default login configuration use the following line
+# com.sun.management.jmxremote.login.config=<config-name>
+
+#
+# ################ RMI Password file location ##################
+#
+# com.sun.management.jmxremote.password.file=filepath
+# Specifies location for password file
+# This is optional - default location is
+# $JRE/conf/management/jmxremote.password
+#
+# If the property "com.sun.management.jmxremote.authenticate" is set to
+# false, then this property and the password & access files are ignored.
+# Otherwise the password file must exist and be in the valid format.
+# If the password file is empty or non-existent then no access is allowed.
+#
+
+# For a non-default password file location use the following line
+# com.sun.management.jmxremote.password.file=filepath
+
+#
+# ################ RMI Access file location #####################
+#
+# com.sun.management.jmxremote.access.file=filepath
+# Specifies location for access file
+# This is optional - default location is
+# $JRE/conf/management/jmxremote.access
+#
+# If the property "com.sun.management.jmxremote.authenticate" is set to
+# false, then this property and the password & access files are ignored.
+# Otherwise, the access file must exist and be in the valid format.
+# If the access file is empty or non-existent then no access is allowed.
+#
+
+# For a non-default password file location use the following line
+# com.sun.management.jmxremote.access.file=filepath
+#
+
+# ################ Management agent listen interface #########################
+#
+# com.sun.management.jmxremote.host=<host-or-interface-name>
+# Specifies the local interface on which the JMX RMI agent will bind.
+# This is useful when running on machines which have several
+# interfaces defined. It makes it possible to listen to a specific
+# subnet accessible through that interface.
+#
+# The format of the value for that property is any string accepted
+# by java.net.InetAddress.getByName(String).
+#
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/unix/classes/jdk/internal/agent/FileSystemImpl.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.agent;
+
+import java.io.File;
+import java.io.IOException;
+
+/*
+ * Solaris/Linux implementation of jdk.internal.agent.FileSystem
+ */
+public class FileSystemImpl extends FileSystem {
+
+ public boolean supportsFileSecurity(File f) throws IOException {
+ return true;
+ }
+
+ public boolean isAccessUserOnly(File f) throws IOException {
+ return isAccessUserOnly0(f.getPath());
+ }
+
+ // Native methods
+
+ static native boolean isAccessUserOnly0(String path) throws IOException;
+
+ // Initialization
+
+ static {
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Void>() {
+ public Void run() {
+ System.loadLibrary("management_rmi");
+ return null;
+ }
+ });
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/unix/native/libmanagement_rmi/FileSystemImpl.c Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jdk_internal_agent_FileSystemImpl.h"
+
+#ifdef _ALLBSD_SOURCE
+#define stat64 stat
+#endif
+
+/*
+ * JNI_OnLoad
+ */
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
+{
+ JNIEnv* env;
+
+ if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) {
+ return JNI_EVERSION; /* JNI version not supported */
+ }
+
+ return JNI_VERSION_9;
+}
+
+/*
+ * Class: jdk_internal_agent_FileSystemImpl
+ * Method: isAccessUserOnly0
+ * Signature: (Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jdk_internal_agent_FileSystemImpl_isAccessUserOnly0
+ (JNIEnv *env, jclass ignored, jstring str)
+{
+ jboolean res = JNI_FALSE;
+ jboolean isCopy;
+ const char *path = JNU_GetStringPlatformChars(env, str, &isCopy);
+ if (path != NULL) {
+ struct stat64 sb;
+ if (stat64(path, &sb) == 0) {
+ res = ((sb.st_mode & (S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH)) == 0) ? JNI_TRUE : JNI_FALSE;
+ } else {
+ JNU_ThrowIOExceptionWithLastError(env, "stat64 failed");
+ }
+ if (isCopy) {
+ JNU_ReleaseStringPlatformChars(env, str, path);
+ }
+ }
+ return res;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/windows/classes/jdk/internal/agent/FileSystemImpl.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.agent;
+
+import java.io.File;
+import java.io.IOException;
+
+/*
+ * Windows implementation of sun.management.FileSystem
+ */
+public class FileSystemImpl extends FileSystem {
+
+ public boolean supportsFileSecurity(File f) throws IOException {
+ return isSecuritySupported0(f.getAbsolutePath());
+ }
+
+ public boolean isAccessUserOnly(File f) throws IOException {
+ String path = f.getAbsolutePath();
+ if (!isSecuritySupported0(path)) {
+ throw new UnsupportedOperationException("File system does not support file security");
+ }
+ return isAccessUserOnly0(path);
+ }
+
+ // Native methods
+
+ static native void init0();
+
+ static native boolean isSecuritySupported0(String path) throws IOException;
+
+ static native boolean isAccessUserOnly0(String path) throws IOException;
+
+ // Initialization
+
+ static {
+ java.security.AccessController.doPrivileged(
+ new java.security.PrivilegedAction<Void>() {
+ public Void run() {
+ System.loadLibrary("management_rmi");
+ return null;
+ }
+ });
+ init0();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.management.agent/windows/native/libmanagement_rmi/FileSystemImpl.c Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2004, 2011, 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 <windows.h>
+#include <malloc.h>
+#include <string.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jdk_internal_agent_FileSystemImpl.h"
+
+JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved)
+{
+ JNIEnv* env;
+
+ if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_2) != JNI_OK) {
+ return JNI_EVERSION; /* JNI version not supported */
+ }
+
+ return JNI_VERSION_9;
+}
+
+
+/*
+ * Access mask to represent any file access
+ */
+#define ANY_ACCESS (FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE)
+
+/*
+ * Returns JNI_TRUE if the specified file is on a file system that supports
+ * persistent ACLs (On NTFS file systems returns true, on FAT32 file systems
+ * returns false).
+ */
+static jboolean isSecuritySupported(JNIEnv* env, const char* path) {
+ char* root;
+ char* p;
+ BOOL res;
+ DWORD dwMaxComponentLength;
+ DWORD dwFlags;
+ char fsName[128];
+ DWORD fsNameLength;
+
+ /*
+ * Get root directory. Assume that files are absolute paths. For UNCs
+ * the slash after the share name is required.
+ */
+ root = strdup(path);
+ if (*root == '\\') {
+ /*
+ * \\server\share\file ==> \\server\share\
+ */
+ int slashskip = 3;
+ p = root;
+ while ((*p == '\\') && (slashskip > 0)) {
+ char* p2;
+ p++;
+ p2 = strchr(p, '\\');
+ if ((p2 == NULL) || (*p2 != '\\')) {
+ free(root);
+ JNU_ThrowIOException(env, "Malformed UNC");
+ return JNI_FALSE;
+ }
+ p = p2;
+ slashskip--;
+ }
+ if (slashskip != 0) {
+ free(root);
+ JNU_ThrowIOException(env, "Malformed UNC");
+ return JNI_FALSE;
+ }
+ p++;
+ *p = '\0';
+
+ } else {
+ p = strchr(root, '\\');
+ if (p == NULL) {
+ free(root);
+ JNU_ThrowIOException(env, "Absolute filename not specified");
+ return JNI_FALSE;
+ }
+ p++;
+ *p = '\0';
+ }
+
+
+ /*
+ * Get the volume information - this gives us the file system file and
+ * also tells us if the file system supports persistent ACLs.
+ */
+ fsNameLength = sizeof(fsName)-1;
+ res = GetVolumeInformation(root,
+ NULL, // address of name of the volume, can be NULL
+ 0, // length of volume name
+ NULL, // address of volume serial number, can be NULL
+ &dwMaxComponentLength,
+ &dwFlags,
+ fsName,
+ fsNameLength);
+ if (res == 0) {
+ free(root);
+ JNU_ThrowIOExceptionWithLastError(env, "GetVolumeInformation failed");
+ return JNI_FALSE;
+ }
+
+ free(root);
+ return (dwFlags & FS_PERSISTENT_ACLS) ? JNI_TRUE : JNI_FALSE;
+}
+
+
+/*
+ * Returns the security descriptor for a file.
+ */
+static SECURITY_DESCRIPTOR* getFileSecurityDescriptor(JNIEnv* env, const char* path) {
+ SECURITY_DESCRIPTOR* sd;
+ DWORD len = 0;
+ SECURITY_INFORMATION info =
+ OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
+
+ GetFileSecurityA(path, info , 0, 0, &len);
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+ JNU_ThrowIOExceptionWithLastError(env, "GetFileSecurity failed");
+ return NULL;
+ }
+ sd = (SECURITY_DESCRIPTOR *)malloc(len);
+ if (sd == NULL) {
+ JNU_ThrowOutOfMemoryError(env, 0);
+ } else {
+ if (!(*GetFileSecurityA)(path, info, sd, len, &len)) {
+ JNU_ThrowIOExceptionWithLastError(env, "GetFileSecurity failed");
+ free(sd);
+ return NULL;
+ }
+ }
+ return sd;
+}
+
+/*
+ * Returns pointer to the SID identifying the owner of the specified
+ * file.
+ */
+static SID* getFileOwner(JNIEnv* env, SECURITY_DESCRIPTOR* sd) {
+ SID* owner;
+ BOOL defaulted;
+
+ if (!GetSecurityDescriptorOwner(sd, &owner, &defaulted)) {
+ JNU_ThrowIOExceptionWithLastError(env, "GetSecurityDescriptorOwner failed");
+ return NULL;
+ }
+ return owner;
+}
+
+/*
+ * Returns pointer discretionary access-control list (ACL) from the security
+ * descriptor of the specified file.
+ */
+static ACL* getFileDACL(JNIEnv* env, SECURITY_DESCRIPTOR* sd) {
+ ACL *acl;
+ int defaulted, present;
+
+ if (!GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted)) {
+ JNU_ThrowIOExceptionWithLastError(env, "GetSecurityDescriptorDacl failed");
+ return NULL;
+ }
+ if (!present) {
+ JNU_ThrowInternalError(env, "Security descriptor does not contain a DACL");
+ return NULL;
+ }
+ return acl;
+}
+
+/*
+ * Returns JNI_TRUE if the specified owner is the only SID will access
+ * to the file.
+ */
+static jboolean isAccessUserOnly(JNIEnv* env, SID* owner, ACL* acl) {
+ ACL_SIZE_INFORMATION acl_size_info;
+ DWORD i;
+
+ /*
+ * If there's no DACL then there's no access to the file
+ */
+ if (acl == NULL) {
+ return JNI_TRUE;
+ }
+
+ /*
+ * Get the ACE count
+ */
+ if (!GetAclInformation(acl, (void *) &acl_size_info, sizeof(acl_size_info),
+ AclSizeInformation)) {
+ JNU_ThrowIOExceptionWithLastError(env, "GetAclInformation failed");
+ return JNI_FALSE;
+ }
+
+ /*
+ * Iterate over the ACEs. For each "allow" type check that the SID
+ * matches the owner, and check that the access is read only.
+ */
+ for (i = 0; i < acl_size_info.AceCount; i++) {
+ void* ace;
+ ACCESS_ALLOWED_ACE *access;
+ SID* sid;
+
+ if (!GetAce(acl, i, &ace)) {
+ JNU_ThrowIOExceptionWithLastError(env, "GetAce failed");
+ return -1;
+ }
+ if (((ACCESS_ALLOWED_ACE *)ace)->Header.AceType != ACCESS_ALLOWED_ACE_TYPE) {
+ continue;
+ }
+ access = (ACCESS_ALLOWED_ACE *)ace;
+ sid = (SID *) &access->SidStart;
+ if (!EqualSid(owner, sid)) {
+ /*
+ * If the ACE allows any access then the file is not secure.
+ */
+ if (access->Mask & ANY_ACCESS) {
+ return JNI_FALSE;
+ }
+ }
+ }
+ return JNI_TRUE;
+}
+
+
+/*
+ * Class: jdk_internal_agent_FileSystemImpl
+ * Method: init0
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_jdk_internal_agent_FileSystemImpl_init0
+ (JNIEnv *env, jclass ignored)
+{
+ /* nothing to do */
+}
+
+/*
+ * Class: jdk_internal_agent_FileSystemImpl
+ * Method: isSecuritySupported0
+ * Signature: (Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jdk_internal_agent_FileSystemImpl_isSecuritySupported0
+ (JNIEnv *env, jclass ignored, jstring str)
+{
+ jboolean res;
+ jboolean isCopy;
+ const char* path;
+
+ path = JNU_GetStringPlatformChars(env, str, &isCopy);
+ if (path != NULL) {
+ res = isSecuritySupported(env, path);
+ if (isCopy) {
+ JNU_ReleaseStringPlatformChars(env, str, path);
+ }
+ return res;
+ } else {
+ /* exception thrown - doesn't matter what we return */
+ return JNI_TRUE;
+ }
+}
+
+
+/*
+ * Class: jdk_internal_agent_FileSystemImpl
+ * Method: isAccessUserOnly0
+ * Signature: (Ljava/lang/String;)Z
+ */
+JNIEXPORT jboolean JNICALL Java_jdk_internal_agent_FileSystemImpl_isAccessUserOnly0
+ (JNIEnv *env, jclass ignored, jstring str)
+{
+ jboolean res = JNI_FALSE;
+ jboolean isCopy;
+ const char* path;
+
+ path = JNU_GetStringPlatformChars(env, str, &isCopy);
+ if (path != NULL) {
+ /*
+ * From the security descriptor get the file owner and
+ * DACL. Then check if anybody but the owner has access
+ * to the file.
+ */
+ SECURITY_DESCRIPTOR* sd = getFileSecurityDescriptor(env, path);
+ if (sd != NULL) {
+ SID *owner = getFileOwner(env, sd);
+ if (owner != NULL) {
+ ACL* acl = getFileDACL(env, sd);
+ if (acl != NULL) {
+ res = isAccessUserOnly(env, owner, acl);
+ } else {
+ /*
+ * If acl is NULL it means that an exception was thrown
+ * or there is "all acess" to the file.
+ */
+ res = JNI_FALSE;
+ }
+ }
+ free(sd);
+ }
+ if (isCopy) {
+ JNU_ReleaseStringPlatformChars(env, str, path);
+ }
+ }
+ return res;
+}
--- a/jdk/test/com/sun/tools/attach/StartManagementAgent.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/com/sun/tools/attach/StartManagementAgent.java Thu Feb 02 21:55:34 2017 +0000
@@ -41,7 +41,7 @@
* @summary Test for VirtualMachine.startManagementAgent and VirtualMachine.startLocalManagementAgent
* @modules jdk.jartool/sun.tools.jar
* @library /lib/testlibrary
- * @modules java.management
+ * @modules jdk.management.agent
* jdk.attach
* jdk.jartool/sun.tools.jar
* @run build Application SimpleProvider jdk.testlibrary.*
--- a/jdk/test/java/net/HttpURLConnection/SetAuthenticator/HTTPSetAuthenticatorTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/java/net/HttpURLConnection/SetAuthenticator/HTTPSetAuthenticatorTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -32,11 +32,12 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
-/**
+/*
* @test
* @bug 8169415
* @library /lib/testlibrary/
- * @modules java.base/sun.net.www
+ * @modules java.logging
+ * java.base/sun.net.www
* java.base/sun.net.www.protocol.http
* jdk.httpserver/sun.net.httpserver
* @build jdk.testlibrary.SimpleSSLContext HTTPTest HTTPTestServer HTTPTestClient HTTPSetAuthenticatorTest
--- a/jdk/test/java/net/HttpURLConnection/SetAuthenticator/HTTPTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/java/net/HttpURLConnection/SetAuthenticator/HTTPTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, 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
@@ -43,11 +43,12 @@
import javax.net.ssl.SSLSession;
import jdk.testlibrary.SimpleSSLContext;
-/**
+/*
* @test
* @bug 8169415
* @library /lib/testlibrary/
- * @modules java.base/sun.net.www
+ * @modules java.logging
+ * java.base/sun.net.www
* jdk.httpserver/sun.net.httpserver
* @build jdk.testlibrary.SimpleSSLContext HTTPTest HTTPTestServer HTTPTestClient
* @summary A simple HTTP test that starts an echo server supporting Digest
--- a/jdk/test/java/net/ProxySelector/SystemProxies.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/java/net/ProxySelector/SystemProxies.java Thu Feb 02 21:55:34 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, 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,13 @@
*/
/*
- * This is a manual test to determine the proxies set on the system for various
- * protocols. See bug 6912868.
+ * @test
+ * @bug 6912868 8170868
+ * @summary Basic test to provide some coverage of system proxy code. Will
+ * always pass. Should be run manually for specific systems to inspect output.
+ * @run main/othervm -Djava.net.useSystemProxies=true SystemProxies
*/
+
import java.net.Proxy;
import java.net.ProxySelector;
import java.net.URI;
--- a/jdk/test/javax/management/MBeanInfo/NotificationInfoTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/MBeanInfo/NotificationInfoTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @summary Test that JMX classes use fully-qualified class names
* in MBeanNotificationInfo
* @author Eamonn McManus
- * @modules java.management
+ * @modules java.management.rmi
* @run clean NotificationInfoTest
* @run build NotificationInfoTest
* @run main NotificationInfoTest
--- a/jdk/test/javax/management/MBeanServer/ExceptionTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/MBeanServer/ExceptionTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 8058865
* @summary Checks that exceptions are correctly wired (compared to reference).
* @author Olivier Lagneau
- * @modules java.management
+ * @modules java.management.rmi
* @run main/othervm/timeout=300 -DDEBUG_STANDARD ExceptionTest
*/
@@ -368,5 +368,3 @@
}
}
-
-
--- a/jdk/test/javax/management/MBeanServer/OldMBeanServerTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/MBeanServer/OldMBeanServerTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -97,7 +97,7 @@
* @bug 5072268
* @summary Test that nothing assumes a post-1.2 MBeanServer
* @author Eamonn McManus
- * @modules java.management
+ * @modules java.management.rmi
* @run main/othervm -ea OldMBeanServerTest
*/
--- a/jdk/test/javax/management/modelmbean/UnserializableTargetObjectTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/modelmbean/UnserializableTargetObjectTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @summary Test that a RequiredModelMBean operation can have a targetObject
* that is not serializable
* @author Eamonn McManus
- * @modules java.management
+ * @modules java.management.rmi
* @run clean UnserializableTargetObjectTest
* @run build UnserializableTargetObjectTest
* @run main UnserializableTargetObjectTest
--- a/jdk/test/javax/management/mxbean/GenericArrayTypeTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/mxbean/GenericArrayTypeTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @summary Test support for arrays in parameterized types.
* @author Luis-Miguel Alventosa
* @key intermittent
- * @modules java.management
+ * @modules java.management.rmi
* @run clean GenericArrayTypeTest
* @run build GenericArrayTypeTest
* @run main GenericArrayTypeTest
--- a/jdk/test/javax/management/mxbean/MXBeanExceptionHandlingTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/mxbean/MXBeanExceptionHandlingTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 8058865
* @summary Checks correct exception and error events from NotificationListener
* @author Olivier Lagneau
- * @modules java.management
+ * @modules java.management.rmi
* @library /lib/testlibrary
* @compile Basic.java
* @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanExceptionHandlingTest -timeForNotificationInSeconds 3
--- a/jdk/test/javax/management/mxbean/MXBeanInteropTest1.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/mxbean/MXBeanInteropTest1.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 8058865
* @summary Test all MXBeans available by default on the platform
* @author Olivier Lagneau
- * @modules java.management
+ * @modules java.management.rmi
* @library /lib/testlibrary
* @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanInteropTest1
*/
--- a/jdk/test/javax/management/mxbean/MXBeanInteropTest2.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/mxbean/MXBeanInteropTest2.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 8058865
* @summary Checks access to test MXBean
* @author Olivier Lagneau
- * @modules java.management
+ * @modules java.management.rmi
* @library /lib/testlibrary
* @compile Basic.java
* @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanInteropTest2
--- a/jdk/test/javax/management/mxbean/MXBeanNotifTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/mxbean/MXBeanNotifTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 8058865
* @summary Checks MXBean proper registration both as its implementation class and interface
* @author Olivier Lagneau
- * @modules java.management
+ * @modules java.management.rmi
* @library /lib/testlibrary
* @compile Basic.java
* @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanNotifTest -numOfNotifications 239 -timeForNotificationInSeconds 4
--- a/jdk/test/javax/management/mxbean/MXBeanTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/mxbean/MXBeanTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @summary General MXBean test.
* @author Eamonn McManus
* @author Jaroslav Bachorik
- * @modules java.management
+ * @modules java.management.rmi
* @run clean MXBeanTest MerlinMXBean TigerMXBean
* @run build MXBeanTest MerlinMXBean TigerMXBean
* @run main MXBeanTest
--- a/jdk/test/javax/management/mxbean/MXBeanWeirdParamTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/mxbean/MXBeanWeirdParamTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @summary Checks that a serialized instance is not transmitted from an MXBean.
* All the communication should be done via Open Types
* @author Olivier Lagneau
- * @modules java.management
+ * @modules java.management.rmi
* @library /lib/testlibrary
* @compile Basic.java
* @run main/othervm/timeout=300 -DDEBUG_STANDARD MXBeanWeirdParamTest
--- a/jdk/test/javax/management/query/SupportedQueryTypesTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/query/SupportedQueryTypesTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 8058865
* @summary Tests most of the existing query types.
* @author Olivier Lagneau
- * @modules java.management
+ * @modules java.management.rmi
* @compile TestQuery.java
* @run main/othervm/timeout=300 -DDEBUG_STANDARD SupportedQueryTypesTest -mbeanClassName TestQuery
*/
--- a/jdk/test/javax/management/remote/mandatory/connection/AddressableTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connection/AddressableTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 6238815
* @summary test the new interface Addressable
* @author Shanliang JIANG
- * @modules java.management
+ * @modules java.management.rmi
* @run clean AddressableTest
* @run build AddressableTest
* @run main AddressableTest
--- a/jdk/test/javax/management/remote/mandatory/connection/BrokenConnectionTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connection/BrokenConnectionTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @summary Tests behaviour when connections break
* @author Eamonn McManus
* @key intermittent
- * @modules java.management
+ * @modules java.management.rmi
* @run clean BrokenConnectionTest
* @run build BrokenConnectionTest
* @run main BrokenConnectionTest
--- a/jdk/test/javax/management/remote/mandatory/connection/CloseableTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connection/CloseableTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -28,7 +28,7 @@
* the method "void close() throws IOException;" extend
* or implement the java.io.Closeable interface.
* @author Luis-Miguel Alventosa
- * @modules java.management
+ * @modules java.management.rmi
* @run clean CloseableTest
* @run build CloseableTest
* @run main CloseableTest
--- a/jdk/test/javax/management/remote/mandatory/connection/ConnectionListenerNullTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connection/ConnectionListenerNullTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 4943248
* @summary Tests that NullPointerException is thrown when listener is null.
* @author Daniel Fuchs
- * @modules java.management
+ * @modules java.management.rmi
* @run clean ConnectionListenerNullTest
* @run build ConnectionListenerNullTest
* @run main ConnectionListenerNullTest
--- a/jdk/test/javax/management/remote/mandatory/connection/ConnectionTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connection/ConnectionTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 4865397
* @summary Tests remote JMX connections
* @author Eamonn McManus
- * @modules java.management
+ * @modules java.management.rmi
* @run clean ConnectionTest
* @run build ConnectionTest
* @run main ConnectionTest
--- a/jdk/test/javax/management/remote/mandatory/connection/DaemonRMIExporterTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connection/DaemonRMIExporterTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -28,7 +28,7 @@
* @summary test the connector server option that causes it not to prevent the
* VM from exiting
* @author Shanliang JIANG, Eamonn McManus
- * @modules java.management
+ * @modules java.management.rmi
* @run main/othervm DaemonRMIExporterTest
*/
import java.util.Arrays;
--- a/jdk/test/javax/management/remote/mandatory/connection/GetConnectionTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connection/GetConnectionTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 4951414
* @summary Try to get an IOException.
* @author Shanliang JIANG
- * @modules java.management
+ * @modules java.management.rmi
* @run clean GetConnectionTest
* @run build GetConnectionTest
* @run main GetConnectionTest
--- a/jdk/test/javax/management/remote/mandatory/connection/IIOPURLTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connection/IIOPURLTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 4886799
* @summary Check that IIOP URLs have /ior/ in the path
* @author Eamonn McManus
- * @modules java.management
+ * @modules java.management.rmi
* @run clean IIOPURLTest
* @run build IIOPURLTest
* @run main IIOPURLTest
--- a/jdk/test/javax/management/remote/mandatory/connection/IdleTimeoutTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connection/IdleTimeoutTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,8 @@
* @bug 4886838 4886830 8025204
* @summary Tests that idle timeouts happen at appropriate times
* @author Eamonn McManus
- * @modules java.management/com.sun.jmx.remote.util
+ * @modules java.management.rmi
+ * java.management/com.sun.jmx.remote.util
* @run clean IdleTimeoutTest
* @run build IdleTimeoutTest
* @run main IdleTimeoutTest
--- a/jdk/test/javax/management/remote/mandatory/connection/MultiThreadDeadLockTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connection/MultiThreadDeadLockTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -45,7 +45,7 @@
* @bug 6697180
* @summary test on a client notification deadlock.
* @author Shanliang JIANG
- * @modules java.management
+ * @modules java.management.rmi
* @run clean MultiThreadDeadLockTest
* @run build MultiThreadDeadLockTest
* @run main MultiThreadDeadLockTest
--- a/jdk/test/javax/management/remote/mandatory/connection/ObjectInputStreamWithLoaderNullCheckTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connection/ObjectInputStreamWithLoaderNullCheckTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -29,7 +29,7 @@
* thrown when constructor is invoked with null class loader as
* an argument.
* @author Amit Sapre
- * @modules java.management/javax.management.remote.rmi:open
+ * @modules java.management.rmi/javax.management.remote.rmi:open
* @run clean ObjectInputStreamWithLoaderNullCheckTest
* @run build ObjectInputStreamWithLoaderNullCheckTest
* @run main ObjectInputStreamWithLoaderNullCheckTest
--- a/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorInternalMapTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -42,7 +42,7 @@
* @bug 6566891
* @summary Check no memory leak on RMIConnector's rmbscMap
* @author Shanliang JIANG
- * @modules java.management/javax.management.remote.rmi:open
+ * @modules java.management.rmi/javax.management.remote.rmi:open
* @run clean RMIConnectorInternalMapTest
* @run build RMIConnectorInternalMapTest
* @run main RMIConnectorInternalMapTest
--- a/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connection/RMIConnectorNullSubjectConnTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -38,7 +38,7 @@
* @bug 6566891
* @summary Check no memory leak on RMIConnector's nullSubjectConn
* @author Shanliang JIANG
- * @modules java.management/javax.management.remote.rmi:open
+ * @modules java.management.rmi/javax.management.remote.rmi:open
* @run clean RMIConnectorNullSubjectConnTest
* @run build RMIConnectorNullSubjectConnTest
* @run main RMIConnectorNullSubjectConnTest
--- a/jdk/test/javax/management/remote/mandatory/connection/RMIConnector_NPETest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connection/RMIConnector_NPETest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @summary NPE IN RMIConnector.connect
* @bug 6984520
* @library /java/rmi/testlibrary
- * @modules java.management
+ * @modules java.management.rmi
* java.rmi/sun.rmi.registry
* java.rmi/sun.rmi.server
* java.rmi/sun.rmi.transport
@@ -75,4 +75,3 @@
}
}
-
--- a/jdk/test/javax/management/remote/mandatory/connection/RMIExitTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connection/RMIExitTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @bug 4917237
* @summary test that process exit immediately after stop() / close() called
* @author Jean Francois Denise
- * @modules java.management
+ * @modules java.management.rmi
* @run clean RMIExitTest
* @run build RMIExitTest
* @run main RMIExitTest
--- a/jdk/test/javax/management/remote/mandatory/connection/RMISerializeTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connection/RMISerializeTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @summary Tests to serialize RMIConnector
* @bug 5032052
* @author Shanliang JIANG
- * @modules java.management
+ * @modules java.management.rmi
* @run clean RMISerializeTest
* @run build RMISerializeTest
* @run main RMISerializeTest
--- a/jdk/test/javax/management/remote/mandatory/connectorServer/ConnectorStopDeadlockTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connectorServer/ConnectorStopDeadlockTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 6475157
* @summary Tests deadlock in simultaneous connection and connector-server close
* @author Eamonn McManus
- * @modules java.management
+ * @modules java.management.rmi
*/
/* This test is somewhat dependent on implementation details. If it suddenly
--- a/jdk/test/javax/management/remote/mandatory/connectorServer/JNDIFailureTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connectorServer/JNDIFailureTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @summary Tests that JNDI bind failure doesn't leave an orphan RMI
* Connector Server object
* @author Eamonn McManus
- * @modules java.management
+ * @modules java.management.rmi
* @run clean JNDIFailureTest
* @run build JNDIFailureTest
* @run main JNDIFailureTest
--- a/jdk/test/javax/management/remote/mandatory/connectorServer/MBSFPreStartPostStartTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connectorServer/MBSFPreStartPostStartTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @summary Test that setting an MBeanServerForwarder on an already
* started RMI connector server has the expected behavior.
* @author Luis-Miguel Alventosa
- * @modules java.management
+ * @modules java.management.rmi
* @run clean MBSFPreStartPostStartTest
* @run build MBSFPreStartPostStartTest
* @run main MBSFPreStartPostStartTest
--- a/jdk/test/javax/management/remote/mandatory/connectorServer/RMIExporterTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connectorServer/RMIExporterTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 5016705
* @summary Tests the use of the RMIExporter class.
* @author Luis-Miguel Alventosa
- * @modules java.management/com.sun.jmx.remote.internal
+ * @modules java.management.rmi/com.sun.jmx.remote.internal.rmi
* @run clean RMIExporterTest
* @run build RMIExporterTest
* @run main RMIExporterTest
@@ -46,7 +46,7 @@
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;
-import com.sun.jmx.remote.internal.RMIExporter;
+import com.sun.jmx.remote.internal.rmi.RMIExporter;
public class RMIExporterTest {
--- a/jdk/test/javax/management/remote/mandatory/connectorServer/SetMBeanServerForwarder.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/connectorServer/SetMBeanServerForwarder.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,8 @@
* @summary Tests that IllegalArgumentException is thrown when
* MBeanServerForwrder is null.
* @author Daniel Fuchs
- * @modules java.management/com.sun.jmx.remote.security
+ * @modules java.management.rmi
+ * java.management/com.sun.jmx.remote.security
* @run clean SetMBeanServerForwarder
* @run build SetMBeanServerForwarder
* @run main SetMBeanServerForwarder
--- a/jdk/test/javax/management/remote/mandatory/loading/DeserializeEncodedURLTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/loading/DeserializeEncodedURLTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 4924683
* @summary Check RMI/JRMP stubs can be deserialized using user's loader
* @author Eamonn McManus
- * @modules java.management
+ * @modules java.management.rmi
* @run clean DeserializeEncodedURLTest SingleClassLoader
* @run build DeserializeEncodedURLTest SingleClassLoader
* @run main DeserializeEncodedURLTest
--- a/jdk/test/javax/management/remote/mandatory/loading/MissingClassTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/loading/MissingClassTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 4915825 4921009 4934965 4977469 8019584
* @summary Tests behavior when client or server gets object of unknown class
* @author Eamonn McManus
- * @modules java.management
+ * @modules java.management.rmi
* @run clean MissingClassTest SingleClassLoader
* @run build MissingClassTest SingleClassLoader
* @run main MissingClassTest
--- a/jdk/test/javax/management/remote/mandatory/loading/RMIDownloadTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/loading/RMIDownloadTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 5021246
* @summary Check that class downloading is supported by RMI connector
* @author Eamonn McManus
- * @modules java.management
+ * @modules java.management.rmi
* @run main RMIDownloadTest receive without
* @run main RMIDownloadTest send without
* @run main RMIDownloadTest receive with
--- a/jdk/test/javax/management/remote/mandatory/loading/TargetMBeanTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/loading/TargetMBeanTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 4910428
* @summary Tests target MBean class loader used before JSR 160 loader
* @author Eamonn McManus
- * @modules java.management
+ * @modules java.management.rmi
* @run clean TargetMBeanTest
* @run build TargetMBeanTest
* @run main TargetMBeanTest
--- a/jdk/test/javax/management/remote/mandatory/notif/ConcurrentModificationTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/notif/ConcurrentModificationTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 7120365
* @summary test on Concurrent Modification
* @author Shanliang JIANG
- * @modules java.management
+ * @modules java.management.rmi
* @run main ConcurrentModificationTest
*/
--- a/jdk/test/javax/management/remote/mandatory/notif/DeadListenerTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/notif/DeadListenerTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -25,7 +25,7 @@
* @test
* @bug 6957378
* @summary Test that a listener can be removed remotely from an MBean that no longer exists.
- * @modules java.management/javax.management.remote.rmi:open
+ * @modules java.management.rmi/javax.management.remote.rmi:open
* java.management/com.sun.jmx.remote.internal:+open
* @author Eamonn McManus
* @run main/othervm -XX:+UsePerfData DeadListenerTest
--- a/jdk/test/javax/management/remote/mandatory/notif/EmptyDomainNotificationTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/notif/EmptyDomainNotificationTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @summary Check that the expected notification is received by the JMX
* client even when the domain in the ObjectName is not specified
* @author Shanliang JIANG
- * @modules java.management
+ * @modules java.management.rmi
* @run clean EmptyDomainNotificationTest
* @run build EmptyDomainNotificationTest
* @run main EmptyDomainNotificationTest
--- a/jdk/test/javax/management/remote/mandatory/notif/ListenerScaleTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/notif/ListenerScaleTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 6338874
* @summary Check that notification dispatch is not linear in number of MBeans.
* @author Eamonn McManus
- * @modules java.management
+ * @modules java.management.rmi
*
* @library /lib/testlibrary
* @run build jdk.testlibrary.* ListenerScaleTest
--- a/jdk/test/javax/management/remote/mandatory/notif/NotSerializableNotifTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/notif/NotSerializableNotifTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @summary Tests to send a not serializable notification.
* @bug 5022196 8132003
* @author Shanliang JIANG
- * @modules java.management
+ * @modules java.management.rmi
* @run clean NotSerializableNotifTest
* @run build NotSerializableNotifTest
* @run main NotSerializableNotifTest
--- a/jdk/test/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/notif/NotifReconnectDeadlockTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 6199899
* @summary Tests reconnection done by a fetching notif thread.
* @author Shanliang JIANG
- * @modules java.management
+ * @modules java.management.rmi
* @run clean NotifReconnectDeadlockTest
* @run build NotifReconnectDeadlockTest
* @run main NotifReconnectDeadlockTest
--- a/jdk/test/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/notif/NotificationAccessControllerTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,8 @@
* @bug 5106721
* @summary Check the NotificationAccessController methods are properly called.
* @author Luis-Miguel Alventosa
- * @modules java.management/com.sun.jmx.remote.security
+ * @modules java.management.rmi
+ * java.management/com.sun.jmx.remote.security
* @run clean NotificationAccessControllerTest
* @run build NotificationAccessControllerTest
* @run main NotificationAccessControllerTest
--- a/jdk/test/javax/management/remote/mandatory/notif/NotificationBufferCreationTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/notif/NotificationBufferCreationTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 4934236
* @summary Tests that NotificationBuffer is created when used.
* @author jfd@...
- * @modules java.management
+ * @modules java.management.rmi
* @run clean NotificationBufferCreationTest NotificationSender
* @run build NotificationBufferCreationTest
* @run main NotificationBufferCreationTest
--- a/jdk/test/javax/management/remote/mandatory/notif/NotificationEmissionTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/notif/NotificationEmissionTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -28,7 +28,7 @@
* installed. Test the property "jmx.remote.x.check.notification.emission".
* @author Luis-Miguel Alventosa
* @key intermittent
- * @modules java.management
+ * @modules java.management.rmi
* @run clean NotificationEmissionTest
* @run build NotificationEmissionTest
* @run main NotificationEmissionTest 1
--- a/jdk/test/javax/management/remote/mandatory/notif/RMINotifTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/notif/RMINotifTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @summary Tests to receive notifications for opened and closed connections
ions
* @author sjiang
- * @modules java.management
+ * @modules java.management.rmi
* @run clean RMINotifTest
* @run build RMINotifTest
* @run main RMINotifTest
--- a/jdk/test/javax/management/remote/mandatory/notif/ServerNotifs.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/notif/ServerNotifs.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @summary Tests the reception of the notifications for opened and closed
* connections
* @author sjiang
- * @modules java.management
+ * @modules java.management.rmi
* @run clean ServerNotifs
* @run build ServerNotifs
* @run main ServerNotifs
--- a/jdk/test/javax/management/remote/mandatory/notif/UnexpectedNotifTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/notif/UnexpectedNotifTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @summary Tests whether a listener receives notifs emitted before the
* listener is registered.
* @author Shanliang JIANG
- * @modules java.management
+ * @modules java.management.rmi
* @run clean UnexpectedNotifTest
* @run build UnexpectedNotifTest
* @run main UnexpectedNotifTest
--- a/jdk/test/javax/management/remote/mandatory/passwordAccessFile/NonJMXPrincipalsTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/passwordAccessFile/NonJMXPrincipalsTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @summary Tests that MBeanServerFileAccessController supports
* principals other than JMXPrincipal.
* @author Luis-Miguel Alventosa
- * @modules java.management
+ * @modules java.management.rmi
* @run clean NonJMXPrincipalsTest SimpleStandard SimpleStandardMBean
* @run build NonJMXPrincipalsTest SimpleStandard SimpleStandardMBean
* @run main NonJMXPrincipalsTest
--- a/jdk/test/javax/management/remote/mandatory/passwordAccessFile/PasswordAccessFileTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/passwordAccessFile/PasswordAccessFileTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @summary Tests the use of the "jmx.remote.x.password.file" and
* "jmx.remote.x.access.file" environment map properties.
* @author Luis-Miguel Alventosa
- * @modules java.management
+ * @modules java.management.rmi
* @run clean PasswordAccessFileTest SimpleStandard SimpleStandardMBean
* @run build PasswordAccessFileTest SimpleStandard SimpleStandardMBean
* @run main PasswordAccessFileTest
--- a/jdk/test/javax/management/remote/mandatory/passwordAuthenticator/RMIAltAuthTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/passwordAuthenticator/RMIAltAuthTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,8 @@
* @bug 5016508
* @summary Supplies an alternative JAAS configuration for authenticating RMI clients
* @author Luis-Miguel Alventosa
- * @modules java.management/com.sun.jmx.remote.security
+ * @modules java.management.rmi
+ * java.management/com.sun.jmx.remote.security
* @run clean RMIAltAuthTest
* @run build RMIAltAuthTest SimpleStandard SimpleStandardMBean
* @run main RMIAltAuthTest
--- a/jdk/test/javax/management/remote/mandatory/passwordAuthenticator/RMIPasswdAuthTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/passwordAuthenticator/RMIPasswdAuthTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,8 @@
* @bug 5016508
* @summary Tests the default JAAS configuration for authenticating RMI clients
* @author Luis-Miguel Alventosa
- * @modules java.management/com.sun.jmx.remote.security
+ * @modules java.management.rmi
+ * java.management/com.sun.jmx.remote.security
* @run clean RMIPasswdAuthTest
* @run build RMIPasswdAuthTest SimpleStandard SimpleStandardMBean
* @run main RMIPasswdAuthTest
--- a/jdk/test/javax/management/remote/mandatory/provider/ProviderTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/provider/ProviderTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -24,7 +24,7 @@
/*
* @test ProviderTest.java
* @summary Tests jar services provider are called
- * @modules java.management
+ * @modules java.management.rmi
* @run clean ProviderTest provider.JMXConnectorProviderImpl provider.JMXConnectorServerProviderImpl
* @run build ProviderTest provider.JMXConnectorProviderImpl provider.JMXConnectorServerProviderImpl
* @run main ProviderTest
--- a/jdk/test/javax/management/remote/mandatory/serverError/JMXServerErrorTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/serverError/JMXServerErrorTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,8 @@
* @bug 4871761
* @summary Tests that JMXServiceErrorException is correctly emitted.
* @author Daniel Fuchs
- * @modules java.management/com.sun.jmx.remote.security
+ * @modules java.management.rmi
+ * java.management/com.sun.jmx.remote.security
* @run clean JMXServerErrorTest
* @run build JMXServerErrorTest
* @run main JMXServerErrorTest
--- a/jdk/test/javax/management/remote/mandatory/socketFactories/RMISocketFactoriesTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/socketFactories/RMISocketFactoriesTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 7654321
* @summary Tests the use of the custom RMI socket factories.
* @author Luis-Miguel Alventosa
- * @modules java.management
+ * @modules java.management.rmi
* @run clean RMISocketFactoriesTest
* @run build RMISocketFactoriesTest RMIClientFactory RMIServerFactory
* @run main RMISocketFactoriesTest test_server_factory
--- a/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation1Test.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation1Test.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,8 @@
* @summary Tests the use of the subject delegation feature in the
* RMI connector
* @author Luis-Miguel Alventosa
- * @modules java.management/com.sun.jmx.remote.security
+ * @modules java.management.rmi
+ * java.management/com.sun.jmx.remote.security
* @run clean SubjectDelegation1Test SimpleStandard SimpleStandardMBean
* @run build SubjectDelegation1Test SimpleStandard SimpleStandardMBean
* @run main SubjectDelegation1Test policy11 ok
--- a/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation2Test.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation2Test.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,8 @@
* @summary Tests the use of the subject delegation feature on the authenticated
* principals within the RMI connector server's creator codebase.
* @author Luis-Miguel Alventosa
- * @modules java.management/com.sun.jmx.remote.security
+ * @modules java.management.rmi
+ * java.management/com.sun.jmx.remote.security
* @run clean SubjectDelegation2Test SimpleStandard SimpleStandardMBean
* @run build SubjectDelegation2Test SimpleStandard SimpleStandardMBean
* @run main SubjectDelegation2Test policy21 ok
--- a/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation3Test.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/subjectDelegation/SubjectDelegation3Test.java Thu Feb 02 21:55:34 2017 +0000
@@ -28,7 +28,8 @@
* principals within the RMI connector server's creator codebase with
* subject delegation.
* @author Luis-Miguel Alventosa
- * @modules java.management/com.sun.jmx.remote.security
+ * @modules java.management.rmi
+ * java.management/com.sun.jmx.remote.security
* @run clean SubjectDelegation3Test SimpleStandard SimpleStandardMBean
* @run build SubjectDelegation3Test SimpleStandard SimpleStandardMBean
* @run main SubjectDelegation3Test policy31 ok
--- a/jdk/test/javax/management/remote/mandatory/util/MapNullValuesTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/remote/mandatory/util/MapNullValuesTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -31,7 +31,8 @@
* Check also that null values for keys are not allowed in
* the maps passed to the JMXConnector[Server] factories.
* @author Luis-Miguel Alventosa
- * @modules java.management/com.sun.jmx.remote.util
+ * @modules java.management.rmi
+ * java.management/com.sun.jmx.remote.util
* @run clean MapNullValuesTest
* @run build MapNullValuesTest
* @run main MapNullValuesTest
--- a/jdk/test/javax/management/security/AuthorizationTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/security/AuthorizationTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 8058865
* @summary Checks various authentication behavior from remote jmx client
* @author Olivier Lagneau
- * @modules java.management
+ * @modules java.management.rmi
* @library /lib/testlibrary
* @compile Simple.java
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=username1 -Dpassword=password1 AuthorizationTest -server -mapType x.access.file;x.password.file -populate -client -mapType credentials
--- a/jdk/test/javax/management/security/SecurityTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/javax/management/security/SecurityTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -26,7 +26,7 @@
* @bug 8058865
* @summary Checks various secure ways of connecting from remote jmx client
* @author Olivier Lagneau
- * @modules java.management
+ * @modules java.management.rmi
* @library /lib/testlibrary
* @compile MBS_Light.java ServerDelegate.java TestSampleLoginModule.java
* @run main/othervm/timeout=300 -DDEBUG_STANDARD -Dusername=SQE_username -Dpassword=SQE_password SecurityTest -server -mapType x.password.file -client -mapType credentials
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/internal/agent/AgentCMETest.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/**
+ * @test
+ * @bug 7164191
+ * @summary properties.putAll API may fail with ConcurrentModifcationException on multi-thread scenario
+ * @modules jdk.management.agent/jdk.internal.agent
+ * @author Deven You
+ */
+
+import java.util.Properties;
+import jdk.internal.agent.Agent;
+
+public class AgentCMETest {
+ static Class<?> agentClass;
+
+ /**
+ * In jdk.internal.agent.Agent.loadManagementProperties(), call
+ * properties.putAll API may fail with ConcurrentModifcationException if the
+ * system properties are modified simultaneously by another thread
+ *
+ * @param args
+ * @throws Exception
+ */
+ public static void main(String[] args) throws Exception {
+ System.out.println("Start...");
+
+ final Properties properties = System.getProperties();
+ Thread t1 = new Thread(new Runnable() {
+ public void run() {
+ for (int i = 0; i < 100; i++) {
+ properties.put(String.valueOf(i), "");
+ try {
+ Thread.sleep(1);
+ } catch (InterruptedException e) {
+ // do nothing
+ }
+ }
+ }
+ });
+ t1.start();
+
+ for (int i = 0; i < 10000; i++) {
+ Agent.loadManagementProperties();
+ }
+
+ System.out.println("Finished...");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/internal/agent/AgentCheckTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,62 @@
+/*
+ * 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
+ * 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 5013605
+ * @summary Localize log messages from the management agents
+ * @modules jdk.management.agent/jdk.internal.agent
+ *
+ * @author Tim Bell
+ */
+import jdk.internal.agent.Agent;
+
+public class AgentCheckTest {
+
+ public static void main(String[] args){
+ String [][] testStrings = {
+ {"agent.err.error", "", ""},
+ {"jmxremote.ConnectorBootstrap.starting", "", ""},
+ {"jmxremote.ConnectorBootstrap.noAuthentication", "", ""},
+ {"jmxremote.ConnectorBootstrap.ready", "Phony JMXServiceURL", ""},
+ {"jmxremote.ConnectorBootstrap.password.readonly", "Phony passwordFileName", ""},
+ };
+
+ boolean pass = true;
+ System.out.println("Start...");
+ for (int ii = 0; ii < testStrings.length; ii++) {
+ String key = testStrings[ii][0];
+ String p1 = testStrings[ii][1];
+ String p2 = testStrings[ii][2];
+ String ss = Agent.getText(key, p1, p2);
+ if (ss.startsWith("missing resource key")) {
+ pass = false;
+ System.out.println(" lookup failed for key = " + key);
+ }
+ }
+ if (!pass) {
+ throw new Error ("Resource lookup(s) failed; Test failed");
+ }
+ System.out.println("...Finished.");
+ }
+}
--- a/jdk/test/sun/management/AgentCMETest.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +0,0 @@
-/*
- * Copyright (c) 2012, 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.
- */
-
-/*
- * Portions Copyright (c) 2012 IBM Corporation
- */
-
-/**
- * @test
- * @bug 7164191
- * @summary properties.putAll API may fail with ConcurrentModifcationException on multi-thread scenario
- * @modules java.management/sun.management
- * @author Deven You
- */
-
-import java.util.Properties;
-import sun.management.Agent;
-
-public class AgentCMETest {
- static Class<?> agentClass;
-
- /**
- * In sun.management.Agent.loadManagementProperties(), call
- * properties.putAll API may fail with ConcurrentModifcationException if the
- * system properties are modified simultaneously by another thread
- *
- * @param args
- * @throws Exception
- */
- public static void main(String[] args) throws Exception {
- System.out.println("Start...");
-
- final Properties properties = System.getProperties();
- Thread t1 = new Thread(new Runnable() {
- public void run() {
- for (int i = 0; i < 100; i++) {
- properties.put(String.valueOf(i), "");
- try {
- Thread.sleep(1);
- } catch (InterruptedException e) {
- // do nothing
- }
- }
- }
- });
- t1.start();
-
- for (int i = 0; i < 10000; i++) {
- Agent.loadManagementProperties();
- }
-
- System.out.println("Finished...");
- }
-}
--- a/jdk/test/sun/management/AgentCheckTest.java Thu Feb 02 21:20:38 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * 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
- * 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 5013605
- * @summary Localize log messages from the management agents
- * @modules java.management/sun.management
- *
- * @author Tim Bell
- */
-import sun.management.Agent;
-
-public class AgentCheckTest {
-
- public static void main(String[] args){
- String [][] testStrings = {
- {"agent.err.error", "", ""},
- {"jmxremote.ConnectorBootstrap.starting", "", ""},
- {"jmxremote.ConnectorBootstrap.noAuthentication", "", ""},
- {"jmxremote.ConnectorBootstrap.ready", "Phony JMXServiceURL", ""},
- {"jmxremote.ConnectorBootstrap.password.readonly", "Phony passwordFileName", ""},
- };
-
- boolean pass = true;
- System.out.println("Start...");
- for (int ii = 0; ii < testStrings.length; ii++) {
- String key = testStrings[ii][0];
- String p1 = testStrings[ii][1];
- String p2 = testStrings[ii][2];
- String ss = Agent.getText(key, p1, p2);
- if (ss.startsWith("missing resource key")) {
- pass = false;
- System.out.println(" lookup failed for key = " + key);
- }
- }
- if (!pass) {
- throw new Error ("Resource lookup(s) failed; Test failed");
- }
- System.out.println("...Finished.");
- }
-}
--- a/jdk/test/sun/management/jdp/JdpDefaultsTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jdp/JdpDefaultsTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -31,7 +31,7 @@
* @test JdpDefaultsTest
* @summary Assert that we can read JDP packets from a multicast socket connection, on default IP and port.
* @library /lib/testlibrary
- * @modules java.management/sun.management.jdp
+ * @modules jdk.management.agent/sun.management.jdp
* @build jdk.testlibrary.* ClientConnection JdpTestUtil JdpTestCase JdpOnTestCase DynamicLauncher
* @run main JdpDefaultsTest
*/
--- a/jdk/test/sun/management/jdp/JdpOffTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jdp/JdpOffTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -32,7 +32,7 @@
* @test JdpOffTest.java
* @summary Assert that no JDP packets are sent to the default address and port.
* @library /lib/testlibrary
- * @modules java.management/sun.management.jdp
+ * @modules jdk.management.agent/sun.management.jdp
* @build jdk.testlibrary.* ClientConnection JdpTestUtil JdpTestCase JdpOffTestCase DynamicLauncher
* @run main JdpOffTest
*/
--- a/jdk/test/sun/management/jdp/JdpSpecificAddressTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jdp/JdpSpecificAddressTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -31,7 +31,7 @@
* @test JdpSpecificAddressTest
* @summary Assert that we can read JDP packets from a multicast socket connection, on specific IP and port.
* @library /lib/testlibrary
- * @modules java.management/sun.management.jdp
+ * @modules jdk.management.agent/sun.management.jdp
* @build jdk.testlibrary.* ClientConnection JdpTestUtil JdpTestCase JdpOnTestCase DynamicLauncher
* @run main JdpSpecificAddressTest
*/
--- a/jdk/test/sun/management/jmxremote/LocalRMIServerSocketFactoryTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/LocalRMIServerSocketFactoryTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -28,7 +28,7 @@
*
* @author Daniel Fuchs
*
- * @modules java.management/sun.management.jmxremote
+ * @modules jdk.management.agent/sun.management.jmxremote
* @run compile -XDignore.symbol.file=true -g LocalRMIServerSocketFactoryTest.java
* @run main LocalRMIServerSocketFactoryTest
*/
--- a/jdk/test/sun/management/jmxremote/bootstrap/CustomLauncherTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/bootstrap/CustomLauncherTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -41,8 +41,7 @@
* @test
* @bug 6434402 8004926
* @library /lib/testlibrary
- * @modules java.management/sun.management
- * java.management
+ * @modules jdk.management.agent/jdk.internal.agent
* @build jdk.testlibrary.*
* @build TestManager TestApplication CustomLauncherTest
* @run main/othervm CustomLauncherTest
@@ -147,7 +146,7 @@
ProcessBuilder client = ProcessTools.createJavaProcessBuilder(
"-cp",
TEST_CLASSPATH,
- "--add-exports", "java.management/sun.management=ALL-UNNAMED",
+ "--add-exports", "jdk.management.agent/jdk.internal.agent=ALL-UNNAMED",
"TestManager",
String.valueOf(serverPrc.getPid()),
port.get(),
--- a/jdk/test/sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/bootstrap/JMXInterfaceBindingTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -48,8 +48,8 @@
* @summary Test JMX agent host address binding. Same ports but different
* interfaces to bind to (using plain sockets and SSL sockets).
*
- * @modules java.management/sun.management
- * java.management/sun.management.jmxremote
+ * @modules jdk.management.agent/jdk.internal.agent
+ * jdk.management.agent/sun.management.jmxremote
* @library /lib/testlibrary
* @build jdk.testlibrary.* JMXAgentInterfaceBinding
* @run main/timeout=5 JMXInterfaceBindingTest
--- a/jdk/test/sun/management/jmxremote/bootstrap/JvmstatCountersTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/bootstrap/JvmstatCountersTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @summary Tests that the jvmstat counters published by the out-of-the-box
* management agent for the JMX connection details are correct.
* @author Luis-Miguel Alventosa
- * @modules java.management/sun.management
+ * @modules jdk.management.agent/jdk.internal.agent
* @run clean JvmstatCountersTest
* @run build JvmstatCountersTest
* @run main/othervm/timeout=600 -XX:+UsePerfData JvmstatCountersTest 1
@@ -42,7 +42,7 @@
import javax.management.*;
import javax.management.remote.*;
import com.sun.tools.attach.*;
-import sun.management.ConnectorAddressLink;
+import jdk.internal.agent.ConnectorAddressLink;
public class JvmstatCountersTest {
--- a/jdk/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/bootstrap/LocalManagementTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -38,7 +38,7 @@
* without connection or username/password details.
* TestManager will attempt a connection to the address obtained from
* both agent properties and jvmstat buffer.
- * @modules java.management/sun.management
+ * @modules jdk.management.agent/jdk.internal.agent
* @build jdk.testlibrary.* TestManager TestApplication
* @run main/othervm/timeout=300 LocalManagementTest
*/
@@ -131,7 +131,7 @@
ProcessBuilder client = ProcessTools.createJavaProcessBuilder(
"-cp",
TEST_CLASSPATH,
- "--add-exports", "java.management/sun.management=ALL-UNNAMED",
+ "--add-exports", "jdk.management.agent/jdk.internal.agent=ALL-UNNAMED",
"TestManager",
String.valueOf(serverPrc.getPid()),
port.get(),
--- a/jdk/test/sun/management/jmxremote/bootstrap/PasswordFilePermissionTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/bootstrap/PasswordFilePermissionTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -28,7 +28,7 @@
* @library /lib/testlibrary
* @bug 6557093
* @summary Check SSL config file permission for out-of-the-box management
- * @modules java.management
+ * @modules jdk.management.agent
* @build jdk.testlibrary.* AbstractFilePermissionTest Dummy
* @run main/timeout=300 PasswordFilePermissionTest
*
--- a/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -40,7 +40,7 @@
import javax.management.remote.*;
import javax.management.*;
-import sun.management.AgentConfigurationError;
+import jdk.internal.agent.AgentConfigurationError;
import java.security.Security;
--- a/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh Thu Feb 02 21:55:34 2017 +0000
@@ -28,9 +28,8 @@
#
# @key intermittent
# @library /lib/testlibrary
-# @modules java.management/sun.management
-# java.management/sun.management.jmxremote
-# java.management
+# @modules jdk.management.agent/jdk.internal.agent
+# jdk.management.agent/sun.management.jmxremote
# @build jdk.testlibrary.* TestLogger Utils RmiBootstrapTest
# @run shell/timeout=300 RmiBootstrapTest.sh
@@ -51,8 +50,8 @@
DEBUGOPTIONS=""
export DEBUGOPTIONS
-EXTRAOPTIONS="--add-exports java.management/sun.management=ALL-UNNAMED \
- --add-exports java.management/sun.management.jmxremote=ALL-UNNAMED"
+EXTRAOPTIONS="--add-exports jdk.management.agent/jdk.internal.agent=ALL-UNNAMED \
+ --add-exports jdk.management.agent/sun.management.jmxremote=ALL-UNNAMED"
export EXTRAOPTIONS
# Call the common generic test
--- a/jdk/test/sun/management/jmxremote/bootstrap/RmiRegistrySslTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiRegistrySslTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -42,7 +42,7 @@
* @library /lib/testlibrary
* @bug 6228231
* @summary Test that RMI registry uses SSL.
- * @modules java.management
+ * @modules jdk.management.agent
* @build jdk.testlibrary.* RmiRegistrySslTestApp
* @run main/timeout=300 RmiRegistrySslTest
* @author Luis-Miguel Alventosa, Taras Ledkov
--- a/jdk/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh Thu Feb 02 21:55:34 2017 +0000
@@ -27,8 +27,8 @@
# @summary Test RMI Bootstrap with SSL
#
# @library /lib/testlibrary
-# @modules java.management/sun.management
-# java.management/sun.management.jmxremote
+# @modules jdk.management.agent/jdk.internal.agent
+# jdk.management.agent/sun.management.jmxremote
# @build jdk.testlibrary.* TestLogger Utils RmiBootstrapTest
# @run shell/timeout=300 RmiSslBootstrapTest.sh
@@ -49,8 +49,8 @@
DEBUGOPTIONS=""
export DEBUGOPTIONS
-EXTRAOPTIONS="--add-exports java.management/sun.management=ALL-UNNAMED \
- --add-exports java.management/sun.management.jmxremote=ALL-UNNAMED"
+EXTRAOPTIONS="--add-exports jdk.management.agent/jdk.internal.agent=ALL-UNNAMED \
+ --add-exports jdk.management.agent/sun.management.jmxremote=ALL-UNNAMED"
export EXTRAOPTIONS
# Call the common generic test
--- a/jdk/test/sun/management/jmxremote/bootstrap/RmiSslNoKeyStoreTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiSslNoKeyStoreTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -43,7 +43,7 @@
import javax.management.remote.*;
import javax.management.*;
-import sun.management.AgentConfigurationError;
+import jdk.internal.agent.AgentConfigurationError;
/**
* <p>This class implements unit test for RMI Bootstrap.
--- a/jdk/test/sun/management/jmxremote/bootstrap/RmiSslNoKeyStoreTest.sh Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/bootstrap/RmiSslNoKeyStoreTest.sh Thu Feb 02 21:55:34 2017 +0000
@@ -26,8 +26,8 @@
# @summary Test RMI Bootstrap with SSL and no keystore.
#
# @bug 4932854
-# @modules java.management/sun.management
-# java.management/sun.management.jmxremote
+# @modules jdk.management.agent/jdk.internal.agent
+# jdk.management.agent/sun.management.jmxremote
# @build TestLogger RmiSslNoKeyStoreTest
# @run shell/timeout=300 RmiSslNoKeyStoreTest.sh
@@ -48,8 +48,8 @@
DEBUGOPTIONS=""
export DEBUGOPTIONS
-EXTRAOPTIONS="--add-exports java.management/sun.management=ALL-UNNAMED \
- --add-exports java.management/sun.management.jmxremote=ALL-UNNAMED"
+EXTRAOPTIONS="--add-exports jdk.management.agent/jdk.internal.agent=ALL-UNNAMED \
+ --add-exports jdk.management.agent/sun.management.jmxremote=ALL-UNNAMED"
export EXTRAOPTIONS
# Call the common generic test
--- a/jdk/test/sun/management/jmxremote/bootstrap/SSLConfigFilePermissionTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/bootstrap/SSLConfigFilePermissionTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -27,7 +27,7 @@
* @test
* @library /lib/testlibrary
* @bug 6557093
- * @modules java.management
+ * @modules jdk.management.agent
* @build jdk.testlibrary.* Dummy AbstractFilePermissionTest
* @summary Check SSL config file permission for out-of-the-box management
* @run main/timeout=300 SSLConfigFilePermissionTest
--- a/jdk/test/sun/management/jmxremote/bootstrap/TestManager.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/bootstrap/TestManager.java Thu Feb 02 21:55:34 2017 +0000
@@ -46,7 +46,7 @@
import com.sun.tools.attach.VirtualMachine;
// Sun implementation specific
-import sun.management.ConnectorAddressLink;
+import jdk.internal.agent.ConnectorAddressLink;
public class TestManager {
@@ -57,7 +57,7 @@
try {
VirtualMachine.attach(pid).startLocalManagementAgent();
} catch (Exception x) {
- throw new IOException(x.getMessage());
+ throw new IOException(x.getMessage(), x);
}
}
--- a/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/startstop/JMXStartStopTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -46,14 +46,15 @@
import jdk.testlibrary.ProcessTools;
import jdk.testlibrary.Utils;
-import sun.management.Agent;
-import sun.management.AgentConfigurationError;
+import jdk.internal.agent.Agent;
+import jdk.internal.agent.AgentConfigurationError;
+import jdk.internal.agent.ConnectorAddressLink;
/**
* @test
* @bug 7110104
* @library /lib/testlibrary
- * @modules java.management/sun.management
+ * @modules jdk.management.agent/jdk.internal.agent
* @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
@@ -103,7 +104,7 @@
String jmxUrlStr = null;
try {
- jmxUrlStr = sun.management.ConnectorAddressLink.importFrom((int)pid);
+ jmxUrlStr = ConnectorAddressLink.importFrom((int)pid);
dbg_print("Local Service URL: " +jmxUrlStr);
if ( jmxUrlStr == null ) {
throw new Exception("No Service URL. Local agent not started?");
--- a/jdk/test/sun/management/jmxremote/startstop/JMXStatusPerfCountersTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/startstop/JMXStatusPerfCountersTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -42,7 +42,7 @@
* in the related performance counters.
* @key intermittent
* @library /lib/testlibrary
- * @modules java.management/sun.management
+ * @modules jdk.management.agent/jdk.internal.agent
* @build jdk.testlibrary.* PortAllocator TestApp ManagementAgentJcmd
* @run testng/othervm -XX:+UsePerfData JMXStatusPerfCountersTest
*/
--- a/jdk/test/sun/management/jmxremote/startstop/JMXStatusTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/startstop/JMXStatusTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -38,7 +38,7 @@
* Management agent may be disabled, started (only local connections) and started.
* The test asserts that the expected text is being printed.
* @library /lib/testlibrary
- * @modules java.management/sun.management
+ * @modules jdk.management.agent/jdk.internal.agent
* @build jdk.testlibrary.* PortAllocator TestApp ManagementAgentJcmd
* JMXStatusTest JMXStatus1Test JMXStatus2Test
* @run testng/othervm -XX:+UsePerfData JMXStatus1Test
--- a/jdk/test/sun/management/jmxremote/startstop/ManagementAgentJcmd.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/management/jmxremote/startstop/ManagementAgentJcmd.java Thu Feb 02 21:55:34 2017 +0000
@@ -30,8 +30,8 @@
import java.util.function.Consumer;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import sun.management.Agent;
-import sun.management.AgentConfigurationError;
+import jdk.internal.agent.Agent;
+import jdk.internal.agent.AgentConfigurationError;
import jdk.testlibrary.JDKToolLauncher;
import jdk.testlibrary.ProcessTools;
--- a/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyAuthTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyAuthTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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 @@
* @bug 4323990 4413069 8160838
* @summary HttpsURLConnection doesn't send Proxy-Authorization on CONNECT
* Incorrect checking of proxy server response
- * @modules java.base/sun.net.www
+ * @modules jdk.crypto.ec
+ * java.base/sun.net.www
* @library /javax/net/ssl/templates
* @run main/othervm ProxyAuthTest fail
* @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic
--- a/jdk/test/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java Thu Feb 02 21:55:34 2017 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, 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
@@ -29,6 +29,7 @@
/*
* @test
* @bug 4392475
+ * @modules jdk.crypto.ec
* @library /javax/net/ssl/templates
* @summary Calling setWantClientAuth(true) disables anonymous suites
* @run main/othervm -Djavax.net.debug=all AnonCipherWithWantClientAuth
--- a/jdk/test/tools/jlink/JLinkTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/tools/jlink/JLinkTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -284,6 +284,13 @@
helper.generateDefaultJModule(moduleName, "composite2");
helper.generateDefaultImage(userOptions, moduleName).assertFailure("Error: orphan argument: bar");
}
+
+ // basic check for --help - JDK-8173717
+ {
+ JImageGenerator.getJLinkTask()
+ .option("--help")
+ .call().assertSuccess();
+ }
}
private static void testCompress(Helper helper, String moduleName, String... userOptions) throws IOException {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/launcher/LauncherMessageTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2017, 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 8167063
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.FileUtils
+ * @run main LauncherMessageTest
+ * @summary LauncherHelper should not throw JNI error for LinkageError
+ */
+import java.io.File;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import jdk.testlibrary.FileUtils;
+
+public class LauncherMessageTest {
+
+ public static void main(String[] args) throws Exception {
+ String userDir = System.getProperty("user.dir", ".");
+ File testDir = new File(userDir, "test");
+ List<String> srcContent = new ArrayList<>();
+
+ // Try to create a test directory before proceeding further
+ if (!testDir.mkdir()) {
+ throw new Exception("Test failed: unable to create"
+ + " writable working directory "
+ + testDir.getAbsolutePath());
+ }
+
+ // Create test sub-directories for sources, classes and modules respectively
+ File srcA = new File(testDir.getPath(), "srcA");
+ srcA.mkdir();
+ File srcB = new File(testDir.getPath(), "srcB");
+ srcB.mkdir();
+ File classesA = new File(testDir.getPath(), "classesA");
+ classesA.mkdir();
+ File classesB = new File(testDir.getPath(), "classesB");
+ classesB.mkdir();
+ File modules = new File(testDir.getPath(), "modules");
+ modules.mkdir();
+
+ // Define content and create module-info.java and corresponding source files
+ File modAinfo = new File(srcA.getPath(), "module-info.java");
+ srcContent.add("module mod.a { exports pkgA; }");
+ TestHelper.createFile(modAinfo, srcContent);
+
+ File classA = new File(srcA.getPath(), "ClassA.java");
+ srcContent.clear();
+ srcContent.add("package pkgA; public class ClassA { }");
+ TestHelper.createFile(classA, srcContent);
+
+ File modBinfo = new File(srcB.getPath(), "module-info.java");
+ srcContent.clear();
+ srcContent.add("module mod.b { requires mod.a; }");
+ TestHelper.createFile(modBinfo, srcContent);
+
+ File classB = new File(srcB.getPath(), "ClassB.java");
+ srcContent.clear();
+ srcContent.add("package pkgB;");
+ srcContent.add("import pkgA.ClassA;");
+ srcContent.add("public class ClassB extends ClassA {");
+ srcContent.add("public static void main(String[] args) { } }");
+ TestHelper.createFile(classB, srcContent);
+
+ // Compile all source files and create Jars
+ TestHelper.compile("-d", classesA.getPath(), classA.getPath(), modAinfo.getPath());
+ TestHelper.createJar("cf", Paths.get(modules.getPath(), "mod.a.jar").toString(),
+ "-C", classesA.getPath(), ".");
+ TestHelper.compile("-d", classesB.getPath(), "--module-path", modules.getPath(),
+ classB.getPath(), modBinfo.getPath());
+ TestHelper.createJar("cf", Paths.get(modules.getPath(), "mod.b.jar").toString(),
+ "-C", classesB.getPath(), ".");
+
+ // Delete the module-info.java and Jar file corresponding to mod.a
+ FileUtils.deleteFileWithRetry(Paths.get(modAinfo.getPath()));
+ FileUtils.deleteFileWithRetry(Paths.get(modules.getPath(), "mod.a.jar"));
+
+ // Re-create module-info.java (by removing "exports pkgA;")
+ // and corresponding Jar file
+ srcContent.clear();
+ srcContent.add("module mod.a { }");
+ TestHelper.createFile(modAinfo, srcContent);
+ TestHelper.compile("-d", classesA.getPath(), classA.getPath(), modAinfo.getPath());
+ TestHelper.createJar("cf", Paths.get(modules.getPath(), "mod.a.jar").toString(),
+ "-C", classesA.getPath(), ".");
+
+ // Execute the main class
+ String[] commands = {TestHelper.javaCmd, "--module-path", modules.getPath(),
+ "-m", "mod.b/pkgB.ClassB"};
+ TestHelper.TestResult result = TestHelper.doExec(commands);
+
+ // Clean the test directory and check test status
+ FileUtils.deleteFileTreeWithRetry(Paths.get(testDir.getPath()));
+ if (result.isOK()) {
+ throw new Exception("Test Passed Unexpectedly!");
+ } else {
+ result.testOutput.forEach(System.err::println);
+ if (result.contains("JNI error")) {
+ throw new Exception("Test Failed with JNI error!");
+ }
+ }
+ System.out.println("Test passes, failed with expected error message");
+ }
+}
--- a/jdk/test/tools/launcher/modules/listmods/ListModsTest.java Thu Feb 02 21:20:38 2017 +0000
+++ b/jdk/test/tools/launcher/modules/listmods/ListModsTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -147,7 +147,7 @@
@Test
public void testListWithLimitMods1() throws Exception {
OutputAnalyzer output
- = executeTestJava("--limit-modules", "java.management", "--list-modules")
+ = executeTestJava("--limit-modules", "java.management.rmi", "--list-modules")
.outputTo(System.out)
.errorTo(System.out);
output.shouldContain("java.rmi");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/schemagen/MultiReleaseJarTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2017, 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
+ * @summary Test Multi-Release jar support in schemagen tool
+ * @library /test/lib
+ * @library /lib/testlibrary
+ * @modules jdk.compiler java.xml.ws
+ * @build jdk.test.lib.JDKToolFinder jdk.test.lib.JDKToolLauncher
+ * jdk.test.lib.process.OutputAnalyzer
+ * jdk.test.lib.process.ProcessTools
+ * jdk.test.lib.Utils
+ * CompilerUtils MultiReleaseJarTest
+ * @run testng MultiReleaseJarTest
+ */
+
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.Utils;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.stream.Stream;
+
+import static org.testng.Assert.assertTrue;
+
+public class MultiReleaseJarTest {
+ private static final int SUCCESS = 0;
+
+ @DataProvider(name = "jarFiles")
+ public Object[][] jarFiles() {
+ return new Object[][]{{"MV_BOTH.jar", 9},
+ {"MV_ONLY_9.jar", 9},
+ {"NON_MV.jar", 8}};
+ }
+
+ @BeforeClass
+ public void setUpTest() throws Throwable {
+ compile();
+ Path classes = Paths.get("classes");
+ jar("cf", "MV_BOTH.jar",
+ "-C", classes.resolve("base").toString(), ".",
+ "--release", "9", "-C", classes.resolve("v9").toString(), ".",
+ "--release", "10", "-C", classes.resolve("v10").toString(), ".")
+ .shouldHaveExitValue(SUCCESS);
+
+ jar("cf", "MV_ONLY_9.jar",
+ "-C", classes.resolve("base").toString(), ".",
+ "--release", "9", "-C", classes.resolve("v9").toString(), ".")
+ .shouldHaveExitValue(SUCCESS);
+ jar("cf", "NON_MV.jar",
+ "-C", classes.resolve("base").toString(), ".")
+ .shouldHaveExitValue(SUCCESS);
+ }
+
+ @Test(dataProvider = "jarFiles")
+ public void testSchemagen(String jar, int mainVer) throws Throwable {
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("schemagen");
+ Utils.getForwardVmOptions().forEach(launcher::addToolArg);
+ launcher.addToolArg("-cp").addToolArg(jar)
+ .addToolArg("schemagen.Person");
+ ProcessTools.executeCommand(launcher.getCommand())
+ .shouldHaveExitValue(SUCCESS);
+
+ String pattern = "version" + mainVer;
+ assertTrue(grep(pattern, Paths.get("schema1.xsd")),
+ "Pattern " + pattern + " not found in the generated file.");
+ }
+
+ private boolean grep(String pattern, Path file) throws IOException {
+ return new String(Files.readAllBytes(file)).contains(pattern);
+ }
+
+ private OutputAnalyzer jar(String... args) throws Throwable {
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jar");
+ Stream.of(args).forEach(launcher::addToolArg);
+ return ProcessTools.executeCommand(launcher.getCommand());
+ }
+
+ private void compile() throws Throwable {
+ String[] vers = {"base", "v9", "v10"};
+ for (String ver : vers) {
+ Path classes = Paths.get("classes", ver);
+ Files.createDirectories(classes);
+ Path source = Paths.get(Utils.TEST_SRC,"data", "mr", ver);
+ assertTrue(CompilerUtils.compile(source, classes,
+ "--add-modules", "java.xml.ws"));
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/schemagen/data/mr/base/schemagen/Person.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+package schemagen;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+public class Person {
+
+ @XmlAttribute
+ private String version8;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/schemagen/data/mr/v10/schemagen/Person.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+package schemagen;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+public class Person {
+
+ @XmlAttribute
+ private String version10;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/schemagen/data/mr/v9/schemagen/Person.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+package schemagen;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlRootElement;
+
+@XmlRootElement
+public class Person {
+
+ @XmlAttribute
+ private String version9;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/wsgen/MultiReleaseJarTest.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 2017, 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
+ * @summary Test Multi-Release jar support in wsgen tool
+ * @library /test/lib
+ * @library /lib/testlibrary
+ * @modules jdk.compiler java.xml.ws
+ * @build jdk.test.lib.JDKToolFinder jdk.test.lib.JDKToolLauncher
+ * jdk.test.lib.process.OutputAnalyzer
+ * jdk.test.lib.process.ProcessTools
+ * jdk.test.lib.Utils
+ * CompilerUtils MultiReleaseJarTest
+ * @run testng MultiReleaseJarTest
+ */
+
+import jdk.test.lib.JDKToolLauncher;
+import jdk.test.lib.Utils;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.stream.Stream;
+
+import static org.testng.Assert.assertTrue;
+
+public class MultiReleaseJarTest {
+ private static final int SUCCESS = 0;
+
+ @DataProvider(name = "jarFiles")
+ public Object[][] jarFiles() {
+ return new Object[][]{{"MV_BOTH.jar", 9},
+ {"MV_ONLY_9.jar", 9},
+ {"NON_MV.jar", 8}};
+ }
+
+ @BeforeClass
+ public void setUpTest() throws Throwable {
+ compile();
+ Path classes = Paths.get("classes");
+ jar("cf", "MV_BOTH.jar",
+ "-C", classes.resolve("base").toString(), ".",
+ "--release", "9", "-C", classes.resolve("v9").toString(), ".",
+ "--release", "10", "-C", classes.resolve("v10").toString(), ".")
+ .shouldHaveExitValue(SUCCESS);
+
+ jar("cf", "MV_ONLY_9.jar",
+ "-C", classes.resolve("base").toString(), ".",
+ "--release", "9", "-C", classes.resolve("v9").toString(), ".")
+ .shouldHaveExitValue(SUCCESS);
+ jar("cf", "NON_MV.jar",
+ "-C", classes.resolve("base").toString(), ".")
+ .shouldHaveExitValue(SUCCESS);
+ }
+
+
+ @Test(dataProvider = "jarFiles")
+ public void testWsgen(String jar, int mainVer) throws Throwable {
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("wsgen");
+ Utils.getForwardVmOptions().forEach(launcher::addToolArg);
+ launcher.addToolArg("-cp").addToolArg(jar)
+ .addToolArg("-keep")
+ .addToolArg("wsgen.TestServer");
+ ProcessTools.executeCommand(launcher.getCommand())
+ .shouldHaveExitValue(SUCCESS);
+
+ String pattern = "version" + mainVer;
+ assertTrue(grep(pattern,
+ Paths.get("wsgen/jaxws/GetJavaVersion.java")),
+ "Pattern " + pattern + " not found in the generated file.");
+ }
+
+ private boolean grep(String pattern, Path file) throws IOException {
+ return new String(Files.readAllBytes(file)).contains(pattern);
+ }
+
+ private OutputAnalyzer jar(String... args) throws Throwable {
+ JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jar");
+ Stream.of(args).forEach(launcher::addToolArg);
+ return ProcessTools.executeCommand(launcher.getCommand());
+ }
+
+ private void compile() throws Throwable {
+ String[] vers = {"base", "v9", "v10"};
+ for (String ver : vers) {
+ Path classes = Paths.get("classes", ver);
+ Files.createDirectories(classes);
+ Path source = Paths.get(Utils.TEST_SRC,"data", "mr", ver);
+ assertTrue(CompilerUtils.compile(source, classes,
+ "--add-modules", "java.xml.ws"));
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/wsgen/data/mr/base/wsgen/TestServer.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+package wsgen;
+
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+
+@WebService
+public class TestServer {
+
+ @WebMethod(operationName = "version8")
+ public String getJavaVersion() {
+ return "8";
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/wsgen/data/mr/v10/wsgen/TestServer.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+package wsgen;
+
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+
+@WebService
+public class TestServer {
+
+ @WebMethod(operationName = "version10")
+ public String getJavaVersion() {
+ return "10";
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/wsgen/data/mr/v9/wsgen/TestServer.java Thu Feb 02 21:55:34 2017 +0000
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+package wsgen;
+
+import javax.jws.WebMethod;
+import javax.jws.WebService;
+
+@WebService
+public class TestServer {
+
+ @WebMethod(operationName = "version9")
+ public String getJavaVersion() {
+ return "9";
+ }
+}
\ No newline at end of file