Merge
authorduke
Wed, 05 Jul 2017 16:39:18 +0200
changeset 852 d776f58e8a63
parent 851 9ab23b73f1b9 (current diff)
parent 850 49d52a53975d (diff)
child 854 a7fdb5ff3e2c
Merge
--- a/.hgtags-top-repo	Thu Jul 17 11:28:32 2008 -0700
+++ b/.hgtags-top-repo	Wed Jul 05 16:39:18 2017 +0200
@@ -5,3 +5,4 @@
 56652b46f328937f6b9b5130f1e4cd80f48868ef jdk7-b28
 31e08f70e88d77c2053f91c21b49a04296bdc59a jdk7-b29
 2dab2f712e1832c92acfa63ec0337048b9422c20 jdk7-b30
+3300a35a0bd56d695b92fe0b34f03ebbfc939064 jdk7-b31
--- a/README-builds.html	Thu Jul 17 11:28:32 2008 -0700
+++ b/README-builds.html	Wed Jul 05 16:39:18 2017 +0200
@@ -5,15 +5,12 @@
     </head>
     <body style="background-color:lightcyan">
         <!-- ====================================================== -->
-        <table width="100%" style="background-color:white">
+        +        <table width="100%">
             <tr>
                 <td align="center">
-                    <a href="http://openjdk.java.net" border="0">    
-                        <img alt="OpenJDK" 
-                             src="http://openjdk.java.net/images/openjdk.png"
-                             width=256
-                             style="border-style: none"/>
-                    </a>
+                    <img alt="OpenJDK" 
+                         src="http://openjdk.java.net/images/openjdk.png" 
+                         width=256 />
                 </td>
             </tr>
             <tr>
@@ -54,6 +51,7 @@
                             <li><a href="#bootjdk">Bootstrap JDK</a> </li>
                             <li><a href="#binaryplugs">Binary Plugs</a> </li>
                             <li><a href="#importjdk">Optional Import JDK</a> </li>
+                            <li><a href="#ant">Ant</a> </li>
                             <li><a href="#cacerts">Certificate Authority File (cacert)</a> </li>
                             <li><a href="#compilers">Compilers</a> 
                                 <ul>
@@ -424,24 +422,37 @@
                     you should use <tt>gmake</tt>
                     which will be located in either the <tt>/opt/sfw/bin</tt> or 
                     <tt>/usr/sfw/bin</tt> directory.
+                    In more recent versions of Solaris GNU make can be found
+                    at <tt>/usr/bin/gmake</tt>. 
                 </li>
                 <li>
                     <strong>Windows:</strong>
                     Make sure you start your build inside a bash/sh/ksh shell.
                     <br>
                     <b>WARNING:</b> Watch out for make version 3.81, it may
-                    not work due to a lack of support for drive letter paths
-                    like <tt>C:/</tt>. See
-                    <a href="#gmake">section on gmake</a>.
+                    not work due to a lack of support for MS-DOS drive letter paths
+                    like <tt>C:/</tt> or <tt>C:\</tt>.
                     Use a 3.80 version, or find a newer
-                    version that has this problem fixed.
+                    version that has this problem fixed, like 3.82.
                     The older 3.80 version of make.exe can be downloaded with this
                     <a href="http://cygwin.paracoda.com/release/make/make-3.80-1.tar.bz2" target="_blank">
                     link</a>.
+                    Use of this older 3.80 make.exe may require that you install the
+                    libintl2.dll library or libintl2 cygwin package which is
+                    no longer installed by default by the cygwin installer.
+                    <br>
                     Also see the
                     <a href="http://developer.mozilla.org/en/docs/Windows_build_prerequisites_using_cygwin#make" target="_blank">
                     mozilla developer center</a>
                     on this topic.
+                    <br>
+                    It's hoped that when make 3.82 starts shipping in a future cygwin
+                    release that this MS-DOS path issue will be fixed.
+                    In addition to the above 3.80 make.exe you can download 
+                    this
+                    <a href="http://www.cmake.org/files/cygwin/make.exe">
+                    www.cmake.org make.exe</a> which will not have a libintl2.dll
+                    dependency.
                 </li>
             </ul>
             <p>
@@ -507,6 +518,11 @@
                     Install or upgrade the <a href="#freetype">FreeType development
                     package</a>.
                 </li>
+                <li>
+                    Install
+                    <a href="#ant">Ant</a>, set
+                    <tt><a href="#ANT_HOME">ANT_HOME</a></tt>.
+                </li>
             </ol>
         </blockquote>
         <!-- ------------------------------------------------------ -->
@@ -567,6 +583,11 @@
                     <a href="#cups">CUPS Include files</a>, set
                     <tt><a href="#ALT_CUPS_HEADERS_PATH">ALT_CUPS_HEADERS_PATH</a></tt>.
                 </li>
+                <li>
+                    Install
+                    <a href="#ant">Ant</a>, set
+                    <tt><a href="#ANT_HOME">ANT_HOME</a></tt>.
+                </li>
             </ol>
         </blockquote>
         <!-- ------------------------------------------------------ -->
@@ -654,6 +675,11 @@
                     Install 
                     <a href="#dxsdk">Microsoft DirectX SDK</a>.
                 </li>
+                <li>
+                    Install
+                    <a href="#ant">Ant</a>, set
+                    <tt><a href="#ANT_HOME">ANT_HOME</a></tt>.
+                </li>
             </ol>
         </blockquote>
         <!-- ------------------------------------------------------ -->
@@ -736,6 +762,22 @@
                 and the build will copy the needed files from this import area.
             </blockquote>
             <!-- ------------------------------------------------------ -->
+            <h4><a name="ant">Ant</a></h4>
+            <blockquote>
+                All OpenJDK builds require access to least Ant 1.6.5.
+                The Ant tool is available from the 
+                <a href="http://ant.apache.org/antlibs/bindownload.cgi" target="_blank">
+                Ant download site</a>.
+                You should always set 
+                <tt><a href="#ANT_HOME">ANT_HOME</a></tt>
+                to point to the location of
+                the Ant installation, this is the directory pathname
+                that contains a <tt>bin and lib</tt>.
+                It's also a good idea to also place its <tt>bin</tt> directory
+                in the <tt>PATH</tt> environment variable, although it's
+                not absolutely required.
+            </blockquote>
+            <!-- ------------------------------------------------------ -->
             <h4><a name="cacerts">Certificate Authority File (cacert)</a></h4>
             <blockquote>
                 See <a href="http://en.wikipedia.org/wiki/Certificate_Authority" target="_blank">
@@ -915,6 +957,21 @@
                 and 
                 <tt><a href="#ALT_FREETYPE_HEADERS_PATH">ALT_FREETYPE_HEADERS_PATH</a></tt>
                 to refer to place where library and header files are installed.
+                <p>
+                Building the freetype 2 libraries from scratch is also possible,
+                however on Windows refer to the
+                <a href="http://freetype.freedesktop.org/wiki/FreeType_DLL">
+                Windows FreeType DLL build instructions</a>.
+                <p>
+                Note that by default FreeType is built with byte code hinting
+                support disabled due to licensing restrictions.
+                In this case, text appearance and metrics are expected to
+                differ from Sun's official JDK build.
+                See
+                <a href="http://freetype.sourceforge.net/freetype2/index.html">
+                    the SourceForge FreeType2 Home Page
+                </a>
+                for more information.
             </blockquote>    
             <!-- ------------------------------------------------------ -->
             <h4><a name="alsa">Advanced Linux Sound Architecture (ALSA) (Linux only)</a></h4>
@@ -1036,7 +1093,8 @@
                             <tr>
                                 <td>make.exe</td>
                                 <td>Devel</td>
-                                <td>make: The GNU version of the 'make' utility</td>
+                                <td>make: The GNU version of the 'make' utility<br>
+                                <b>NOTE</b>: See <a href="#gmake">the GNU make section</a></td>
                             </tr>
                             <tr>
                                 <td>m4.exe</td>
@@ -1050,7 +1108,7 @@
                                 <td>cpio: A program to manage archives of files</td>
                             </tr>
                             <tr>
-                                <td>awk.exe</td>
+                                <td>gawk.exe</td>
                                 <td>Utils</td>
                                 <td>awk: Pattern-directed scanning and processing language</td>
                             </tr>
@@ -1061,17 +1119,17 @@
                             </tr>
                             <tr>
                                 <td>zip.exe</td>
-                                <td>Utils</td>
+                                <td>Archive</td>
                                 <td>zip: Package and compress (archive) files</td>
                             </tr>
                             <tr>
                                 <td>unzip.exe</td>
-                                <td>Utils</td>
+                                <td>Archive</td>
                                 <td>unzip: Extract compressed files in a ZIP archive</td>
                             </tr>
                             <tr>
                                 <td>free.exe</td>
-                                <td>Utils</td>
+                                <td>Procps</td>
                                 <td>free: Display amount of free and used memory in the system</td>
                             </tr>
                         </tbody>
@@ -1224,46 +1282,6 @@
         document) that can impact the build are:
         <blockquote>
             <dl>
-                <dt><a name="path"><tt>PATH</tt></a> </dt>
-                <dd>Typically you want to set the <tt>PATH</tt> to include:
-                    <ul>
-                        <li>The location of the GNU make binary</li>
-                        <li>The location of the Bootstrap JDK <tt>java</tt> 
-                        (see <a href="#bootjdk">Bootstrap JDK</a>)</li>
-                        <li>The location of the C/C++ compilers 
-                        (see <a href="#compilers"><tt>compilers</tt></a>)</li>
-                        <li>The location or locations for the Unix command utilities
-                        (e.g. <tt>/usr/bin</tt>)</li>
-                    </ul>
-                </dd>
-                <dt><tt>MILESTONE</tt> </dt>
-                <dd>
-                    The milestone name for the build (<i>e.g.</i>"beta"). 
-                    The default value is "internal".
-                </dd>
-                <dt><tt>BUILD_NUMBER</tt> </dt>
-                <dd>
-                    The build number for the build (<i>e.g.</i> "b27"). 
-                    The default value is "b00".
-                </dd>
-                <dt><a name="arch_data_model"><tt>ARCH_DATA_MODEL</tt></a></dt>
-                <dd>The <tt>ARCH_DATA_MODEL</tt> variable
-                    is used to specify whether the build is to generate 32-bit or 64-bit
-                    binaries. 
-                    The Solaris build supports either 32-bit or 64-bit builds, but
-                    Windows and Linux will support only one, depending on the specific
-                    OS being used.
-                    Normally, setting this variable is only necessary on Solaris.
-                    Set <tt>ARCH_DATA_MODEL</tt> to <tt>32</tt> for generating 32-bit binaries, 
-                    or to <tt>64</tt> for generating 64-bit binaries.
-                </dd>
-                <dt><a name="ALT_BOOTDIR"><tt>ALT_BOOTDIR</tt></a></dt>
-                <dd>
-                    The location of the bootstrap JDK installation. 
-                    See <a href="#bootjdk">Bootstrap JDK</a> for more information.
-                    You should always install your own local Bootstrap JDK and
-                    always set <tt>ALT_BOOTDIR</tt> explicitly.
-                </dd>
                 <dt><a name="ALT_BINARY_PLUGS_PATH"><tt>ALT_BINARY_PLUGS_PATH</tt></a></dt>
                 <dd>
                     The location of the binary plugs installation.
@@ -1272,98 +1290,32 @@
                     recent Binary Plugs install image
                     and set this variable to that location.
                 </dd>
-                <dt><a name="ALT_JDK_IMPORT_PATH"><tt>ALT_JDK_IMPORT_PATH</tt></a></dt>
-                <dd>
-                    The location of a previously built JDK installation. 
-                    See <a href="#importjdk">Optional Import JDK</a> for more information.
-                </dd>
-                <dt><a name="ALT_OUTPUTDIR"><tt>ALT_OUTPUTDIR</tt></a> </dt>
-                <dd>
-                    An override for specifying the (absolute) path of where the
-                    build output is to go.
-                    The default output directory will be build/<i>platform</i>.
-                </dd>
-                <dt><a name="ALT_COMPILER_PATH"><tt>ALT_COMPILER_PATH</tt></a> </dt>
-                <dd>
-                    The location of the C/C++ compiler.
-                    The default varies depending on the platform. 
-                </dd>
-                <dt><tt><a name="ALT_CACERTS_FILE">ALT_CACERTS_FILE</a></tt></dt>
+                <dt><a name="ALT_BOOTDIR"><tt>ALT_BOOTDIR</tt></a></dt>
                 <dd>
-                    The location of the <a href="#cacerts">cacerts</a> file.
-                    The default will refer to 
-                    <tt>jdk/src/share/lib/security/cacerts</tt>.
-                </dd>
-                <dt><a name="ALT_CUPS_HEADERS_PATH"><tt>ALT_CUPS_HEADERS_PATH</tt></a> </dt>
-                <dd>
-                    The location of the CUPS header files.
-                    See <a href="#cups">CUPS information</a> for more information.
-                    If this path does not exist the fallback path is 
-                    <tt>/usr/include</tt>.
-                </dd>
-                <dt><a name="ALT_FREETYPE_LIB_PATH"><tt>ALT_FREETYPE_LIB_PATH</tt></a></dt>
-                <dd>
-                    The location of the FreeType shared library. 
-                    See <a href="#freetype">FreeType information</a> for details. 
-                </dd>
-                <dt><a name="ALT_FREETYPE_HEADERS_PATH"><tt>ALT_FREETYPE_HEADERS_PATH</tt></a></dt>
-                <dd>
-                    The location of the FreeType header files.
-                    See <a href="#freetype">FreeType information</a> for details. 
-                </dd>
-                <dt><a name="ALT_JDK_DEVTOOLS_PATH"><tt>ALT_JDK_DEVTOOLS_PATH</tt></a></dt>
-                <dd>
-                    The default root location of the devtools.
-                    The default value is 
-                    <tt>$(ALT_SLASH_JAVA)/devtools</tt>.
+                    The location of the bootstrap JDK installation. 
+                    See <a href="#bootjdk">Bootstrap JDK</a> for more information.
+                    You should always install your own local Bootstrap JDK and
+                    always set <tt>ALT_BOOTDIR</tt> explicitly.
                 </dd>
-                <dt><tt><a name="ALT_DEVTOOLS_PATH">ALT_DEVTOOLS_PATH</a></tt> </dt>
-                <dd>
-                    The location of tools like the 
-                    <a href="#zip"><tt>zip</tt> and <tt>unzip</tt></a>
-                    binaries, but might also contain the GNU make utility
-                    (<tt><i>gmake</i></tt>).
-                    So this area is a bit of a grab bag, especially on Windows.
-                    The default value depends on the platform and
-                    Unix Commands being used.
-                    On Linux the default will be 
-                    <tt>$(ALT_JDK_DEVTOOLS_PATH)/linux/bin</tt>, 
-                    on Solaris
-                    <tt>$(ALT_JDK_DEVTOOLS_PATH)/<i>{sparc,i386}</i>/bin</tt>, 
-                    on Windows with MKS
-                    <tt>%SYSTEMDRIVE%/UTILS</tt>, 
-                    and on Windows with CYGWIN
-                    <tt>/usr/bin</tt>.
-                </dd>
-                <dt><a name="ALT_UNIXCOMMAND_PATH"><tt>ALT_UNIXCOMMAND_PATH</tt></a> </dt>
+                <dt><a name="ALT_BUILD_BINARY_PLUGS_PATH"><tt>ALT_BUILD_BINARY_PLUGS_PATH</tt></a></dt>
                 <dd>
-                    An override for specifying where the
-                    Unix command set are located. 
-                    The default location varies depending on the platform,
-                    <tt>"%SYSTEMDRIVE%/MKSNT"</tt> or
-                    <tt>$(ROOTDIR)</tt> on Windows with MKS, otherwise it's 
-                    <tt>"/bin"</tt> or <tt>/usr/bin</tt>.
-                </dd>
-                <dt><a name="ALT_UNIXCCS_PATH"><tt>ALT_UNIXCCS_PATH</tt></a></dt>
-                <dd>
-                    <strong>Solaris only:</strong>
-                    An override for specifying where the Unix CCS
-                    command set are located.
-                    The default location is <tt>/usr/ccs/bin</tt> 
-                </dd>
-                <dt><a name="ALT_USRBIN_PATH"><tt>ALT_USRBIN_PATH</tt></a></dt>
-                <dd>
-                    An override for specifying where the
-                    Unix <tt>/usr/bin</tt> commands are located. You usually do not need
-                    to set this variable: the default location is <tt>/usr/bin</tt>)
-                </dd>
-                <dt><a name="ALT_SLASHJAVA"><tt>ALT_SLASHJAVA</tt></a></dt>
-                <dd>
-                    The default root location for many of the ALT path locations
-                    of the following ALT variables.
-                    The default value is 
-                    <tt>"/java"</tt> on Solaris and Linux, 
-                    <tt>"J:"</tt> on Windows.
+                    These are useful in managing builds on multiple platforms.
+                    The default network location for all of the binary plug images
+                    for all platforms. 
+                    If <tt><a href="#ALT_BINARY_PLUGS_PATH">ALT_BINARY_PLUGS_PATH</a></tt>
+                    is not set, this directory will be used and should contain 
+                    the following directories:
+                    <tt>solaris-sparc</tt>,
+                    <tt>solaris-i586</tt>,
+                    <tt>solaris-sparcv9</tt>,
+                    <tt>solaris-amd64</tt>,
+                    <tt>linux-i586</tt>,
+                    <tt>linux-amd64</tt>,
+                    <tt>windows-i586</tt>,
+                    and
+                    <tt>windows-amd64</tt>.
+                    Where each of these directories contain the binary plugs image
+                    for that platform.
                 </dd>
                 <dt><a name="ALT_BUILD_JDK_IMPORT_PATH"><tt>ALT_BUILD_JDK_IMPORT_PATH</tt></a></dt>
                 <dd>
@@ -1385,56 +1337,166 @@
                     Where each of these directories contain the import JDK image
                     for that platform.
                 </dd>
-                <dt><a name="ALT_BUILD_BINARY_PLUGS_PATH"><tt>ALT_BUILD_BINARY_PLUGS_PATH</tt></a></dt>
+                <dt><tt><a name="ALT_CACERTS_FILE">ALT_CACERTS_FILE</a></tt></dt>
+                <dd>
+                    The location of the <a href="#cacerts">cacerts</a> file.
+                    The default will refer to 
+                    <tt>jdk/src/share/lib/security/cacerts</tt>.
+                </dd>
+                <dt><a name="ALT_COMPILER_PATH"><tt>ALT_COMPILER_PATH</tt></a> </dt>
+                <dd>
+                    The location of the C/C++ compiler.
+                    The default varies depending on the platform. 
+                </dd>
+                <dt><a name="ALT_CUPS_HEADERS_PATH"><tt>ALT_CUPS_HEADERS_PATH</tt></a> </dt>
+                <dd>
+                    The location of the CUPS header files.
+                    See <a href="#cups">CUPS information</a> for more information.
+                    If this path does not exist the fallback path is 
+                    <tt>/usr/include</tt>.
+                </dd>
+                <dt><tt><a name="ALT_DEVTOOLS_PATH">ALT_DEVTOOLS_PATH</a></tt> </dt>
+                <dd>
+                    The location of tools like the 
+                    <a href="#zip"><tt>zip</tt> and <tt>unzip</tt></a>
+                    binaries, but might also contain the GNU make utility
+                    (<tt><i>gmake</i></tt>).
+                    So this area is a bit of a grab bag, especially on Windows.
+                    The default value depends on the platform and
+                    Unix Commands being used.
+                    On Linux the default will be 
+                    <tt>$(ALT_JDK_DEVTOOLS_PATH)/linux/bin</tt>, 
+                    on Solaris
+                    <tt>$(ALT_JDK_DEVTOOLS_PATH)/<i>{sparc,i386}</i>/bin</tt>, 
+                    on Windows with MKS
+                    <tt>%SYSTEMDRIVE%/UTILS</tt>, 
+                    and on Windows with CYGWIN
+                    <tt>/usr/bin</tt>.
+                </dd>
+                <dt><tt><a name="ALT_DXSDK_PATH">ALT_DXSDK_PATH</a></tt> </dt>
                 <dd>
-                    These are useful in managing builds on multiple platforms.
-                    The default network location for all of the binary plug images
-                    for all platforms. 
-                    If <tt><a href="#ALT_BINARY_PLUGS_PATH">ALT_BINARY_PLUGS_PATH</a></tt>
-                    is not set, this directory will be used and should contain 
-                    the following directories:
-                    <tt>solaris-sparc</tt>,
-                    <tt>solaris-i586</tt>,
-                    <tt>solaris-sparcv9</tt>,
-                    <tt>solaris-amd64</tt>,
-                    <tt>linux-i586</tt>,
-                    <tt>linux-amd64</tt>,
-                    <tt>windows-i586</tt>,
-                    and
-                    <tt>windows-amd64</tt>.
-                    Where each of these directories contain the binary plugs image
-                    for that platform.
+                    <strong>Windows Only:</strong>
+                    The location of the 
+                    <a href="#dxsdk">Microsoft DirectX 9 SDK</a>.
+                    The default will be to try and use the DirectX environment
+                    variable <tt>DXSDK_DIR</tt>,
+                    failing that, look in <tt>C:/DXSDK</tt>.
+                </dd>
+                <dt><a name="ALT_FREETYPE_HEADERS_PATH"><tt>ALT_FREETYPE_HEADERS_PATH</tt></a></dt>
+                <dd>
+                    The location of the FreeType header files.
+                    See <a href="#freetype">FreeType information</a> for details. 
+                </dd>
+                <dt><a name="ALT_FREETYPE_LIB_PATH"><tt>ALT_FREETYPE_LIB_PATH</tt></a></dt>
+                <dd>
+                    The location of the FreeType shared library. 
+                    See <a href="#freetype">FreeType information</a> for details. 
                 </dd>
-                <dt><strong>Windows specific:</strong></dt>
+                <dt><a name="ALT_JDK_DEVTOOLS_PATH"><tt>ALT_JDK_DEVTOOLS_PATH</tt></a></dt>
+                <dd>
+                    The default root location of the devtools.
+                    The default value is 
+                    <tt>$(ALT_SLASH_JAVA)/devtools</tt>.
+                </dd>
+                <dt><a name="ALT_JDK_IMPORT_PATH"><tt>ALT_JDK_IMPORT_PATH</tt></a></dt>
+                <dd>
+                    The location of a previously built JDK installation. 
+                    See <a href="#importjdk">Optional Import JDK</a> for more information.
+                </dd>
+                <dt><a name="ALT_MSDEVTOOLS_PATH"><tt>ALT_MSDEVTOOLS_PATH</tt></a> </dt>
+                <dd>
+                    <strong>Windows Only:</strong>
+                    The location of the Microsoft Visual Studio .NET 2003
+                    tools 'bin' directory.
+                    The default is usually derived from
+                    <a href="#ALT_COMPILER_PATH"><tt>ALT_COMPILER_PATH</tt></a>.
+                </dd>
+                <dt><tt><a name="ALT_MSVCR71_DLL_PATH">ALT_MSVCR71_DLL_PATH</a></tt> </dt>
                 <dd>
-                    <dl>
-                        <dt><a name="ALT_MSDEVTOOLS_PATH"><tt>ALT_MSDEVTOOLS_PATH</tt></a> </dt>
-                        <dd>
-                            The location of the Microsoft Visual Studio .NET 2003
-                            tools 'bin' directory.
-                            The default is usually derived from
-                            <a href="#ALT_COMPILER_PATH"><tt>ALT_COMPILER_PATH</tt></a>.
-                        </dd>
-                        <dt><tt><a name="ALT_DXSDK_PATH">ALT_DXSDK_PATH</a></tt> </dt>
-                        <dd>
-                            The location of the 
-                            <a href="#dxsdk">Microsoft DirectX 9 SDK</a>.
-                            The default will be to try and use the DirectX environment
-                            variable <tt>DXSDK_DIR</tt>,
-                            failing that, look in <tt>C:/DXSDK</tt>.
-                        </dd>
-                        <dt><tt><a name="ALT_MSVCRT_DLL_PATH">ALT_MSVCRT_DLL_PATH</a></tt> </dt>
-                        <dd>
-                            The location of the 
-                            <a href="#msvcrt"><tt>MSVCRT.DLL</tt></a>. 
-                        </dd>
-                        <dt><tt><a name="ALT_MSVCR71_DLL_PATH">ALT_MSVCR71_DLL_PATH</a></tt> </dt>
-                        <dd>
-                            <strong>i586 only:</strong>
-                            The location of the 
-                            <a href="#msvcr71"><tt>MSVCR71.DLL</tt></a>. 
-                        </dd>
-                    </dl>
+                    <strong>Windows i586 only:</strong>
+                    The location of the 
+                    <a href="#msvcr71"><tt>MSVCR71.DLL</tt></a>. 
+                </dd>
+                <dt><tt><a name="ALT_MSVCRT_DLL_PATH">ALT_MSVCRT_DLL_PATH</a></tt> </dt>
+                <dd>
+                    <strong>Windows Only:</strong>
+                    The location of the 
+                    <a href="#msvcrt"><tt>MSVCRT.DLL</tt></a>. 
+                </dd>
+                <dt><a name="ALT_OUTPUTDIR"><tt>ALT_OUTPUTDIR</tt></a> </dt>
+                <dd>
+                    An override for specifying the (absolute) path of where the
+                    build output is to go.
+                    The default output directory will be build/<i>platform</i>.
+                </dd>
+                <dt><a name="ALT_SLASHJAVA"><tt>ALT_SLASHJAVA</tt></a></dt>
+                <dd>
+                    The default root location for many of the ALT path locations
+                    of the following ALT variables.
+                    The default value is 
+                    <tt>"/java"</tt> on Solaris and Linux, 
+                    <tt>"J:"</tt> on Windows.
+                </dd>
+                <dt><a name="ALT_UNIXCCS_PATH"><tt>ALT_UNIXCCS_PATH</tt></a></dt>
+                <dd>
+                    <strong>Solaris only:</strong>
+                    An override for specifying where the Unix CCS
+                    command set are located.
+                    The default location is <tt>/usr/ccs/bin</tt> 
+                </dd>
+                <dt><a name="ALT_UNIXCOMMAND_PATH"><tt>ALT_UNIXCOMMAND_PATH</tt></a> </dt>
+                <dd>
+                    An override for specifying where the
+                    Unix command set are located. 
+                    The default location varies depending on the platform,
+                    <tt>"%SYSTEMDRIVE%/MKSNT"</tt> or
+                    <tt>$(ROOTDIR)</tt> on Windows with MKS, otherwise it's 
+                    <tt>"/bin"</tt> or <tt>/usr/bin</tt>.
+                </dd>
+                <dt><a name="ALT_USRBIN_PATH"><tt>ALT_USRBIN_PATH</tt></a></dt>
+                <dd>
+                    An override for specifying where the
+                    Unix <tt>/usr/bin</tt> commands are located. You usually do not need
+                    to set this variable: the default location is <tt>/usr/bin</tt>)
+                </dd>
+                <dt><a name="ANT_HOME"><tt>ANT_HOME</tt></a></dt>
+                <dd>
+                    The location of the Ant installation. 
+                    See <a href="#ant">Ant</a> for more information.
+                    You should always set <tt>ANT_HOME</tt> explicitly.
+                </dd>
+                <dt><a name="arch_data_model"><tt>ARCH_DATA_MODEL</tt></a></dt>
+                <dd>The <tt>ARCH_DATA_MODEL</tt> variable
+                    is used to specify whether the build is to generate 32-bit or 64-bit
+                    binaries. 
+                    The Solaris build supports either 32-bit or 64-bit builds, but
+                    Windows and Linux will support only one, depending on the specific
+                    OS being used.
+                    Normally, setting this variable is only necessary on Solaris.
+                    Set <tt>ARCH_DATA_MODEL</tt> to <tt>32</tt> for generating 32-bit binaries, 
+                    or to <tt>64</tt> for generating 64-bit binaries.
+                </dd>
+                <dt><tt>BUILD_NUMBER</tt> </dt>
+                <dd>
+                    The build number for the build (<i>e.g.</i> "b27"). 
+                    The default value is "b00".
+                </dd>
+                <dt><tt>MILESTONE</tt> </dt>
+                <dd>
+                    The milestone name for the build (<i>e.g.</i>"beta"). 
+                    The default value is "internal".
+                </dd>
+                <dt><a name="path"><tt>PATH</tt></a> </dt>
+                <dd>Typically you want to set the <tt>PATH</tt> to include:
+                    <ul>
+                        <li>The location of the GNU make binary</li>
+                        <li>The location of the Bootstrap JDK <tt>java</tt> 
+                        (see <a href="#bootjdk">Bootstrap JDK</a>)</li>
+                        <li>The location of the C/C++ compilers 
+                        (see <a href="#compilers"><tt>compilers</tt></a>)</li>
+                        <li>The location or locations for the Unix command utilities
+                        (e.g. <tt>/usr/bin</tt>)</li>
+                    </ul>
                 </dd>
             </dl>
         </blockquote>
--- a/hotspot/.hgtags	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/.hgtags	Wed Jul 05 16:39:18 2017 +0200
@@ -5,3 +5,4 @@
 c14dab40ed9bf45ad21150bd70c9c80cdf655415 jdk7-b28
 4f91c08b3e4498213a9c5a24898f7d9c38cf86fb jdk7-b29
 d1605aabd0a15ecf93787c47de63073c33fba52d jdk7-b30
+9c2ecc2ffb125f14fab3857fe7689598956348a0 jdk7-b31
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -2414,8 +2414,20 @@
   return ::mprotect(bottom, size, prot) == 0;
 }
 
-bool os::protect_memory(char* addr, size_t size) {
-  return linux_mprotect(addr, size, PROT_READ);
+// Set protections specified
+bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
+                        bool is_committed) {
+  unsigned int p = 0;
+  switch (prot) {
+  case MEM_PROT_NONE: p = PROT_NONE; break;
+  case MEM_PROT_READ: p = PROT_READ; break;
+  case MEM_PROT_RW:   p = PROT_READ|PROT_WRITE; break;
+  case MEM_PROT_RWX:  p = PROT_READ|PROT_WRITE|PROT_EXEC; break;
+  default:
+    ShouldNotReachHere();
+  }
+  // is_committed is unused.
+  return linux_mprotect(addr, bytes, p);
 }
 
 bool os::guard_memory(char* addr, size_t size) {
@@ -3704,8 +3716,9 @@
 
 // Mark the polling page as readable
 void os::make_polling_page_readable(void) {
-  if( !protect_memory((char *)_polling_page, Linux::page_size()) )
+  if( !linux_mprotect((char *)_polling_page, Linux::page_size(), PROT_READ)) {
     fatal("Could not enable polling page");
+  }
 };
 
 int os::active_processor_count() {
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -2965,10 +2965,21 @@
   return retVal == 0;
 }
 
-// Protect memory (make it read-only. (Used to pass readonly pages through
+// Protect memory (Used to pass readonly pages through
 // JNI GetArray<type>Elements with empty arrays.)
-bool os::protect_memory(char* addr, size_t bytes) {
-  return solaris_mprotect(addr, bytes, PROT_READ);
+bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
+                        bool is_committed) {
+  unsigned int p = 0;
+  switch (prot) {
+  case MEM_PROT_NONE: p = PROT_NONE; break;
+  case MEM_PROT_READ: p = PROT_READ; break;
+  case MEM_PROT_RW:   p = PROT_READ|PROT_WRITE; break;
+  case MEM_PROT_RWX:  p = PROT_READ|PROT_WRITE|PROT_EXEC; break;
+  default:
+    ShouldNotReachHere();
+  }
+  // is_committed is unused.
+  return solaris_mprotect(addr, bytes, p);
 }
 
 // guard_memory and unguard_memory only happens within stack guard pages.
--- a/hotspot/src/os/windows/vm/os_windows.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/os/windows/vm/os_windows.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -2170,6 +2170,7 @@
             // Windows 98 reports faulting addresses incorrectly
             if (!MacroAssembler::needs_explicit_null_check((intptr_t)addr) ||
                 !os::win32::is_nt()) {
+
               return Handle_Exception(exceptionInfo,
                   SharedRuntime::continuation_for_implicit_exception(thread, pc, SharedRuntime::IMPLICIT_NULL));
             }
@@ -2563,9 +2564,33 @@
   return VirtualFree(addr, 0, MEM_RELEASE) != 0;
 }
 
-bool os::protect_memory(char* addr, size_t bytes) {
+// Set protections specified
+bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
+                        bool is_committed) {
+  unsigned int p = 0;
+  switch (prot) {
+  case MEM_PROT_NONE: p = PAGE_NOACCESS; break;
+  case MEM_PROT_READ: p = PAGE_READONLY; break;
+  case MEM_PROT_RW:   p = PAGE_READWRITE; break;
+  case MEM_PROT_RWX:  p = PAGE_EXECUTE_READWRITE; break;
+  default:
+    ShouldNotReachHere();
+  }
+
   DWORD old_status;
-  return VirtualProtect(addr, bytes, PAGE_READONLY, &old_status) != 0;
+
+  // Strange enough, but on Win32 one can change protection only for committed
+  // memory, not a big deal anyway, as bytes less or equal than 64K
+  if (!is_committed && !commit_memory(addr, bytes)) {
+    fatal("cannot commit protection page");
+  }
+  // One cannot use os::guard_memory() here, as on Win32 guard page
+  // have different (one-shot) semantics, from MSDN on PAGE_GUARD:
+  //
+  // Pages in the region become guard pages. Any attempt to access a guard page
+  // causes the system to raise a STATUS_GUARD_PAGE exception and turn off
+  // the guard page status. Guard pages thus act as a one-time access alarm.
+  return VirtualProtect(addr, bytes, p, &old_status) != 0;
 }
 
 bool os::guard_memory(char* addr, size_t bytes) {
--- a/hotspot/src/os_cpu/linux_sparc/vm/assembler_linux_sparc.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/os_cpu/linux_sparc/vm/assembler_linux_sparc.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -27,12 +27,6 @@
 
 #include <asm-sparc/traps.h>
 
-bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
-  // Since the linux kernel resides at the low end of
-  // user address space, no null pointer check is needed.
-  return offset < 0 || offset >= 0x100000;
-}
-
 void MacroAssembler::read_ccr_trap(Register ccr_save) {
   // No implementation
   breakpoint_trap();
--- a/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_32.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_32.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -39,10 +39,3 @@
 
   movptr(thread, tls);
 }
-
-bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
-  // Linux kernel guarantees that the first page is always unmapped. Don't
-  // assume anything more than that.
-  bool offset_in_first_page =   0 <= offset  &&  offset < os::vm_page_size();
-  return !offset_in_first_page;
-}
--- a/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_64.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/os_cpu/linux_x86/vm/assembler_linux_x86_64.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -65,22 +65,3 @@
        popq(rax);
    }
 }
-
-bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
-  // Exception handler checks the nmethod's implicit null checks table
-  // only when this method returns false.
-  if (UseCompressedOops) {
-    // The first page after heap_base is unmapped and
-    // the 'offset' is equal to [heap_base + offset] for
-    // narrow oop implicit null checks.
-    uintptr_t heap_base = (uintptr_t)Universe::heap_base();
-    if ((uintptr_t)offset >= heap_base) {
-      // Normalize offset for the next check.
-      offset = (intptr_t)(pointer_delta((void*)offset, (void*)heap_base, 1));
-    }
-  }
-  // Linux kernel guarantees that the first page is always unmapped. Don't
-  // assume anything more than that.
-  bool offset_in_first_page =   0 <= offset  &&  offset < os::vm_page_size();
-  return !offset_in_first_page;
-}
--- a/hotspot/src/os_cpu/solaris_sparc/vm/assembler_solaris_sparc.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/assembler_solaris_sparc.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -28,18 +28,6 @@
 #include <sys/trap.h>          // For trap numbers
 #include <v9/sys/psr_compat.h> // For V8 compatibility
 
-bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
-  // The first page of virtual addresses is unmapped on SPARC.
-  // Thus, any access the VM makes through a null pointer with an offset of
-  // less than 4K will get a recognizable SIGSEGV, which the signal handler
-  // will transform into a NullPointerException.
-  // (Actually, the first 64K or so is unmapped, but it's simpler
-  // to depend only on the first 4K or so.)
-
-  bool offset_in_first_page = 0 <= offset && offset < os::vm_page_size();
-  return !offset_in_first_page;
-}
-
 void MacroAssembler::read_ccr_trap(Register ccr_save) {
   // Execute a trap to get the PSR, mask and shift
   // to get the condition codes.
--- a/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_32.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_32.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -79,9 +79,3 @@
   if (thread != rax) popl(rax);
   popl(thread);
 }
-
-bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
-  // Identical to Sparc/Solaris code
-  bool offset_in_first_page =   0 <= offset  &&  offset < os::vm_page_size();
-  return !offset_in_first_page;
-}
--- a/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_64.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/os_cpu/solaris_x86/vm/assembler_solaris_x86_64.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -85,22 +85,3 @@
     popq(rax);
   }
 }
-
-bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
-  // Identical to Sparc/Solaris code
-
-  // Exception handler checks the nmethod's implicit null checks table
-  // only when this method returns false.
-  if (UseCompressedOops) {
-    // The first page after heap_base is unmapped and
-    // the 'offset' is equal to [heap_base + offset] for
-    // narrow oop implicit null checks.
-    uintptr_t heap_base = (uintptr_t)Universe::heap_base();
-    if ((uintptr_t)offset >= heap_base) {
-      // Normalize offset for the next check.
-      offset = (intptr_t)(pointer_delta((void*)offset, (void*)heap_base, 1));
-    }
-  }
-  bool offset_in_first_page = 0 <= offset && offset < os::vm_page_size();
-  return !offset_in_first_page;
-}
--- a/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_32.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_32.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -58,7 +58,3 @@
          "Thread Pointer Offset has not been initialized");
   movl(thread, Address(thread, ThreadLocalStorage::get_thread_ptr_offset()));
 }
-
-bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
-  return offset < 0 || (int)os::vm_page_size() <= offset;
-}
--- a/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_64.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/os_cpu/windows_x86/vm/assembler_windows_x86_64.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -65,19 +65,3 @@
        popq(rax);
    }
 }
-
-bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
-  // Exception handler checks the nmethod's implicit null checks table
-  // only when this method returns false.
-  if (UseCompressedOops) {
-    // The first page after heap_base is unmapped and
-    // the 'offset' is equal to [heap_base + offset] for
-    // narrow oop implicit null checks.
-    uintptr_t heap_base = (uintptr_t)Universe::heap_base();
-    if ((uintptr_t)offset >= heap_base) {
-      // Normalize offset for the next check.
-      offset = (intptr_t)(pointer_delta((void*)offset, (void*)heap_base, 1));
-    }
-  }
-  return offset < 0 || os::vm_page_size() <= offset;
-}
--- a/hotspot/src/share/vm/asm/assembler.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/share/vm/asm/assembler.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -246,6 +246,24 @@
   }
 }
 
+bool MacroAssembler::needs_explicit_null_check(intptr_t offset) {
+  // Exception handler checks the nmethod's implicit null checks table
+  // only when this method returns false.
+#ifndef SPARC
+  // Sparc does not have based addressing
+  if (UseCompressedOops) {
+    // The first page after heap_base is unmapped and
+    // the 'offset' is equal to [heap_base + offset] for
+    // narrow oop implicit null checks.
+    uintptr_t heap_base = (uintptr_t)Universe::heap_base();
+    if ((uintptr_t)offset >= heap_base) {
+      // Normalize offset for the next check.
+      offset = (intptr_t)(pointer_delta((void*)offset, (void*)heap_base, 1));
+    }
+  }
+#endif // SPARC
+  return offset < 0 || os::vm_page_size() <= offset;
+}
 
 #ifndef PRODUCT
 void Label::print_instructions(MacroAssembler* masm) const {
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -61,6 +61,8 @@
   if (_virtual_space != NULL) {
     delete _virtual_space;
     _virtual_space = NULL;
+    // Release memory reserved in the space.
+    rs.release();
   }
   return false;
 }
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -108,8 +108,8 @@
   // size than is needed or wanted for the perm gen.  Use the "compound
   // alignment" ReservedSpace ctor to avoid having to use the same page size for
   // all gens.
-  ReservedSpace heap_rs(pg_max_size, pg_align, og_max_size + yg_max_size,
-                        og_align);
+  ReservedHeapSpace heap_rs(pg_max_size, pg_align, og_max_size + yg_max_size,
+                            og_align);
   os::trace_page_sizes("ps perm", pg_min_size, pg_max_size, pg_page_sz,
                        heap_rs.base(), pg_max_size);
   os::trace_page_sizes("ps main", og_min_size + yg_min_size,
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -422,6 +422,8 @@
       return vspace;
     }
     delete vspace;
+    // Release memory reserved in the space.
+    rs.release();
   }
 
   return 0;
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -71,13 +71,8 @@
 
 void PSVirtualSpace::release() {
   DEBUG_ONLY(PSVirtualSpaceVerifier this_verifier(this));
-  if (reserved_low_addr() != NULL) {
-    if (special()) {
-      os::release_memory_special(reserved_low_addr(), reserved_size());
-    } else {
-      (void)os::release_memory(reserved_low_addr(), reserved_size());
-    }
-  }
+  // This may not release memory it didn't reserve.
+  // Use rs.release() to release the underlying memory instead.
   _reserved_low_addr = _reserved_high_addr = NULL;
   _committed_low_addr = _committed_high_addr = NULL;
   _special = false;
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -222,8 +222,8 @@
 
   *_total_reserved = total_reserved;
   *_n_covered_regions = n_covered_regions;
-  *heap_rs = ReservedSpace(total_reserved, alignment,
-                           UseLargePages, heap_address);
+  *heap_rs = ReservedHeapSpace(total_reserved, alignment,
+                               UseLargePages, heap_address);
 
   return heap_address;
 }
--- a/hotspot/src/share/vm/prims/jni.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/share/vm/prims/jni.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -2173,8 +2173,7 @@
     size_t size = os::vm_allocation_granularity();
     bad_address = os::reserve_memory(size);
     if (bad_address != NULL) {
-      os::commit_memory(bad_address, size);
-      os::protect_memory(bad_address, size);
+      os::protect_memory(bad_address, size, os::MEM_PROT_READ);
     }
   }
   return bad_address;
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -1176,8 +1176,7 @@
   // by ergonomics.
   if (MaxHeapSize <= max_heap_for_compressed_oops()) {
     if (FLAG_IS_DEFAULT(UseCompressedOops)) {
-      // Leave compressed oops off by default. Uncomment
-      // the following line to return it to default status.
+      // Turn off until bug is fixed.
       // FLAG_SET_ERGO(bool, UseCompressedOops, true);
     }
   } else {
--- a/hotspot/src/share/vm/runtime/os.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/share/vm/runtime/os.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -922,8 +922,9 @@
   // time and expensive page trap spinning, 'SerializePageLock' is used to block
   // the mutator thread if such case is encountered. See bug 6546278 for details.
   Thread::muxAcquire(&SerializePageLock, "serialize_thread_states");
-  os::protect_memory( (char *)os::get_memory_serialize_page(), os::vm_page_size() );
-  os::unguard_memory( (char *)os::get_memory_serialize_page(), os::vm_page_size() );
+  os::protect_memory((char *)os::get_memory_serialize_page(),
+                     os::vm_page_size(), MEM_PROT_READ, /*is_committed*/true );
+  os::unguard_memory((char *)os::get_memory_serialize_page(), os::vm_page_size());
   Thread::muxRelease(&SerializePageLock);
 }
 
--- a/hotspot/src/share/vm/runtime/os.hpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/share/vm/runtime/os.hpp	Wed Jul 05 16:39:18 2017 +0200
@@ -193,7 +193,11 @@
   static bool   commit_memory(char* addr, size_t size, size_t alignment_hint);
   static bool   uncommit_memory(char* addr, size_t bytes);
   static bool   release_memory(char* addr, size_t bytes);
-  static bool   protect_memory(char* addr, size_t bytes);
+
+  enum ProtType { MEM_PROT_NONE, MEM_PROT_READ, MEM_PROT_RW, MEM_PROT_RWX };
+  static bool   protect_memory(char* addr, size_t bytes, ProtType prot,
+                               bool is_committed = false);
+
   static bool   guard_memory(char* addr, size_t bytes);
   static bool   unguard_memory(char* addr, size_t bytes);
   static char*  map_memory(int fd, const char* file_name, size_t file_offset,
--- a/hotspot/src/share/vm/runtime/virtualspace.cpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/share/vm/runtime/virtualspace.cpp	Wed Jul 05 16:39:18 2017 +0200
@@ -28,12 +28,15 @@
 
 // ReservedSpace
 ReservedSpace::ReservedSpace(size_t size) {
-  initialize(size, 0, false, NULL);
+  initialize(size, 0, false, NULL, 0);
 }
 
 ReservedSpace::ReservedSpace(size_t size, size_t alignment,
-                             bool large, char* requested_address) {
-  initialize(size, alignment, large, requested_address);
+                             bool large,
+                             char* requested_address,
+                             const size_t noaccess_prefix) {
+  initialize(size+noaccess_prefix, alignment, large, requested_address,
+             noaccess_prefix);
 }
 
 char *
@@ -105,7 +108,8 @@
 ReservedSpace::ReservedSpace(const size_t prefix_size,
                              const size_t prefix_align,
                              const size_t suffix_size,
-                             const size_t suffix_align)
+                             const size_t suffix_align,
+                             const size_t noaccess_prefix)
 {
   assert(prefix_size != 0, "sanity");
   assert(prefix_align != 0, "sanity");
@@ -118,12 +122,16 @@
   assert((suffix_align & prefix_align - 1) == 0,
     "suffix_align not divisible by prefix_align");
 
+  // Add in noaccess_prefix to prefix_size;
+  const size_t adjusted_prefix_size = prefix_size + noaccess_prefix;
+  const size_t size = adjusted_prefix_size + suffix_size;
+
   // On systems where the entire region has to be reserved and committed up
   // front, the compound alignment normally done by this method is unnecessary.
   const bool try_reserve_special = UseLargePages &&
     prefix_align == os::large_page_size();
   if (!os::can_commit_large_page_memory() && try_reserve_special) {
-    initialize(prefix_size + suffix_size, prefix_align, true);
+    initialize(size, prefix_align, true, NULL, noaccess_prefix);
     return;
   }
 
@@ -131,15 +139,19 @@
   _size = 0;
   _alignment = 0;
   _special = false;
+  _noaccess_prefix = 0;
+
+  // Assert that if noaccess_prefix is used, it is the same as prefix_align.
+  assert(noaccess_prefix == 0 ||
+         noaccess_prefix == prefix_align, "noaccess prefix wrong");
 
   // Optimistically try to reserve the exact size needed.
-  const size_t size = prefix_size + suffix_size;
   char* addr = os::reserve_memory(size, NULL, prefix_align);
   if (addr == NULL) return;
 
   // Check whether the result has the needed alignment (unlikely unless
   // prefix_align == suffix_align).
-  const size_t ofs = size_t(addr) + prefix_size & suffix_align - 1;
+  const size_t ofs = size_t(addr) + adjusted_prefix_size & suffix_align - 1;
   if (ofs != 0) {
     // Wrong alignment.  Release, allocate more space and do manual alignment.
     //
@@ -153,11 +165,11 @@
     }
 
     const size_t extra = MAX2(ofs, suffix_align - ofs);
-    addr = reserve_and_align(size + extra, prefix_size, prefix_align,
+    addr = reserve_and_align(size + extra, adjusted_prefix_size, prefix_align,
                              suffix_size, suffix_align);
     if (addr == NULL) {
       // Try an even larger region.  If this fails, address space is exhausted.
-      addr = reserve_and_align(size + suffix_align, prefix_size,
+      addr = reserve_and_align(size + suffix_align, adjusted_prefix_size,
                                prefix_align, suffix_size, suffix_align);
     }
   }
@@ -165,10 +177,12 @@
   _base = addr;
   _size = size;
   _alignment = prefix_align;
+  _noaccess_prefix = noaccess_prefix;
 }
 
 void ReservedSpace::initialize(size_t size, size_t alignment, bool large,
-                               char* requested_address) {
+                               char* requested_address,
+                               const size_t noaccess_prefix) {
   const size_t granularity = os::vm_allocation_granularity();
   assert((size & granularity - 1) == 0,
          "size not aligned to os::vm_allocation_granularity()");
@@ -181,6 +195,7 @@
   _size = 0;
   _special = false;
   _alignment = 0;
+  _noaccess_prefix = 0;
   if (size == 0) {
     return;
   }
@@ -220,7 +235,8 @@
     // important.  If available space is not detected, return NULL.
 
     if (requested_address != 0) {
-      base = os::attempt_reserve_memory_at(size, requested_address);
+      base = os::attempt_reserve_memory_at(size,
+                                           requested_address-noaccess_prefix);
     } else {
       base = os::reserve_memory(size, NULL, alignment);
     }
@@ -259,6 +275,11 @@
   _base = base;
   _size = size;
   _alignment = MAX2(alignment, (size_t) os::vm_page_size());
+  _noaccess_prefix = noaccess_prefix;
+
+  // Assert that if noaccess_prefix is used, it is the same as alignment.
+  assert(noaccess_prefix == 0 ||
+         noaccess_prefix == _alignment, "noaccess prefix wrong");
 
   assert(markOopDesc::encode_pointer_as_mark(_base)->decode_pointer() == _base,
          "area must be distinguisable from marks for mark-sweep");
@@ -274,6 +295,7 @@
   _base = base;
   _size = size;
   _alignment = alignment;
+  _noaccess_prefix = 0;
   _special = special;
 }
 
@@ -320,17 +342,58 @@
 
 void ReservedSpace::release() {
   if (is_reserved()) {
+    char *real_base = _base - _noaccess_prefix;
+    const size_t real_size = _size + _noaccess_prefix;
     if (special()) {
-      os::release_memory_special(_base, _size);
+      os::release_memory_special(real_base, real_size);
     } else{
-      os::release_memory(_base, _size);
+      os::release_memory(real_base, real_size);
     }
     _base = NULL;
     _size = 0;
+    _noaccess_prefix = 0;
     _special = false;
   }
 }
 
+void ReservedSpace::protect_noaccess_prefix(const size_t size) {
+  // If there is noaccess prefix, return.
+  if (_noaccess_prefix == 0) return;
+
+  assert(_noaccess_prefix >= (size_t)os::vm_page_size(),
+         "must be at least page size big");
+
+  // Protect memory at the base of the allocated region.
+  // If special, the page was committed (only matters on windows)
+  if (!os::protect_memory(_base, _noaccess_prefix, os::MEM_PROT_NONE,
+                          _special)) {
+    fatal("cannot protect protection page");
+  }
+
+  _base += _noaccess_prefix;
+  _size -= _noaccess_prefix;
+  assert((size == _size) && ((uintptr_t)_base % _alignment == 0),
+         "must be exactly of required size and alignment");
+}
+
+ReservedHeapSpace::ReservedHeapSpace(size_t size, size_t alignment,
+                                     bool large, char* requested_address) :
+  ReservedSpace(size, alignment, large,
+                requested_address,
+                UseCompressedOops ? lcm(os::vm_page_size(), alignment) : 0) {
+  // Only reserved space for the java heap should have a noaccess_prefix
+  // if using compressed oops.
+  protect_noaccess_prefix(size);
+}
+
+ReservedHeapSpace::ReservedHeapSpace(const size_t prefix_size,
+                                     const size_t prefix_align,
+                                     const size_t suffix_size,
+                                     const size_t suffix_align) :
+  ReservedSpace(prefix_size, prefix_align, suffix_size, suffix_align,
+                UseCompressedOops ? lcm(os::vm_page_size(), prefix_align) : 0) {
+  protect_noaccess_prefix(prefix_size+suffix_size);
+}
 
 // VirtualSpace
 
@@ -348,6 +411,7 @@
   _lower_alignment        = 0;
   _middle_alignment       = 0;
   _upper_alignment        = 0;
+  _special                = false;
 }
 
 
@@ -402,7 +466,8 @@
 
 
 void VirtualSpace::release() {
-  (void)os::release_memory(low_boundary(), reserved_size());
+  // This does not release memory it never reserved.
+  // Caller must release via rs.release();
   _low_boundary           = NULL;
   _high_boundary          = NULL;
   _low                    = NULL;
--- a/hotspot/src/share/vm/runtime/virtualspace.hpp	Thu Jul 17 11:28:32 2008 -0700
+++ b/hotspot/src/share/vm/runtime/virtualspace.hpp	Wed Jul 05 16:39:18 2017 +0200
@@ -29,13 +29,15 @@
  private:
   char*  _base;
   size_t _size;
+  size_t _noaccess_prefix;
   size_t _alignment;
   bool   _special;
 
   // ReservedSpace
   ReservedSpace(char* base, size_t size, size_t alignment, bool special);
   void initialize(size_t size, size_t alignment, bool large,
-                  char* requested_address = NULL);
+                  char* requested_address,
+                  const size_t noaccess_prefix);
 
   // Release parts of an already-reserved memory region [addr, addr + len) to
   // get a new region that has "compound alignment."  Return the start of the
@@ -59,13 +61,19 @@
                           const size_t suffix_size,
                           const size_t suffix_align);
 
+ protected:
+  // Create protection page at the beginning of the space.
+  void protect_noaccess_prefix(const size_t size);
+
  public:
   // Constructor
   ReservedSpace(size_t size);
   ReservedSpace(size_t size, size_t alignment, bool large,
-                char* requested_address = NULL);
+                char* requested_address = NULL,
+                const size_t noaccess_prefix = 0);
   ReservedSpace(const size_t prefix_size, const size_t prefix_align,
-                const size_t suffix_size, const size_t suffix_align);
+                const size_t suffix_size, const size_t suffix_align,
+                const size_t noaccess_prefix);
 
   // Accessors
   char*  base()      const { return _base;      }
@@ -73,6 +81,8 @@
   size_t alignment() const { return _alignment; }
   bool   special()   const { return _special;   }
 
+  size_t noaccess_prefix()   const { return _noaccess_prefix;   }
+
   bool is_reserved() const { return _base != NULL; }
   void release();
 
@@ -104,6 +114,16 @@
   return last_part(partition_size, alignment());
 }
 
+// Class encapsulating behavior specific of memory space reserved for Java heap
+class ReservedHeapSpace : public ReservedSpace {
+public:
+  // Constructor
+  ReservedHeapSpace(size_t size, size_t forced_base_alignment,
+                    bool large, char* requested_address);
+  ReservedHeapSpace(const size_t prefix_size, const size_t prefix_align,
+                    const size_t suffix_size, const size_t suffix_align);
+};
+
 // VirtualSpace is data structure for committing a previously reserved address range in smaller chunks.
 
 class VirtualSpace VALUE_OBJ_CLASS_SPEC {
--- a/jdk/.hgtags	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/.hgtags	Wed Jul 05 16:39:18 2017 +0200
@@ -5,3 +5,4 @@
 02e4c5348592a8d7fc2cba28bc5f8e35c0e17277 jdk7-b28
 e21f4266466cd1306b176aaa08b2cd8337a9be3d jdk7-b29
 b6d6877c1155621a175dccd12dc14c54f938fb8b jdk7-b30
+b7474b739d13bacd9972f88ac91f6350b7b0be12 jdk7-b31
--- a/jdk/make/com/sun/java/pack/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/com/sun/java/pack/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -97,9 +97,6 @@
 	/D "J2SE_FTYPE=0x1L"
 
   RES = $(OBJDIR)/$(PGRM).res
-
-  # Files built here do not compile with warning level 3 if warnings are fatal
-  COMPILER_WARNINGS_FATAL=false
 else
   LDOUTPUT = -o #Have a space 
   LDDFLAGS += -lc
--- a/jdk/make/com/sun/security/auth/module/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/com/sun/security/auth/module/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -55,9 +55,6 @@
     EXTRA_LIBS += netapi32.lib user32.lib mpr.lib
   endif #fdlibm
   # code generates errors when compiled at warning level 3 and warnings are fatal
-  ifeq ($(ARCH_DATA_MODEL), 64)
-    COMPILER_WARNINGS_FATAL=false
-  endif # ARCH_DATA_MODEL
 endif # windows
 
 ifeq ($(PLATFORM), solaris)
--- a/jdk/make/common/Defs-linux.gmk	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/common/Defs-linux.gmk	Wed Jul 05 16:39:18 2017 +0200
@@ -149,10 +149,9 @@
 PIC_CODE_LARGE = -fPIC
 PIC_CODE_SMALL = -fpic
 GLOBAL_KPIC = $(PIC_CODE_LARGE)
+CFLAGS_COMMON   += $(GLOBAL_KPIC) $(GCC_WARNINGS)
 ifeq ($(ARCH), amd64)
-   CFLAGS_COMMON   += $(GLOBAL_KPIC) $(GCC_WARNINGS) -pipe
-else
-   CFLAGS_COMMON   += $(GLOBAL_KPIC) $(GCC_WARNINGS)
+ CFLAGS_COMMON += -pipe
 endif
 
 # Linux 64bit machines use Dwarf2, which can be HUGE, have fastdebug use -g1
--- a/jdk/make/common/Defs-solaris.gmk	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/common/Defs-solaris.gmk	Wed Jul 05 16:39:18 2017 +0200
@@ -40,6 +40,9 @@
 #   LDLIBS        (set $(EXTRA_LIBS) instead)
 #   LDLIBS_COMMON (set $(EXTRA_LIBS) instead)
 #   LINTFLAGS     (set $(OTHER_LINTFLAGS) instead)
+#
+# Note: CPPFLAGS are used in C and C++ compiles.
+#
 
 # Get shared JDK settings
 include $(JDK_MAKE_SHARED_DIR)/Defs.gmk
@@ -112,6 +115,10 @@
 #                       Required with many of the source files.
 #       -mt             Assume multi-threaded (important)
 #
+# The more unusual options to the Sun C compiler:
+#       +w              Print more warnings
+#       +w2             Maximum warnings
+#
 
 #
 # Debug flag for C and C++ compiler
@@ -140,15 +147,34 @@
   CXXFLAGS_DEBUG_OPTION  = -g0  $(CC_FASTDEBUG_OPT)
 endif
 
-CFLAGS_COMMON   = -v -mt -L$(OBJDIR) -xc99=%none
+CFLAGS_COMMON   = -L$(OBJDIR)
+
+# Do not allow C99 language features like declarations in code etc.
+CFLAGS_COMMON  += -xc99=%none
+
+# Allow C++ comments in C code
 CFLAGS_COMMON  += -xCC
-CFLAGS_COMMON  += -errshort=tags
+
+# Show error message tags on errors
+CFLAGS_COMMON   += -errshort=tags
+CXXFLAGS_COMMON += -errtags=yes
+
+# Optimization flags
 CFLAGS_OPT      = $(POPT)
+
+# Debug version flags
 CFLAGS_DBG      = $(CFLAGS_DEBUG_OPTION)
-CFLAGS_COMMON  +=  -Xa $(CFLAGS_REQUIRED)
+
+# Required C compiler flags
+CFLAGS_COMMON  += -Xa $(CFLAGS_REQUIRED)
+
+# Maximum warnings all the time
+CXXFLAGS_COMMON += +w
+CFLAGS_COMMON   += -v
 
 # Assume MT behavior all the time (important)
-CXXFLAGS_COMMON  = -mt
+CXXFLAGS_COMMON += -mt
+CFLAGS_COMMON   += -mt
 
 # Assume no C++ exceptions are used
 CXXFLAGS_COMMON += -features=no%except -DCC_NOEX
@@ -237,8 +263,8 @@
 # OTHER_CFLAGS += -DPERTURBALOT
 #
 
-CPPFLAGS_COMMON = -D$(ARCH_FAMILY) -D__solaris__ -D_REENTRANT 
-CPPFLAGS_OPT    = 
+CPPFLAGS_COMMON = -D__solaris__  -D$(ARCH_FAMILY)
+CPPFLAGS_OPT    = -DNDEBUG
 CPPFLAGS_DBG    = -DDEBUG
 
 ifeq ($(ARCH_FAMILY), i586)
--- a/jdk/make/common/Defs-windows.gmk	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/common/Defs-windows.gmk	Wed Jul 05 16:39:18 2017 +0200
@@ -283,7 +283,7 @@
 ifeq ($(ARCH), amd64)
   CPPFLAGS_COMMON += -D_AMD64_ -Damd64
 else
-  CPPFLAGS_COMMON += -DWIN32 -D_X86_ -Dx86 
+  CPPFLAGS_COMMON += -D_X86_ -Dx86 
 endif
 CPPFLAGS_COMMON += -DWIN32_LEAN_AND_MEAN
 
@@ -293,16 +293,23 @@
 CFLAGS_COMMON += -Fd$(OBJDIR)/$(basename $(@F)).pdb -Fm$(OBJDIR)/$(basename $(@F)).map
 
 #
+# Use -wdNNNN to disable warning NNNN.
+#   C4800 is a warning about bool performance casts (can't make go away)
+#
+COMPILER_WARNINGS_TO_IGNORE = 4800
+CFLAGS_COMMON += $(COMPILER_WARNINGS_TO_IGNORE:%=-wd%)
+
+#
 # Add warnings and extra on 64bit issues
 #
 ifeq ($(ARCH_DATA_MODEL), 64)
   CFLAGS_COMMON += -Wp64 
 endif
-CFLAGS_COMMON += -W$(COMPILER_WARNING_LEVEL)
 
 #
 # Treat compiler warnings as errors, if requested
 #
+CFLAGS_COMMON += -W$(COMPILER_WARNING_LEVEL)
 ifeq ($(COMPILER_WARNINGS_FATAL),true)
   CFLAGS_COMMON += -WX
 endif
@@ -352,17 +359,9 @@
   #    BUILD_WIN_SA=1
   # on the make command.
   ifdef BUILD_WIN_SA
-    ifeq ($(ARCH), amd64)
-      INCLUDE_SA = true
-    else
-      INCLUDE_SA = true
-    endif
+    INCLUDE_SA = true
   else
-    ifeq ($(ARCH), amd64)
-      INCLUDE_SA = false
-    else
-      INCLUDE_SA = false
-    endif
+    INCLUDE_SA = false
   endif
 endif
 
@@ -404,7 +403,6 @@
 else
   JDK_UPDATE_VER := 0
 endif
-JDK_VER = $(JDK_MINOR_VERSION),$(JDK_MICRO_VERSION),$(JDK_UPDATE_VER),$(COOKED_BUILD_NUMBER)
 
 RC_FLAGS = /l 0x409 /r
 
@@ -414,15 +412,23 @@
   RC_FLAGS += $(MS_RC_DEBUG_OPTION)
 endif 
 
-ifndef COPYRIGHT_YEAR
-    COPYRIGHT_YEAR = 2007 
-endif
+# Values for the RC variables defined in RC_FLAGS
+JDK_RC_BUILD_ID = $(FULL_VERSION)
+JDK_RC_COMPANY = $(COMPANY_NAME)
+JDK_RC_COMPONENT = $(PRODUCT_NAME) $(JDK_RC_PLATFORM_NAME) binary
+JDK_RC_VER = \
+    $(JDK_MINOR_VERSION).$(JDK_MICRO_VERSION).$(JDK_UPDATE_VER).$(COOKED_BUILD_NUMBER)
+JDK_RC_COPYRIGHT = Copyright \xA9 $(COPYRIGHT_YEAR)
+JDK_RC_NAME = \
+    $(PRODUCT_NAME) $(JDK_RC_PLATFORM_NAME) $(JDK_MINOR_VERSION) $(JDK_UPDATE_META_TAG)
+JDK_RC_FVER = \
+    $(JDK_MINOR_VERSION),$(JDK_MICRO_VERSION),$(JDK_UPDATE_VER),$(COOKED_BUILD_NUMBER)
 
 # J2SE name required here
-RC_FLAGS += -d "J2SE_BUILD_ID=$(FULL_VERSION)" \
-            -d "J2SE_COMPANY=$(COMPANY_NAME)" \
-            -d "J2SE_COMPONENT=$(PRODUCT_NAME) Platform SE binary" \
-            -d "J2SE_VER=$(JDK_MINOR_VERSION).$(JDK_MICRO_VERSION).$(JDK_UPDATE_VER).$(COOKED_BUILD_NUMBER)" \
-            -d "J2SE_COPYRIGHT=Copyright \xA9 $(COPYRIGHT_YEAR)" \
-            -d "J2SE_NAME=$(PRODUCT_NAME) Platform SE $(JDK_MINOR_VERSION) $(JDK_UPDATE_META_TAG)" \
-            -d "J2SE_FVER=$(JDK_VER)"
+RC_FLAGS += -d "J2SE_BUILD_ID=$(JDK_RC_BUILD_ID)" \
+            -d "J2SE_COMPANY=$(JDK_RC_COMPANY)" \
+            -d "J2SE_COMPONENT=$(JDK_RC_COMPONENT)" \
+            -d "J2SE_VER=$(JDK_RC_VER)" \
+            -d "J2SE_COPYRIGHT=$(JDK_RC_COPYRIGHT)" \
+            -d "J2SE_NAME=$(JDK_RC_NAME)" \
+            -d "J2SE_FVER=$(JDK_RC_FVER)"
--- a/jdk/make/common/Defs.gmk	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/common/Defs.gmk	Wed Jul 05 16:39:18 2017 +0200
@@ -703,7 +703,7 @@
 ifdef ALT_COPYRIGHT_YEAR
   COPYRIGHT_YEAR = $(ALT_COPYRIGHT_YEAR)
 else
-  COPYRIGHT_YEAR = $(shell $(DATE) '+%Y')
+  COPYRIGHT_YEAR := $(shell $(DATE) '+%Y')
 endif
 
 # Install of imported file (JDK_IMPORT_PATH, or some other external location)
--- a/jdk/make/common/shared/Compiler-gcc.gmk	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/common/shared/Compiler-gcc.gmk	Wed Jul 05 16:39:18 2017 +0200
@@ -73,23 +73,18 @@
     REQUIRED_CC_VER = 4.0
     REQUIRED_GCC_VER = 4.0.*
   else
-  ifeq ($(ARCH_DATA_MODEL), 32)
-    # i586
     REQUIRED_CC_VER = 3.2
-    REQUIRED_GCC_VER = 3.2.1*
-    REQUIRED_GCC_VER_INT = 3.2.1-7a
-  else
-  ifeq ($(ARCH), amd64)
-    # amd64
-    REQUIRED_CC_VER = 3.2
-    REQUIRED_GCC_VER = 3.2.*
-  endif
-  ifeq ($(ARCH), ia64)
-    # ia64
-    REQUIRED_CC_VER = 3.2
-    REQUIRED_GCC_VER = 2.9[56789].*
-  endif
-  endif
+    ifeq ($(ARCH_DATA_MODEL), 32)
+      REQUIRED_GCC_VER = 3.2.1*
+      REQUIRED_GCC_VER_INT = 3.2.1-7a
+    else
+      ifeq ($(ARCH), amd64)
+        REQUIRED_GCC_VER = 3.2.*
+      endif
+      ifeq ($(ARCH), ia64)
+        REQUIRED_GCC_VER = 2.9[56789].*
+      endif
+    endif
   endif
   # Option used to create a shared library
   SHARED_LIBRARY_FLAG = -shared -mimpure-text
--- a/jdk/make/common/shared/Defs-java.gmk	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/common/shared/Defs-java.gmk	Wed Jul 05 16:39:18 2017 +0200
@@ -107,7 +107,10 @@
 ifeq ($(DEBUG_CLASSFILES),true)
   JAVACFLAGS += -g
 endif
-ifeq ($(COMPILER_WARNINGS_FATAL), true)
+ifeq ($(JAVAC_MAX_WARNINGS), true)
+  JAVACFLAGS  += -Xlint:all
+endif
+ifeq ($(JAVAC_WARNINGS_FATAL), true)
   JAVACFLAGS  += -Werror
 endif
 
@@ -180,7 +183,10 @@
 # The javac options supplied to the boot javac is limited. This compiler
 #   should only be used to build the 'make/tools' sources, which are not
 #   class files that end up in the classes directory.
-ifeq ($(COMPILER_WARNINGS_FATAL), true)
+ifeq ($(JAVAC_MAX_WARNINGS), true)
+  BOOT_JAVACFLAGS  += -Xlint:all
+endif
+ifeq ($(JAVAC_WARNINGS_FATAL), true)
   BOOT_JAVACFLAGS  += -Werror
 endif
 BOOT_JAVACFLAGS  += -encoding ascii
--- a/jdk/make/common/shared/Defs.gmk	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/common/shared/Defs.gmk	Wed Jul 05 16:39:18 2017 +0200
@@ -188,16 +188,18 @@
 endif
 
 # Default names
-LAUNCHER_NAME = java
-PRODUCT_NAME = Java(TM)
-PRODUCT_SUFFIX = SE Runtime Environment
-COMPANY_NAME = Sun Microsystems, Inc.
-
 ifdef OPENJDK
   LAUNCHER_NAME = openjdk
   PRODUCT_NAME = OpenJDK
   PRODUCT_SUFFIX = Runtime Environment
-  COMPANY_NAME =
+  JDK_RC_PLATFORM_NAME = Platform
+  COMPANY_NAME = N/A
+else
+  LAUNCHER_NAME = java
+  PRODUCT_NAME = Java(TM)
+  PRODUCT_SUFFIX = SE Runtime Environment
+  JDK_RC_PLATFORM_NAME = Platform SE
+  COMPANY_NAME = Sun Microsystems, Inc.
 endif
 
 RUNTIME_NAME = $(PRODUCT_NAME) $(PRODUCT_SUFFIX)
--- a/jdk/make/common/shared/Platform.gmk	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/common/shared/Platform.gmk	Wed Jul 05 16:39:18 2017 +0200
@@ -373,35 +373,41 @@
   REQUIRED_DXSDK_VER = 0x0700
   OS_VENDOR = Microsoft
   # How much RAM does this machine have:
-  ifeq ($(USING_CYGWIN),true)
-    # CYGWIN has the 'free' utility
-    _MB_OF_MEMORY := \
-	 $(shell free -m | grep Mem: | awk '{print $$2;}' )
-  else
-    # Windows 2000 has the mem utility, but two memory areas
-    #    extended memory is what is beyond 1024M
-    _B_OF_EXT_MEMORY := \
-	 $(shell mem 2> $(DEV_NULL) | grep 'total contiguous extended memory' | awk '{print $$1;}')
-    ifeq ($(_B_OF_EXT_MEMORY),)
-      _B_OF_MEMORY := \
-	 $(shell mem 2> $(DEV_NULL) | grep 'total conventional memory' | awk '{print $$1;}')
+  ifeq ($(JDK_HAS_MEM_INFO),)
+    ifeq ($(USING_CYGWIN),true)
+      # CYGWIN has the 'free' utility
+      _MB_OF_MEMORY := \
+	   $(shell free -m | grep Mem: | awk '{print $$2;}' )
     else
-      _B_OF_MEMORY := \
-         $(shell expr 1048576 '+' $(_B_OF_EXT_MEMORY) 2> $(DEV_NULL))
+      # Windows 2000 has the mem utility, but two memory areas
+      #    extended memory is what is beyond 1024M
+      _B_OF_EXT_MEMORY := \
+	   $(shell mem 2> $(DEV_NULL) | \
+		   grep 'total contiguous extended memory' | awk '{print $$1;}')
+      ifeq ($(_B_OF_EXT_MEMORY),)
+          _B_OF_MEMORY := \
+	   $(shell mem 2> $(DEV_NULL) | \
+		   grep 'total conventional memory' | awk '{print $$1;}')
+      else
+        _B_OF_MEMORY := \
+           $(shell expr 1048576 '+' $(_B_OF_EXT_MEMORY) 2> $(DEV_NULL))
+      endif
+      ifeq ($(_B_OF_MEMORY),)
+        # Windows 2003 has the systeminfo utility use it if mem doesn't work
+        _MB_OF_MEMORY := \
+	    $(shell systeminfo 2> $(DEV_NULL) | \
+		    grep 'Total Physical Memory:' | \
+		    awk '{print $$4;}' | sed -e 's@,@@')
+      else
+        _MB_OF_MEMORY := $(shell expr $(_B_OF_MEMORY) '/' 1024 2> $(DEV_NULL))
+      endif
     endif
-    ifeq ($(_B_OF_MEMORY),)
-      # Windows 2003 has the systeminfo utility use it if mem doesn't work
-      _MB_OF_MEMORY := \
-	  $(shell systeminfo 2> $(DEV_NULL) | grep 'Total Physical Memory:' | awk '{print $$4;}' | sed -e 's@,@@')
+    ifeq ($(shell expr $(_MB_OF_MEMORY) '+' 0 2> $(DEV_NULL)), $(_MB_OF_MEMORY))
+      MB_OF_MEMORY := $(_MB_OF_MEMORY)
     else
-      _MB_OF_MEMORY := $(shell expr $(_B_OF_MEMORY) '/' 1024 2> $(DEV_NULL))
+      MB_OF_MEMORY := 512
     endif
   endif
-  ifeq ($(shell expr $(_MB_OF_MEMORY) '+' 0 2> $(DEV_NULL)), $(_MB_OF_MEMORY))
-    MB_OF_MEMORY := $(_MB_OF_MEMORY)
-  else
-    MB_OF_MEMORY := 512
-  endif
 endif
 
 REQUIRED_ZIP_VER = 2.2
@@ -446,30 +452,38 @@
 #    system swapping during the build.
 #    If we don't know, assume 512. Subtract 128 from MB for VM MAX.
 #    Don't set VM max over 1024-128=896.
-ifneq ($(MB_OF_MEMORY),)
-  LOW_MEMORY_MACHINE := $(shell \
-    if [ $(MB_OF_MEMORY) -le 512 ] ; then \
-      echo "true"; \
-    else \
-      echo "false"; \
-    fi)
-  MAX_VM_MEMORY := $(shell \
-    if [ $(MB_OF_MEMORY) -le 1024 ] ; then \
-      expr $(MB_OF_MEMORY) '-' 128 2> $(DEV_NULL) ; \
-    else \
-      echo "896"; \
-    fi)
-  MIN_VM_MEMORY := $(shell \
-    if [ $(MAX_VM_MEMORY) -le 128 ] ; then \
-      expr $(MAX_VM_MEMORY) '-' 8 2> $(DEV_NULL) ; \
-    else \
-      echo "128"; \
-    fi)
-else
-  MB_OF_MEMORY       := unknown
-  LOW_MEMORY_MACHINE := true
-  MAX_VM_MEMORY      := 384
-  MIN_VM_MEMORY      := 128
+ifeq ($(JDK_HAS_MEM_INFO),)
+  JDK_HAS_MEM_INFO=true
+  export JDK_HAS_MEM_INFO
+  ifneq ($(MB_OF_MEMORY),)
+    LOW_MEMORY_MACHINE := $(shell \
+      if [ $(MB_OF_MEMORY) -le 512 ] ; then \
+        echo "true"; \
+      else \
+        echo "false"; \
+      fi)
+    MAX_VM_MEMORY := $(shell \
+      if [ $(MB_OF_MEMORY) -le 1024 ] ; then \
+        expr $(MB_OF_MEMORY) '-' 128 2> $(DEV_NULL) ; \
+      else \
+        echo "896"; \
+      fi)
+    MIN_VM_MEMORY := $(shell \
+      if [ $(MAX_VM_MEMORY) -le 128 ] ; then \
+        expr $(MAX_VM_MEMORY) '-' 8 2> $(DEV_NULL) ; \
+      else \
+        echo "128"; \
+      fi)
+  else
+    MB_OF_MEMORY       := unknown
+    LOW_MEMORY_MACHINE := true
+    MAX_VM_MEMORY      := 384
+    MIN_VM_MEMORY      := 128
+  endif
+  export MB_OF_MEMORY
+  export LOW_MEMORY_MACHINE
+  export MAX_VM_MEMORY
+  export MIN_VM_MEMORY
 endif
 
 # If blanks in the username, use the first 4 words and pack them together
--- a/jdk/make/java/fdlibm/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/java/fdlibm/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -46,8 +46,6 @@
   _OPT = $(CC_NO_OPT)
   OTHER_CFLAGS =
   CPPFLAGS_DBG += -DLOGGING
-  # Files built here do not compile with warning level 3 if warnings are fatal
-  COMPILER_WARNINGS_FATAL=false
 endif
 
 #
--- a/jdk/make/java/hpi/windows/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/java/hpi/windows/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -37,8 +37,6 @@
 # windows compiler flags
 ifeq ($(PLATFORM),windows)
   CPPFLAGS_DBG += -DLOGGING
-  # Files built here do not compile with warning level 3 if warnings are fatal
-  COMPILER_WARNINGS_FATAL=false
 endif
 
 FILES_c = \
--- a/jdk/make/java/java/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/java/java/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -37,8 +37,6 @@
 # windows compiler flags
 ifeq ($(PLATFORM),windows)
   OTHER_CFLAGS =
-  # Files built here do not compile with warning level 3 if warnings are fatal
-  COMPILER_WARNINGS_FATAL=false
   # build directly into BINDIR...
   LIB_LOCATION = $(BINDIR)
   # Exported functions
--- a/jdk/make/java/java_crw_demo/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/java/java_crw_demo/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -48,11 +48,6 @@
 OTHER_INCLUDES = -I$(SRCDIR)
 
 #
-# This removes all asserts in the optimized version
-#
-CPPFLAGS_OPT += -DNDEBUG
-
-#
 # Library to compile.
 #
 include $(BUILDDIR)/common/Library.gmk
--- a/jdk/make/java/java_hprof_demo/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/java/java_hprof_demo/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -92,11 +92,6 @@
 INIT += $(LIBDIR)/jvm.hprof.txt
 
 #
-# This removes all asserts in the optimized version
-#
-CPPFLAGS_OPT += -DNDEBUG
-
-#
 # This puts logging code in
 #
 CPPFLAGS_DBG += -DHPROF_LOGGING
--- a/jdk/make/java/jli/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/java/jli/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -115,9 +115,6 @@
 		     -export:JLI_ManifestIterate \
 		     -export:JLI_SetTraceLauncher
 
-	# Files from zlib built here do not compile with warning level 3
-	# if warnings are fatal
-	COMPILER_WARNINGS_FATAL=false
 endif
 
 OTHER_INCLUDES += -I$(LAUNCHER_SHARE_SRC)
--- a/jdk/make/java/net/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/java/net/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -94,8 +94,6 @@
 
 ifeq ($(PLATFORM), windows)
   OTHER_LDLIBS = ws2_32.lib $(JVMLIB)
-  # Will not compile at warning level 3 if warnings are fatal
-  COMPILER_WARNINGS_FATAL=false
 else
   OTHER_LDLIBS = $(LIBSOCKET) -lnsl -ldl $(JVMLIB)
 endif
--- a/jdk/make/java/nio/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/java/nio/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -134,7 +134,6 @@
      $(OBJDIR)/../../../java.lang/java/$(OBJDIRNAME)/FileDescriptor_md.obj
 endif
 ifeq ($(PLATFORM), linux)
-COMPILER_WARNINGS_FATAL=true
 OTHER_LDLIBS += -L$(LIBDIR)/$(LIBARCH) -ljava -lnet -lpthread -ldl
 endif
 ifeq ($(PLATFORM), solaris)
--- a/jdk/make/java/npt/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/java/npt/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -53,11 +53,6 @@
 OTHER_INCLUDES = -I$(SRCDIR) -I$(PSRCDIR)
 
 #
-# This removes all asserts in the optimized version
-#
-CPPFLAGS_OPT += -DNDEBUG
-
-#
 # Library to compile.
 #
 include $(BUILDDIR)/common/Library.gmk
--- a/jdk/make/java/verify/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/java/verify/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -43,8 +43,6 @@
   #
   JAVALIB = 
   EXTRA_LIBS = 
-  # Files built here do not compile with warning level 3 if warnings are fatal
-  COMPILER_WARNINGS_FATAL=false
 endif
 
 #
--- a/jdk/make/java/zip/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/java/zip/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -49,9 +49,6 @@
 
 ifneq ($(PLATFORM), windows)
 OTHER_CFLAGS += -DUSE_MMAP
-else
-  # Files built here do not compile with warning level 3 if warnings are fatal
-  COMPILER_WARNINGS_FATAL=false
 endif
 
 #
--- a/jdk/make/jpda/back/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/jpda/back/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -53,11 +53,6 @@
 endif # PLATFORM
 
 #
-# This turns off all assert() checking in the optimized library
-#
-CPPFLAGS_OPT += -DNDEBUG
-
-#
 # This controls the ability to do logging in the library.
 #
 CPPFLAGS_DBG += -DJDWP_LOGGING
--- a/jdk/make/jpda/transport/shmem/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/jpda/transport/shmem/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -36,13 +36,6 @@
 
 include $(BUILDDIR)/common/Defs.gmk
 
-# 64-bit windows does not build at -W3 if warnings are fatal
-ifeq ($(PLATFORM), windows)
-  ifeq ($(ARCH_DATA_MODEL), 64)
-    COMPILER_WARNINGS_FATAL=false
-  endif
-endif
-
 FILES_c = \
         SharedMemoryTransport.c \
         SharedMemoryConnection.c \
--- a/jdk/make/jpda/transport/socket/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/jpda/transport/socket/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -36,11 +36,6 @@
 
 include $(BUILDDIR)/common/Defs.gmk
 
-ifeq ($(PLATFORM), windows)
-  # Files built here do not compile with warning level 3 if warnings are fatal
-  COMPILER_WARNINGS_FATAL=false
-endif
-
 ifeq ($(PLATFORM), linux)
   OTHER_LDLIBS += -lnsl $(LIBSOCKET) -lpthread
 endif
--- a/jdk/make/sun/cmm/kcms/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/sun/cmm/kcms/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -47,8 +47,6 @@
 ifeq ($(PLATFORM), windows)
   # Override the default version info with our own resource file (see 5043594)
   VERSIONINFO_RESOURCE = $(CLOSED_SRC)/share/native/sun/java2d/cmm/kcms/cmm.rc
-  # Files built here do not compile with warning level 3 if warnings are fatal
-  COMPILER_WARNINGS_FATAL=false
 endif
 
 # Rules
--- a/jdk/make/sun/font/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/sun/font/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -77,9 +77,6 @@
 
 ifeq ($(PLATFORM), windows)
 
-  # Files built here do not compile with warning level 3 if warnings are fatal
-  COMPILER_WARNINGS_FATAL=false
-
   LDLIBS += user32.lib gdi32.lib $(OBJDIR)/../../../sun.awt/awt/$(OBJDIRNAME)/awt.lib  
 
   OTHER_CFLAGS += -DCC_NOEX
--- a/jdk/make/sun/font/t2k/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/sun/font/t2k/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -64,9 +64,6 @@
 
 ifeq ($(PLATFORM), windows)
 
-  # Files built here do not compile with warning level 3 if warnings are fatal
-  COMPILER_WARNINGS_FATAL=false
-
   # t2k imports several shared methods from fontmanager.dll
   LDLIBS += user32.lib $(OBJDIR)/../../../sun.font/fontmanager/$(OBJDIRNAME)/fontmanager.lib
 
--- a/jdk/make/sun/jdbc/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/sun/jdbc/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -69,11 +69,6 @@
   INIT += $(ODBC_FAKE_LIBRARIES)
 endif
 
-ifeq ($(PLATFORM),windows)
-  # Files built here do not compile with warning level 3 if warnings are fatal
-  COMPILER_WARNINGS_FATAL=false
-endif
-
 #
 # Rules
 #
--- a/jdk/make/sun/jpeg/Makefile	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/make/sun/jpeg/Makefile	Wed Jul 05 16:39:18 2017 +0200
@@ -73,10 +73,5 @@
 #
 vpath %.c   $(SHARE_SRC)/native/$(PKGDIR)/image/jpeg
 
-ifeq ($(PLATFORM), windows)
-  # Files built here do not compile with warning level 3 if warnings are fatal
-  COMPILER_WARNINGS_FATAL=false
-endif # PLATFORM
-
 CLASSES.export += java.io.InputStream
 
--- a/jdk/src/share/back/eventFilter.c	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/back/eventFilter.c	Wed Jul 05 16:39:18 2017 +0200
@@ -492,14 +492,17 @@
                   char *sourceName = 0;
                   jvmtiError error = JVMTI_FUNC_PTR(gdata->jvmti,GetSourceFileName)
                                             (gdata->jvmti, clazz, &sourceName);
-                  if (error == JVMTI_ERROR_NONE) {
-                      if (sourceName == 0 || !patternStringMatch(sourceName, desiredNamePattern)) {
-                        /* We have no match */
-                        jvmtiDeallocate(sourceName);
-                        return JNI_FALSE;
-                      }
+                  if (error == JVMTI_ERROR_NONE &&
+                      sourceName != 0 &&
+                      patternStringMatch(sourceName, desiredNamePattern)) {
+                          // got a hit - report the event
+                          jvmtiDeallocate(sourceName);
+                          break;
                   }
+                  // We have no match, we have no source file name,
+                  // or we got a JVM TI error. Don't report the event.
                   jvmtiDeallocate(sourceName);
+                  return JNI_FALSE;
               }
               break;
           }
--- a/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/interceptor/DefaultMBeanServerInterceptor.java	Wed Jul 05 16:39:18 2017 +0200
@@ -84,8 +84,13 @@
 import com.sun.jmx.mbeanserver.Repository;
 import com.sun.jmx.mbeanserver.NamedObject;
 import com.sun.jmx.mbeanserver.Introspector;
+import com.sun.jmx.mbeanserver.MBeanInjector;
+import com.sun.jmx.mbeanserver.NotifySupport;
+import com.sun.jmx.mbeanserver.Repository.RegistrationContext;
 import com.sun.jmx.mbeanserver.Util;
 import com.sun.jmx.remote.util.EnvHelp;
+import javax.management.DynamicWrapperMBean;
+import javax.management.NotificationBroadcasterSupport;
 
 /**
  * This is the default class for MBean manipulation on the agent side. It
@@ -433,36 +438,26 @@
         if (instance instanceof MBeanRegistration)
             preDeregisterInvoke((MBeanRegistration) instance);
 
-        repository.remove(name);
-            // may throw InstanceNotFoundException
-
-        /**
-         * Checks if the unregistered MBean is a ClassLoader
-         * If so, it removes the  MBean from the default loader repository.
-         */
+        final Object resource = getResource(instance);
 
-        Object resource = getResource(instance);
-        if (resource instanceof ClassLoader
-            && resource != server.getClass().getClassLoader()) {
-            final ModifiableClassLoaderRepository clr =
-                instantiator.getClassLoaderRepository();
-            if (clr != null) clr.removeClassLoader(name);
-        }
+        // Unregisters the MBean from the repository.
+        // Returns the resource context that was used.
+        // The returned context does nothing for regular MBeans.
+        // For ClassLoader MBeans and JMXNamespace (and JMXDomain)
+        // MBeans - the context makes it possible to unregister these
+        // objects from the appropriate framework artifacts, such as
+        // the CLR or the dispatcher, from within the repository lock.
+        // In case of success, we also need to call context.done() at the
+        // end of this method.
+        //
+        final ResourceContext context =
+                unregisterFromRepository(resource, instance, name);
 
-        // ---------------------
-        // Send deletion event
-        // ---------------------
-        if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
-            MBEANSERVER_LOGGER.logp(Level.FINER,
-                    DefaultMBeanServerInterceptor.class.getName(),
-                    "unregisterMBean", "Send delete notification of object " +
-                    name.getCanonicalName());
-        }
-        sendNotification(MBeanServerNotification.UNREGISTRATION_NOTIFICATION,
-                         name);
 
         if (instance instanceof MBeanRegistration)
             postDeregisterInvoke((MBeanRegistration) instance);
+
+        context.done();
     }
 
     public ObjectInstance getObjectInstance(ObjectName name)
@@ -939,15 +934,22 @@
         }
 
         ObjectName logicalName = name;
+        logicalName = preRegister(mbean, server, name);
 
-        if (mbean instanceof MBeanRegistration) {
-            MBeanRegistration reg = (MBeanRegistration) mbean;
-            logicalName = preRegisterInvoke(reg, name, server);
+        // preRegister returned successfully, so from this point on we
+        // must call postRegister(false) if there is any problem.
+        boolean registered = false;
+        boolean registerFailed = false;
+        ResourceContext context = null;
+
+        try {
+            mbean = injectResources(mbean, server, logicalName);
+
             if (mbean instanceof DynamicMBean2) {
                 try {
                     ((DynamicMBean2) mbean).preRegister2(server, logicalName);
+                    registerFailed = true;  // until we succeed
                 } catch (Exception e) {
-                    postRegisterInvoke(reg, false, false);
                     if (e instanceof RuntimeException)
                         throw (RuntimeException) e;
                     if (e instanceof InstanceAlreadyExistsException)
@@ -960,86 +962,102 @@
                 logicalName =
                     ObjectName.getInstance(nonDefaultDomain(logicalName));
             }
-        }
+
+            checkMBeanPermission(classname, null, logicalName, "registerMBean");
 
-        checkMBeanPermission(classname, null, logicalName, "registerMBean");
+            if (logicalName == null) {
+                final RuntimeException wrapped =
+                        new IllegalArgumentException("No object name specified");
+                throw new RuntimeOperationsException(wrapped,
+                                                     "Exception occurred trying to register the MBean");
+            }
+
+            final Object resource = getResource(mbean);
 
-        final ObjectInstance result;
-        if (logicalName!=null) {
-            result = new ObjectInstance(logicalName, classname);
-            internal_addObject(mbean, logicalName);
-        } else {
-            if (mbean instanceof MBeanRegistration)
-                postRegisterInvoke((MBeanRegistration) mbean, false, true);
-            final RuntimeException wrapped =
-                new IllegalArgumentException("No object name specified");
-            throw new RuntimeOperationsException(wrapped,
-                        "Exception occurred trying to register the MBean");
+            // Register the MBean with the repository.
+            // Returns the resource context that was used.
+            // The returned context does nothing for regular MBeans.
+            // For ClassLoader MBeans and JMXNamespace (and JMXDomain)
+            // MBeans - the context makes it possible to register these
+            // objects with the appropriate framework artifacts, such as
+            // the CLR or the dispatcher, from within the repository lock.
+            // In case of success, we also need to call context.done() at the
+            // end of this method.
+            //
+            context = registerWithRepository(resource, mbean, logicalName);
+
+            registerFailed = false;
+            registered = true;
+        } finally {
+            postRegister(mbean, registered, registerFailed);
         }
 
-        if (mbean instanceof MBeanRegistration)
-            postRegisterInvoke((MBeanRegistration) mbean, true, false);
-
-        /**
-         * Checks if the newly registered MBean is a ClassLoader
-         * If so, tell the ClassLoaderRepository (CLR) about it.  We do
-         * this even if the object is a PrivateClassLoader.  In that
-         * case, the CLR remembers the loader for use when it is
-         * explicitly named (e.g. as the loader in createMBean) but
-         * does not add it to the list that is consulted by
-         * ClassLoaderRepository.loadClass.
-         */
-        final Object resource = getResource(mbean);
-        if (resource instanceof ClassLoader) {
-            final ModifiableClassLoaderRepository clr =
-                instantiator.getClassLoaderRepository();
-            if (clr == null) {
-                final RuntimeException wrapped =
-                    new IllegalArgumentException(
-                     "Dynamic addition of class loaders is not supported");
-                throw new RuntimeOperationsException(wrapped,
-           "Exception occurred trying to register the MBean as a class loader");
-            }
-            clr.addClassLoader(logicalName, (ClassLoader) resource);
-        }
-
-        return result;
+        context.done();
+        return new ObjectInstance(logicalName, classname);
     }
 
-    private static ObjectName preRegisterInvoke(MBeanRegistration moi,
-                                                ObjectName name,
-                                                MBeanServer mbs)
-            throws InstanceAlreadyExistsException, MBeanRegistrationException {
-
-        final ObjectName newName;
-
+    private static void throwMBeanRegistrationException(Throwable t, String where)
+    throws MBeanRegistrationException {
         try {
-            newName = moi.preRegister(mbs, name);
+            throw t;
         } catch (RuntimeException e) {
-                throw new RuntimeMBeanException(e,
-                           "RuntimeException thrown in preRegister method");
+                throw new RuntimeMBeanException(
+                        e, "RuntimeException thrown " + where);
         } catch (Error er) {
-                throw new RuntimeErrorException(er,
-                           "Error thrown in preRegister method");
+                throw new RuntimeErrorException(er, "Error thrown " + where);
         } catch (MBeanRegistrationException r) {
             throw r;
         } catch (Exception ex) {
-            throw new MBeanRegistrationException(ex,
-                          "Exception thrown in preRegister method");
+            throw new MBeanRegistrationException(ex, "Exception thrown " + where);
+        } catch (Throwable t1) {
+            throw new RuntimeException(t);  // neither Error nor Exception??
+        }
+    }
+
+    private static ObjectName preRegister(
+            DynamicMBean mbean, MBeanServer mbs, ObjectName name)
+            throws InstanceAlreadyExistsException, MBeanRegistrationException {
+
+        ObjectName newName = null;
+
+        try {
+            if (mbean instanceof MBeanRegistration)
+                newName = ((MBeanRegistration) mbean).preRegister(mbs, name);
+        } catch (Throwable t) {
+            throwMBeanRegistrationException(t, "in preRegister method");
         }
 
         if (newName != null) return newName;
         else return name;
     }
 
-    private static void postRegisterInvoke(MBeanRegistration moi,
-                                           boolean registrationDone,
-                                           boolean registerFailed) {
+    private static DynamicMBean injectResources(
+            DynamicMBean mbean, MBeanServer mbs, ObjectName name)
+    throws MBeanRegistrationException {
+        try {
+            Object resource = getResource(mbean);
+            MBeanInjector.inject(resource, mbs, name);
+            if (MBeanInjector.injectsSendNotification(resource)) {
+                NotificationBroadcasterSupport nbs =
+                        new NotificationBroadcasterSupport();
+                MBeanInjector.injectSendNotification(resource, nbs);
+                mbean = NotifySupport.wrap(mbean, nbs);
+            }
+            return mbean;
+        } catch (Throwable t) {
+            throwMBeanRegistrationException(t, "injecting @Resources");
+            return null;  // not reached
+        }
+    }
 
-        if (registerFailed && moi instanceof DynamicMBean2)
-            ((DynamicMBean2) moi).registerFailed();
+    private static void postRegister(
+            DynamicMBean mbean, boolean registrationDone, boolean registerFailed) {
+
+        if (registerFailed && mbean instanceof DynamicMBean2)
+            ((DynamicMBean2) mbean).registerFailed();
         try {
-            moi.postRegister(registrationDone);
+            if (mbean instanceof MBeanRegistration)
+                ((MBeanRegistration) mbean).postRegister(registrationDone);
         } catch (RuntimeException e) {
             throw new RuntimeMBeanException(e,
                       "RuntimeException thrown in postRegister method");
@@ -1053,17 +1071,8 @@
             throws MBeanRegistrationException {
         try {
             moi.preDeregister();
-        } catch (RuntimeException e) {
-            throw new RuntimeMBeanException(e,
-                         "RuntimeException thrown in preDeregister method");
-        } catch (Error er) {
-            throw new RuntimeErrorException(er,
-                         "Error thrown in preDeregister method");
-        } catch (MBeanRegistrationException t) {
-            throw t;
-        } catch (Exception ex) {
-            throw new MBeanRegistrationException(ex,
-                         "Exception thrown in preDeregister method");
+        } catch (Throwable t) {
+            throwMBeanRegistrationException(t, "in preDeregister method");
         }
     }
 
@@ -1104,12 +1113,19 @@
     }
 
     private static Object getResource(DynamicMBean mbean) {
-        if (mbean instanceof DynamicMBean2)
-            return ((DynamicMBean2) mbean).getResource();
+        if (mbean instanceof DynamicWrapperMBean)
+            return ((DynamicWrapperMBean) mbean).getWrappedObject();
         else
             return mbean;
     }
 
+    private static ClassLoader getResourceLoader(DynamicMBean mbean) {
+        if (mbean instanceof DynamicWrapperMBean)
+            return ((DynamicWrapperMBean) mbean).getWrappedClassLoader();
+        else
+            return mbean.getClass().getClassLoader();
+    }
+
     private ObjectName nonDefaultDomain(ObjectName name) {
         if (name == null || name.getDomain().length() > 0)
             return name;
@@ -1123,14 +1139,7 @@
            if one is supplied where it shouldn't be).  */
         final String completeName = domain + name;
 
-        try {
-            return new ObjectName(completeName);
-        } catch (MalformedObjectNameException e) {
-            final String msg =
-                "Unexpected default domain problem: " + completeName + ": " +
-                e;
-            throw EnvHelp.initCause(new IllegalArgumentException(msg), e);
-        }
+        return Util.newObjectName(completeName);
     }
 
     public String getDefaultDomain()  {
@@ -1211,7 +1220,7 @@
         }
 
         NotificationListener listenerWrapper =
-            getListenerWrapper(listener, name, broadcaster, true);
+            getListenerWrapper(listener, name, instance, true);
         broadcaster.addNotificationListener(listenerWrapper, filter, handback);
     }
 
@@ -1335,7 +1344,6 @@
         DynamicMBean instance = getMBean(name);
         checkMBeanPermission(instance, null, name,
                              "removeNotificationListener");
-        Object resource = getResource(instance);
 
         /* We could simplify the code by assigning broadcaster after
            assigning listenerWrapper, but that would change the error
@@ -1348,7 +1356,7 @@
             getNotificationBroadcaster(name, instance, reqClass);
 
         NotificationListener listenerWrapper =
-            getListenerWrapper(listener, name, resource, false);
+            getListenerWrapper(listener, name, instance, false);
 
         if (listenerWrapper == null)
             throw new ListenerNotFoundException("Unknown listener");
@@ -1366,8 +1374,10 @@
     private static <T extends NotificationBroadcaster>
             T getNotificationBroadcaster(ObjectName name, Object instance,
                                          Class<T> reqClass) {
-        if (instance instanceof DynamicMBean2)
-            instance = ((DynamicMBean2) instance).getResource();
+        if (reqClass.isInstance(instance))
+            return reqClass.cast(instance);
+        if (instance instanceof DynamicWrapperMBean)
+            instance = ((DynamicWrapperMBean) instance).getWrappedObject();
         if (reqClass.isInstance(instance))
             return reqClass.cast(instance);
         final RuntimeException exc =
@@ -1415,24 +1425,31 @@
         checkMBeanPermission(instance, null, name, "isInstanceOf");
 
         try {
-            if (instance instanceof DynamicMBean2) {
-                Object resource = ((DynamicMBean2) instance).getResource();
-                ClassLoader loader = resource.getClass().getClassLoader();
-                Class<?> c = Class.forName(className, false, loader);
-                return c.isInstance(resource);
-            }
+            Object resource = getResource(instance);
 
-            final String cn = getClassName(instance);
-            if (cn.equals(className))
+            final String resourceClassName =
+                    (resource instanceof DynamicMBean) ?
+                        getClassName((DynamicMBean) resource) :
+                        resource.getClass().getName();
+
+            if (resourceClassName.equals(className))
                 return true;
-            final ClassLoader cl = instance.getClass().getClassLoader();
+            final ClassLoader cl = getResourceLoader(instance);
 
             final Class<?> classNameClass = Class.forName(className, false, cl);
-            if (classNameClass.isInstance(instance))
+            if (classNameClass.isInstance(resource))
                 return true;
 
-            final Class<?> instanceClass = Class.forName(cn, false, cl);
-            return classNameClass.isAssignableFrom(instanceClass);
+            // Ensure that isInstanceOf(NotificationEmitter) is true when
+            // the MBean is a NotificationEmitter by virtue of a @Resource
+            // annotation specifying a SendNotification resource.
+            // This is a hack.
+            if (instance instanceof NotificationBroadcaster &&
+                    classNameClass.isAssignableFrom(NotificationEmitter.class))
+                return true;
+
+            final Class<?> resourceClass = Class.forName(resourceClassName, false, cl);
+            return classNameClass.isAssignableFrom(resourceClass);
         } catch (Exception x) {
             /* Could be SecurityException or ClassNotFoundException */
             if (MBEANSERVER_LOGGER.isLoggable(Level.FINEST)) {
@@ -1457,7 +1474,7 @@
 
         DynamicMBean instance = getMBean(mbeanName);
         checkMBeanPermission(instance, null, mbeanName, "getClassLoaderFor");
-        return getResource(instance).getClass().getClassLoader();
+        return getResourceLoader(instance);
     }
 
     /**
@@ -1489,40 +1506,6 @@
     }
 
     /**
-     * Adds a MBean in the repository
-     */
-    private void internal_addObject(DynamicMBean object, ObjectName logicalName)
-        throws InstanceAlreadyExistsException {
-
-        // ------------------------------
-        // ------------------------------
-
-        // Let the repository do the work.
-
-        try {
-           repository.addMBean(object, logicalName);
-        }  catch (InstanceAlreadyExistsException e) {
-            if (object instanceof MBeanRegistration) {
-                postRegisterInvoke((MBeanRegistration) object, false, true);
-            }
-            throw e;
-        }
-
-        // ---------------------
-        // Send create event
-        // ---------------------
-        if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
-            MBEANSERVER_LOGGER.logp(Level.FINER,
-                    DefaultMBeanServerInterceptor.class.getName(),
-                    "addObject", "Send create notification of object " +
-                    logicalName.getCanonicalName());
-        }
-
-        sendNotification(MBeanServerNotification.REGISTRATION_NOTIFICATION,
-                         logicalName ) ;
-    }
-
-    /**
      * Sends an MBeanServerNotifications with the specified type for the
      * MBean with the specified ObjectName
      */
@@ -1712,9 +1695,10 @@
      */
     private NotificationListener getListenerWrapper(NotificationListener l,
                                                     ObjectName name,
-                                                    Object mbean,
+                                                    DynamicMBean mbean,
                                                     boolean create) {
-        ListenerWrapper wrapper = new ListenerWrapper(l, name, mbean);
+        Object resource = getResource(mbean);
+        ListenerWrapper wrapper = new ListenerWrapper(l, name, resource);
         synchronized (listenerWrappers) {
             WeakReference<ListenerWrapper> ref = listenerWrappers.get(wrapper);
             if (ref != null) {
@@ -1758,6 +1742,7 @@
             listener.handleNotification(notification, handback);
         }
 
+        @Override
         public boolean equals(Object o) {
             if (!(o instanceof ListenerWrapper))
                 return false;
@@ -1774,6 +1759,7 @@
              */
         }
 
+        @Override
         public int hashCode() {
             return (System.identityHashCode(listener) ^
                     System.identityHashCode(mbean));
@@ -1851,4 +1837,213 @@
         }
     }
 
+    // ------------------------------------------------------------------
+    //
+    // Dealing with registration of special MBeans in the repository.
+    //
+    // ------------------------------------------------------------------
+
+    /**
+     * A RegistrationContext that makes it possible to perform additional
+     * post registration actions (or post unregistration actions) outside
+     * of the repository lock, once postRegister (or postDeregister) has
+     * been called.
+     * The method {@code done()} will be called in registerMBean or
+     * unregisterMBean, at the end.
+     */
+    private static interface ResourceContext extends RegistrationContext {
+        public void done();
+        /** An empty ResourceContext which does nothing **/
+        public static final ResourceContext NONE = new ResourceContext() {
+            public void done() {}
+            public void registering() {}
+            public void unregistered() {}
+        };
+    }
+
+    /**
+     * Adds a MBean in the repository,
+     * sends MBeanServerNotification.REGISTRATION_NOTIFICATION,
+     * returns ResourceContext for special resources such as ClassLoaders
+     * or JMXNamespaces. For regular MBean this method returns
+     * ResourceContext.NONE.
+     * @return a ResourceContext for special resources such as ClassLoaders
+     *         or JMXNamespaces.
+     */
+    private ResourceContext registerWithRepository(
+            final Object resource,
+            final DynamicMBean object,
+            final ObjectName logicalName)
+            throws InstanceAlreadyExistsException,
+            MBeanRegistrationException {
+
+        // Creates a registration context, if needed.
+        //
+        final ResourceContext context =
+                makeResourceContextFor(resource, logicalName);
+
+
+        repository.addMBean(object, logicalName, context);
+        // May throw InstanceAlreadyExistsException
+
+        // ---------------------
+        // Send create event
+        // ---------------------
+        if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
+            MBEANSERVER_LOGGER.logp(Level.FINER,
+                    DefaultMBeanServerInterceptor.class.getName(),
+                    "addObject", "Send create notification of object " +
+                    logicalName.getCanonicalName());
+        }
+
+        sendNotification(
+                MBeanServerNotification.REGISTRATION_NOTIFICATION,
+                logicalName);
+
+        return context;
+    }
+
+    /**
+     * Removes a MBean in the repository,
+     * sends MBeanServerNotification.UNREGISTRATION_NOTIFICATION,
+     * returns ResourceContext for special resources such as ClassLoaders
+     * or JMXNamespaces, or null. For regular MBean this method returns
+     * ResourceContext.NONE.
+     *
+     * @return a ResourceContext for special resources such as ClassLoaders
+     *         or JMXNamespaces.
+     */
+    private ResourceContext unregisterFromRepository(
+            final Object resource,
+            final DynamicMBean object,
+            final ObjectName logicalName)
+            throws InstanceNotFoundException {
+
+        // Creates a registration context, if needed.
+        //
+        final ResourceContext context =
+                makeResourceContextFor(resource, logicalName);
+
+
+        repository.remove(logicalName, context);
+
+        // ---------------------
+        // Send deletion event
+        // ---------------------
+        if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
+            MBEANSERVER_LOGGER.logp(Level.FINER,
+                    DefaultMBeanServerInterceptor.class.getName(),
+                    "unregisterMBean", "Send delete notification of object " +
+                    logicalName.getCanonicalName());
+        }
+
+        sendNotification(MBeanServerNotification.UNREGISTRATION_NOTIFICATION,
+                logicalName);
+        return context;
+    }
+
+    /**
+     * Registers a ClassLoader with the CLR.
+     * This method is called by the ResourceContext from within the
+     * repository lock.
+     * @param loader       The ClassLoader.
+     * @param logicalName  The ClassLoader MBean ObjectName.
+     */
+    private void addClassLoader(ClassLoader loader,
+            final ObjectName logicalName) {
+        /**
+         * Called when the newly registered MBean is a ClassLoader
+         * If so, tell the ClassLoaderRepository (CLR) about it.  We do
+         * this even if the loader is a PrivateClassLoader.  In that
+         * case, the CLR remembers the loader for use when it is
+         * explicitly named (e.g. as the loader in createMBean) but
+         * does not add it to the list that is consulted by
+         * ClassLoaderRepository.loadClass.
+         */
+        final ModifiableClassLoaderRepository clr =
+                instantiator.getClassLoaderRepository();
+        if (clr == null) {
+            final RuntimeException wrapped =
+                    new IllegalArgumentException(
+                    "Dynamic addition of class loaders" +
+                    " is not supported");
+            throw new RuntimeOperationsException(wrapped,
+                    "Exception occurred trying to register" +
+                    " the MBean as a class loader");
+        }
+        clr.addClassLoader(logicalName, loader);
+    }
+
+    /**
+     * Unregisters a ClassLoader from the CLR.
+     * This method is called by the ResourceContext from within the
+     * repository lock.
+     * @param loader       The ClassLoader.
+     * @param logicalName  The ClassLoader MBean ObjectName.
+     */
+    private void removeClassLoader(ClassLoader loader,
+            final ObjectName logicalName) {
+        /**
+         * Removes the  MBean from the default loader repository.
+         */
+        if (loader != server.getClass().getClassLoader()) {
+            final ModifiableClassLoaderRepository clr =
+                    instantiator.getClassLoaderRepository();
+            if (clr != null) {
+                clr.removeClassLoader(logicalName);
+            }
+        }
+    }
+
+    /**
+     * Creates a ResourceContext for a ClassLoader MBean.
+     * The resource context makes it possible to add the ClassLoader to
+     * (ResourceContext.registering) or resp. remove the ClassLoader from
+     * (ResourceContext.unregistered) the CLR
+     * when the associated MBean is added to or resp. removed from the
+     * repository.
+     *
+     * @param loader       The ClassLoader MBean being registered or
+     *                     unregistered.
+     * @param logicalName  The name of the ClassLoader MBean.
+     * @return a ResourceContext that takes in charge the addition or removal
+     *         of the loader to or from the CLR.
+     */
+    private ResourceContext createClassLoaderContext(
+            final ClassLoader loader,
+            final ObjectName logicalName) {
+        return new ResourceContext() {
+
+            public void registering() {
+                addClassLoader(loader, logicalName);
+            }
+
+            public void unregistered() {
+                removeClassLoader(loader, logicalName);
+            }
+
+            public void done() {
+            }
+        };
+    }
+
+    /**
+     * Creates a ResourceContext for the given resource.
+     * If the resource does not need a ResourceContext, returns
+     * ResourceContext.NONE.
+     * At this time, only JMXNamespaces and ClassLoaders need a
+     * ResourceContext.
+     *
+     * @param resource     The resource being registered or unregistered.
+     * @param logicalName  The name of the associated MBean.
+     * @return
+     */
+    private ResourceContext makeResourceContextFor(Object resource,
+            ObjectName logicalName) {
+        if (resource instanceof ClassLoader) {
+            return createClassLoaderContext((ClassLoader) resource,
+                    logicalName);
+        }
+        return ResourceContext.NONE;
+    }
 }
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/DefaultMXBeanMappingFactory.java	Wed Jul 05 16:39:18 2017 +0200
@@ -686,7 +686,7 @@
                     final String msg =
                         "Cannot convert SortedSet with non-null comparator: " +
                         comparator;
-                    throw new OpenDataException(msg);
+                    throw openDataException(msg, new IllegalArgumentException(msg));
                 }
             }
             final Object[] openArray = (Object[])
@@ -800,7 +800,7 @@
                     final String msg =
                         "Cannot convert SortedMap with non-null comparator: " +
                         comparator;
-                    throw new OpenDataException(msg);
+                    throw openDataException(msg, new IllegalArgumentException(msg));
                 }
             }
             final TabularType tabularType = (TabularType) getOpenType();
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/DynamicMBean2.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/DynamicMBean2.java	Wed Jul 05 16:39:18 2017 +0200
@@ -25,7 +25,7 @@
 
 package com.sun.jmx.mbeanserver;
 
-import javax.management.DynamicMBean;
+import javax.management.DynamicWrapperMBean;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
 
@@ -35,17 +35,7 @@
  *
  * @since 1.6
  */
-public interface DynamicMBean2 extends DynamicMBean {
-    /**
-     * The resource corresponding to this MBean.  This is the object whose
-     * class name should be reflected by the MBean's
-     * getMBeanInfo().getClassName() for example.  For a "plain"
-     * DynamicMBean it will be "this".  For an MBean that wraps another
-     * object, like javax.management.StandardMBean, it will be the wrapped
-     * object.
-     */
-    public Object getResource();
-
+public interface DynamicMBean2 extends DynamicWrapperMBean {
     /**
      * The name of this MBean's class, as used by permission checks.
      * This is typically equal to getResource().getClass().getName().
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Introspector.java	Wed Jul 05 16:39:18 2017 +0200
@@ -25,23 +25,39 @@
 
 package com.sun.jmx.mbeanserver;
 
+import com.sun.jmx.remote.util.EnvHelp;
+import java.beans.BeanInfo;
+import java.beans.PropertyDescriptor;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Array;
 import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
 import java.lang.reflect.UndeclaredThrowableException;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.logging.Level;
+import javax.management.AttributeNotFoundException;
+import javax.management.Description;
 
 import javax.management.Descriptor;
+import javax.management.DescriptorFields;
 import javax.management.DescriptorKey;
 import javax.management.DynamicMBean;
 import javax.management.ImmutableDescriptor;
+import javax.management.MBean;
 import javax.management.MBeanInfo;
+import javax.management.MXBean;
 import javax.management.NotCompliantMBeanException;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.MXBeanMappingFactory;
 
+import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;
+import com.sun.jmx.mbeanserver.Util;
 import com.sun.jmx.remote.util.EnvHelp;
 import java.beans.BeanInfo;
 import java.beans.PropertyDescriptor;
@@ -133,8 +149,12 @@
         }
     }
 
-    public static void checkCompliance(Class mbeanClass)
-        throws NotCompliantMBeanException {
+    public static void checkCompliance(Class<?> mbeanClass)
+    throws NotCompliantMBeanException {
+
+        // Check that @Resource is used correctly (if it used).
+        MBeanInjector.validate(mbeanClass);
+
         // Is DynamicMBean?
         //
         if (DynamicMBean.class.isAssignableFrom(mbeanClass))
@@ -157,21 +177,39 @@
         } catch (NotCompliantMBeanException e) {
             mxbeanException = e;
         }
+        // Is @MBean or @MXBean class?
+        // In fact we find @MBean or @MXBean as a hacky variant of
+        // getStandardMBeanInterface or getMXBeanInterface.  If we get here
+        // then nothing worked.
         final String msg =
             "MBean class " + mbeanClass.getName() + " does not implement " +
-            "DynamicMBean, neither follows the Standard MBean conventions (" +
-            mbeanException.toString() + ") nor the MXBean conventions (" +
-            mxbeanException.toString() + ")";
+            "DynamicMBean; does not follow the Standard MBean conventions (" +
+            mbeanException.toString() + "); does not follow the MXBean conventions (" +
+            mxbeanException.toString() + "); and does not have or inherit the @" +
+            MBean.class.getSimpleName() + " or @" + MXBean.class.getSimpleName() +
+            " annotation";
         throw new NotCompliantMBeanException(msg);
     }
 
+    /**
+     * <p>Make a DynamicMBean out of the existing MBean object.  The object
+     * may already be a DynamicMBean, or it may be a Standard MBean or
+     * MXBean, possibly defined using {@code @MBean} or {@code @MXBean}.</p>
+     * @param mbean the object to convert to a DynamicMBean.
+     * @param <T> a type parameter defined for implementation convenience
+     * (which would have to be removed if this method were part of the public
+     * API).
+     * @return the converted DynamicMBean.
+     * @throws NotCompliantMBeanException if {@code mbean} is not a compliant
+     * MBean object, including the case where it is null.
+     */
     public static <T> DynamicMBean makeDynamicMBean(T mbean)
     throws NotCompliantMBeanException {
         if (mbean == null)
             throw new NotCompliantMBeanException("Null MBean object");
         if (mbean instanceof DynamicMBean)
             return (DynamicMBean) mbean;
-        final Class mbeanClass = mbean.getClass();
+        final Class<?> mbeanClass = mbean.getClass();
         Class<? super T> c = null;
         try {
             c = Util.cast(getStandardMBeanInterface(mbeanClass));
@@ -270,7 +308,7 @@
      *         Return <code>null</code> if the MBean is a DynamicMBean,
      *         or if no MBean interface is found.
      */
-    public static Class getMBeanInterface(Class baseClass) {
+    public static Class<?> getMBeanInterface(Class<?> baseClass) {
         // Check if the given class implements the MBean interface
         // or the Dynamic MBean interface
         if (isDynamic(baseClass)) return null;
@@ -291,10 +329,12 @@
      * @throws NotCompliantMBeanException The specified class is
      * not a JMX compliant Standard MBean.
      */
-    public static Class getStandardMBeanInterface(Class baseClass)
-        throws NotCompliantMBeanException {
-        Class current = baseClass;
-        Class mbeanInterface = null;
+    public static <T> Class<? super T> getStandardMBeanInterface(Class<T> baseClass)
+    throws NotCompliantMBeanException {
+        if (baseClass.isAnnotationPresent(MBean.class))
+            return baseClass;
+        Class<? super T> current = baseClass;
+        Class<? super T> mbeanInterface = null;
         while (current != null) {
             mbeanInterface =
                 findMBeanInterface(current, current.getName());
@@ -321,8 +361,10 @@
      * @throws NotCompliantMBeanException The specified class is
      * not a JMX compliant MXBean.
      */
-    public static Class getMXBeanInterface(Class baseClass)
+    public static <T> Class<? super T> getMXBeanInterface(Class<T> baseClass)
         throws NotCompliantMBeanException {
+        if (hasMXBeanAnnotation(baseClass))
+            return baseClass;
         try {
             return MXBeanSupport.findMXBeanInterface(baseClass);
         } catch (Exception e) {
@@ -345,19 +387,24 @@
      * ------------------------------------------
      */
 
+    static boolean hasMXBeanAnnotation(Class<?> c) {
+        MXBean m = c.getAnnotation(MXBean.class);
+        return (m != null && m.value());
+    }
 
     /**
      * Try to find the MBean interface corresponding to the class aName
      * - i.e. <i>aName</i>MBean, from within aClass and its superclasses.
      **/
-    private static Class findMBeanInterface(Class aClass, String aName) {
-        Class current = aClass;
+    private static <T> Class<? super T> findMBeanInterface(
+            Class<T> aClass, String aName) {
+        Class<? super T> current = aClass;
         while (current != null) {
-            final Class[] interfaces = current.getInterfaces();
+            final Class<?>[] interfaces = current.getInterfaces();
             final int len = interfaces.length;
             for (int i=0;i<len;i++)  {
-                final Class inter =
-                    implementsMBean(interfaces[i], aName);
+                Class<? super T> inter = Util.cast(interfaces[i]);
+                inter = implementsMBean(inter, aName);
                 if (inter != null) return inter;
             }
             current = current.getSuperclass();
@@ -365,6 +412,48 @@
         return null;
     }
 
+    public static String descriptionForElement(AnnotatedElement elmt) {
+        if (elmt == null)
+            return null;
+        Description d = elmt.getAnnotation(Description.class);
+        if (d == null)
+            return null;
+        return d.value();
+    }
+
+    public static String descriptionForParameter(
+            Annotation[] parameterAnnotations) {
+        for (Annotation a : parameterAnnotations) {
+            if (a instanceof Description)
+                return ((Description) a).value();
+        }
+        return null;
+    }
+
+    public static String nameForParameter(
+            Annotation[] parameterAnnotations) {
+        for (Annotation a : parameterAnnotations) {
+            Class<? extends Annotation> ac = a.annotationType();
+            // You'd really have to go out of your way to have more than
+            // one @Name annotation, so we don't check for that.
+            if (ac.getSimpleName().equals("Name")) {
+                try {
+                    Method value = ac.getMethod("value");
+                    if (value.getReturnType() == String.class &&
+                            value.getParameterTypes().length == 0) {
+                        return (String) value.invoke(a);
+                    }
+                } catch (Exception e) {
+                    MBEANSERVER_LOGGER.log(
+                            Level.WARNING,
+                            "Unexpected exception getting @" + ac.getName(),
+                            e);
+                }
+            }
+        }
+        return null;
+    }
+
     public static Descriptor descriptorForElement(final AnnotatedElement elmt) {
         if (elmt == null)
             return ImmutableDescriptor.EMPTY_DESCRIPTOR;
@@ -372,41 +461,18 @@
         return descriptorForAnnotations(annots);
     }
 
+    public static Descriptor descriptorForAnnotation(Annotation annot) {
+        return descriptorForAnnotations(new Annotation[] {annot});
+    }
+
     public static Descriptor descriptorForAnnotations(Annotation[] annots) {
         if (annots.length == 0)
             return ImmutableDescriptor.EMPTY_DESCRIPTOR;
         Map<String, Object> descriptorMap = new HashMap<String, Object>();
         for (Annotation a : annots) {
-            Class<? extends Annotation> c = a.annotationType();
-            Method[] elements = c.getMethods();
-            for (Method element : elements) {
-                DescriptorKey key = element.getAnnotation(DescriptorKey.class);
-                if (key != null) {
-                    String name = key.value();
-                    Object value;
-                    try {
-                        value = element.invoke(a);
-                    } catch (RuntimeException e) {
-                        // we don't expect this - except for possibly
-                        // security exceptions?
-                        // RuntimeExceptions shouldn't be "UndeclaredThrowable".
-                        // anyway...
-                        //
-                        throw e;
-                    } catch (Exception e) {
-                        // we don't expect this
-                        throw new UndeclaredThrowableException(e);
-                    }
-                    value = annotationToField(value);
-                    Object oldValue = descriptorMap.put(name, value);
-                    if (oldValue != null && !equals(oldValue, value)) {
-                        final String msg =
-                            "Inconsistent values for descriptor field " + name +
-                            " from annotations: " + value + " :: " + oldValue;
-                        throw new IllegalArgumentException(msg);
-                    }
-                }
-            }
+            if (a instanceof DescriptorFields)
+                addDescriptorFieldsToMap(descriptorMap, (DescriptorFields) a);
+            addAnnotationFieldsToMap(descriptorMap, a);
         }
 
         if (descriptorMap.isEmpty())
@@ -415,6 +481,62 @@
             return new ImmutableDescriptor(descriptorMap);
     }
 
+    private static void addDescriptorFieldsToMap(
+            Map<String, Object> descriptorMap, DescriptorFields df) {
+        for (String field : df.value()) {
+            int eq = field.indexOf('=');
+            if (eq < 0) {
+                throw new IllegalArgumentException(
+                        "@DescriptorFields string must contain '=': " +
+                        field);
+            }
+            String name = field.substring(0, eq);
+            String value = field.substring(eq + 1);
+            addToMap(descriptorMap, name, value);
+        }
+    }
+
+    private static void addAnnotationFieldsToMap(
+            Map<String, Object> descriptorMap, Annotation a) {
+        Class<? extends Annotation> c = a.annotationType();
+        Method[] elements = c.getMethods();
+        for (Method element : elements) {
+            DescriptorKey key = element.getAnnotation(DescriptorKey.class);
+            if (key != null) {
+                String name = key.value();
+                Object value;
+                try {
+                    value = element.invoke(a);
+                } catch (RuntimeException e) {
+                    // we don't expect this - except for possibly
+                    // security exceptions?
+                    // RuntimeExceptions shouldn't be "UndeclaredThrowable".
+                    // anyway...
+                    throw e;
+                } catch (Exception e) {
+                    // we don't expect this
+                    throw new UndeclaredThrowableException(e);
+                }
+                if (!key.omitIfDefault() ||
+                        !equals(value, element.getDefaultValue())) {
+                    value = annotationToField(value);
+                    addToMap(descriptorMap, name, value);
+                }
+            }
+        }
+    }
+
+    private static void addToMap(
+            Map<String, Object> descriptorMap, String name, Object value) {
+        Object oldValue = descriptorMap.put(name, value);
+        if (oldValue != null && !equals(oldValue, value)) {
+            final String msg =
+                "Inconsistent values for descriptor field " + name +
+                " from annotations: " + value + " :: " + oldValue;
+            throw new IllegalArgumentException(msg);
+        }
+    }
+
     /**
      * Throws a NotCompliantMBeanException or a SecurityException.
      * @param notCompliant the class which was under examination
@@ -473,8 +595,13 @@
         // The only other possibility is that the value is another
         // annotation, or that the language has evolved since this code
         // was written.  We don't allow for either of those currently.
+        // If it is indeed another annotation, then x will be a proxy
+        // with an unhelpful name like $Proxy2.  So we extract the
+        // proxy's interface to use that in the exception message.
+        if (Proxy.isProxyClass(c))
+            c = c.getInterfaces()[0];  // array "can't be empty"
         throw new IllegalArgumentException("Illegal type for annotation " +
-                "element: " + x.getClass().getName());
+                "element using @DescriptorKey: " + c.getName());
     }
 
     // This must be consistent with the check for duplicate field values in
@@ -490,15 +617,15 @@
      * @param c The interface to be tested
      * @param clName The name of the class implementing this interface
      */
-    private static Class implementsMBean(Class c, String clName) {
+    private static <T> Class<? super T> implementsMBean(Class<T> c, String clName) {
         String clMBeanName = clName + "MBean";
         if (c.getName().equals(clMBeanName)) {
             return c;
         }
-        Class[] interfaces = c.getInterfaces();
+        Class<?>[] interfaces = c.getInterfaces();
         for (int i = 0;i < interfaces.length; i++) {
             if (interfaces[i].getName().equals(clMBeanName))
-                return interfaces[i];
+                return Util.cast(interfaces[i]);
         }
 
         return null;
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanAnalyzer.java	Wed Jul 05 16:39:18 2017 +0200
@@ -33,6 +33,10 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import javax.management.MBean;
+import javax.management.MXBean;
+import javax.management.ManagedAttribute;
+import javax.management.ManagedOperation;
 import javax.management.NotCompliantMBeanException;
 
 /**
@@ -125,18 +129,26 @@
         for (Method m : methods) {
             final String name = m.getName();
             final int nParams = m.getParameterTypes().length;
+            final boolean managedOp = m.isAnnotationPresent(ManagedOperation.class);
+            final boolean managedAttr = m.isAnnotationPresent(ManagedAttribute.class);
+            if (managedOp && managedAttr) {
+                throw new NotCompliantMBeanException("Method " + name +
+                        " has both @ManagedOperation and @ManagedAttribute");
+            }
 
             final M cm = introspector.mFrom(m);
 
             String attrName = "";
-            if (name.startsWith("get"))
-                attrName = name.substring(3);
-            else if (name.startsWith("is")
-            && m.getReturnType() == boolean.class)
-                attrName = name.substring(2);
+            if (!managedOp) {
+                if (name.startsWith("get"))
+                    attrName = name.substring(3);
+                else if (name.startsWith("is")
+                         && m.getReturnType() == boolean.class)
+                    attrName = name.substring(2);
+            }
 
             if (attrName.length() != 0 && nParams == 0
-                    && m.getReturnType() != void.class) {
+                    && m.getReturnType() != void.class && !managedOp) {
                 // It's a getter
                 // Check we don't have both isX and getX
                 AttrMethods<M> am = attrMap.get(attrName);
@@ -153,7 +165,7 @@
                 attrMap.put(attrName, am);
             } else if (name.startsWith("set") && name.length() > 3
                     && nParams == 1 &&
-                    m.getReturnType() == void.class) {
+                    m.getReturnType() == void.class && !managedOp) {
                 // It's a setter
                 attrName = name.substring(3);
                 AttrMethods<M> am = attrMap.get(attrName);
@@ -166,6 +178,9 @@
                 }
                 am.setter = cm;
                 attrMap.put(attrName, am);
+            } else if (managedAttr) {
+                throw new NotCompliantMBeanException("Method " + name +
+                        " has @ManagedAttribute but is not a valid getter or setter");
             } else {
                 // It's an operation
                 List<M> cms = opMap.get(name);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanInjector.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.jmx.mbeanserver;
+
+import java.lang.ref.WeakReference;
+import java.security.PrivilegedAction;
+import java.util.Map;
+import java.util.WeakHashMap;
+import javax.annotation.Resource;
+import javax.management.MBeanServer;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+
+import static com.sun.jmx.mbeanserver.Util.newMap;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.security.AccessController;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.management.SendNotification;
+
+public class MBeanInjector {
+    private static Class<?>[] injectedClasses = {
+        MBeanServer.class, ObjectName.class, SendNotification.class,
+    };
+
+    public static void inject(Object mbean, MBeanServer mbs, ObjectName name)
+    throws Exception {
+        ClassInjector injector = injectorForClass(mbean.getClass());
+        injector.inject(mbean, MBeanServer.class, mbs);
+        injector.inject(mbean, ObjectName.class, name);
+    }
+
+    public static boolean injectsSendNotification(Object mbean)
+    throws NotCompliantMBeanException {
+        ClassInjector injector = injectorForClass(mbean.getClass());
+        return injector.injects(SendNotification.class);
+    }
+
+    public static void injectSendNotification(Object mbean, SendNotification sn)
+    throws Exception {
+        ClassInjector injector = injectorForClass(mbean.getClass());
+        injector.inject(mbean, SendNotification.class, sn);
+    }
+
+    public static void validate(Class<?> c) throws NotCompliantMBeanException {
+        injectorForClass(c);
+    }
+
+    private static class ClassInjector {
+        private Map<Class<?>, List<Field>> fields;
+        private Map<Class<?>, List<Method>> methods;
+
+        ClassInjector(Class<?> c) throws NotCompliantMBeanException {
+            fields = newMap();
+            methods = newMap();
+
+            Class<?> sup = c.getSuperclass();
+            ClassInjector supInjector;
+            if (sup == null) {
+                supInjector = null;
+            } else {
+                supInjector = injectorForClass(sup);
+                fields.putAll(supInjector.fields);
+                methods.putAll(supInjector.methods);
+            }
+
+            addMembers(c);
+            eliminateOverriddenMethods();
+
+            // If we haven't added any new fields or methods to what we
+            // inherited, then we can share the parent's maps.
+            if (supInjector != null) {
+                if (fields.equals(supInjector.fields))
+                    fields = supInjector.fields;
+                if (methods.equals(supInjector.methods))
+                    methods = supInjector.methods;
+            }
+        }
+
+        boolean injects(Class<?> c) {
+            return (fields.get(c) != null || methods.get(c) != null);
+        }
+
+        <T> void inject(Object instance, Class<T> type, T resource)
+        throws Exception {
+            List<Field> fs = fields.get(type);
+            if (fs != null) {
+                for (Field f : fs)
+                    f.set(instance, resource);
+            }
+            List<Method> ms = methods.get(type);
+            if (ms != null) {
+                for (Method m : ms) {
+                    try {
+                        m.invoke(instance, resource);
+                    } catch (InvocationTargetException e) {
+                        Throwable cause = e.getCause();
+                        if (cause instanceof Error)
+                            throw (Error) cause;
+                        else
+                            throw (Exception) cause;
+                    }
+                }
+            }
+        }
+
+        private void eliminateOverriddenMethods() {
+            /* Covariant overriding is unlikely, but it is possible that the
+             * parent has a @Resource method that we override with another
+             * @Resource method.  We don't want to invoke both methods,
+             * because polymorphism means we would actually invoke the same
+             * method twice.
+             */
+            for (Map.Entry<Class<?>, List<Method>> entry : methods.entrySet()) {
+                List<Method> list = entry.getValue();
+                list = MBeanAnalyzer.eliminateCovariantMethods(list);
+                entry.setValue(list);
+            }
+        }
+
+        /*
+         * Find Fields or Methods within the given Class that we can inject
+         * resource references into.  Suppose we want to know if a Field can get
+         * a reference to an ObjectName.  We'll accept fields like this:
+         *
+         * @Resource
+         * private transient ObjectName name;
+         *
+         * or like this:
+         *
+         * @Resource(type = ObjectName.class)
+         * private transient Object name;
+         *
+         * but not like this:
+         *
+         * @Resource
+         * private transient Object name;
+         *
+         * (Plain @Resource is equivalent to @Resource(type = Object.class).)
+         *
+         * We don't want to inject into everything that might possibly accept
+         * an ObjectName reference, because examples like the last one above
+         * could also accept an MBeanServer reference or any other sort of
+         * reference.
+         *
+         * So we accept a Field if it has a @Resource annotation and either
+         * (a) its type is ObjectName or a subclass and its @Resource type is
+         * compatible with ObjectName (e.g. it is Object); or
+         * (b) its type is compatible with ObjectName and its @Resource type
+         * is exactly ObjectName.  Fields that meet these criteria will not
+         * meet the same criteria with respect to other types such as MBeanServer.
+         *
+         * The same logic applies mutatis mutandis to Methods such as this:
+         *
+         * @Resource
+         * private void setObjectName1(ObjectName name)
+         * @Resource(type = Object.class)
+         * private void setObjectName2(Object name)
+         */
+        private void addMembers(final Class<?> c)
+        throws NotCompliantMBeanException {
+            AccessibleObject[][] memberArrays =
+                AccessController.doPrivileged(
+                    new PrivilegedAction<AccessibleObject[][]>() {
+                        public AccessibleObject[][] run() {
+                            return new AccessibleObject[][] {
+                                c.getDeclaredFields(), c.getDeclaredMethods()
+                            };
+                        }
+                    });
+            for (AccessibleObject[] members : memberArrays) {
+                for (final AccessibleObject member : members) {
+                    Resource res = member.getAnnotation(Resource.class);
+                    if (res == null)
+                        continue;
+
+                    final Field field;
+                    final Method method;
+                    final Class<?> memberType;
+                    final int modifiers;
+                    if (member instanceof Field) {
+                        field = (Field) member;
+                        memberType = field.getType();
+                        modifiers = field.getModifiers();
+                        method = null;
+                    } else {
+                        field = null;
+                        method = (Method) member;
+                        Class<?>[] paramTypes = method.getParameterTypes();
+                        if (paramTypes.length != 1) {
+                            throw new NotCompliantMBeanException(
+                                    "@Resource method must have exactly 1 " +
+                                    "parameter: " + method);
+                        }
+                        if (method.getReturnType() != void.class) {
+                            throw new NotCompliantMBeanException(
+                                    "@Resource method must return void: " +
+                                    method);
+                        }
+                        memberType = paramTypes[0];
+                        modifiers = method.getModifiers();
+                    }
+
+                    if (Modifier.isStatic(modifiers)) {
+                        throw new NotCompliantMBeanException(
+                                "@Resource method or field cannot be static: " +
+                                member);
+                    }
+
+                    for (Class<?> injectedClass : injectedClasses) {
+                        Class<?>[] types = {memberType, res.type()};
+                        boolean accept = false;
+                        for (int i = 0; i < 2; i++) {
+                            if (types[i] == injectedClass &&
+                                    types[1 - i].isAssignableFrom(injectedClass)) {
+                                accept = true;
+                                break;
+                            }
+                        }
+                        if (accept) {
+                            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                                public Void run() {
+                                    member.setAccessible(true);
+                                    return null;
+                                }
+                            });
+                            addToMap(fields, injectedClass, field);
+                            addToMap(methods, injectedClass, method);
+                        }
+                    }
+                }
+            }
+        }
+
+        private static <K, V> void addToMap(Map<K, List<V>> map, K key, V value) {
+            if (value == null)
+                return;
+            List<V> list = map.get(key);
+            if (list == null)
+                list = Collections.singletonList(value);
+            else {
+                if (list.size() == 1)
+                    list = new ArrayList<V>(list);
+                list.add(value);
+            }
+            map.put(key, list);
+        }
+    }
+
+    private static synchronized ClassInjector injectorForClass(Class<?> c)
+    throws NotCompliantMBeanException {
+        WeakReference<ClassInjector> wr = injectorMap.get(c);
+        ClassInjector ci = (wr == null) ? null : wr.get();
+        if (ci == null) {
+            ci = new ClassInjector(c);
+            injectorMap.put(c, new WeakReference<ClassInjector>(ci));
+        }
+        return ci;
+    }
+
+    private static Map<Class<?>, WeakReference<ClassInjector>> injectorMap =
+            new WeakHashMap<Class<?>, WeakReference<ClassInjector>>();
+}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanIntrospector.java	Wed Jul 05 16:39:18 2017 +0200
@@ -36,20 +36,28 @@
 import java.lang.reflect.Type;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 import java.util.WeakHashMap;
+import javax.management.Description;
 
 import javax.management.Descriptor;
 import javax.management.ImmutableDescriptor;
 import javax.management.IntrospectionException;
 import javax.management.InvalidAttributeValueException;
+import javax.management.MBean;
 import javax.management.MBeanAttributeInfo;
 import javax.management.MBeanConstructorInfo;
 import javax.management.MBeanException;
 import javax.management.MBeanInfo;
 import javax.management.MBeanNotificationInfo;
 import javax.management.MBeanOperationInfo;
+import javax.management.MXBean;
+import javax.management.ManagedAttribute;
+import javax.management.ManagedOperation;
 import javax.management.NotCompliantMBeanException;
 import javax.management.NotificationBroadcaster;
+import javax.management.NotificationInfo;
+import javax.management.NotificationInfos;
 import javax.management.ReflectionException;
 
 /**
@@ -153,6 +161,25 @@
     abstract MBeanAttributeInfo getMBeanAttributeInfo(String attributeName,
             M getter, M setter) throws IntrospectionException;
 
+    final String getAttributeDescription(
+            String attributeName, String defaultDescription,
+            Method getter, Method setter) throws IntrospectionException {
+        String g = Introspector.descriptionForElement(getter);
+        String s = Introspector.descriptionForElement(setter);
+        if (g == null) {
+            if (s == null)
+                return defaultDescription;
+            else
+                return s;
+        } else if (s == null || g.equals(s)) {
+            return g;
+        } else {
+            throw new IntrospectionException(
+                    "Inconsistent @Description on getter and setter for " +
+                    "attribute " + attributeName);
+        }
+    }
+
     /**
      * Construct an MBeanOperationInfo for the given operation based on
      * the M it was derived from.
@@ -184,8 +211,12 @@
     }
 
     void checkCompliance(Class<?> mbeanType) throws NotCompliantMBeanException {
-        if (!mbeanType.isInterface()) {
-            throw new NotCompliantMBeanException("Not an interface: " +
+        if (!mbeanType.isInterface() &&
+                !mbeanType.isAnnotationPresent(MBean.class) &&
+                !Introspector.hasMXBeanAnnotation(mbeanType)) {
+            throw new NotCompliantMBeanException("Not an interface and " +
+                    "does not have @" + MBean.class.getSimpleName() +
+                    " or @" + MXBean.class.getSimpleName() + " annotation: " +
                     mbeanType.getName());
         }
     }
@@ -194,7 +225,12 @@
      * Get the methods to be analyzed to build the MBean interface.
      */
     List<Method> getMethods(final Class<?> mbeanType) throws Exception {
-        return Arrays.asList(mbeanType.getMethods());
+        if (mbeanType.isInterface())
+            return Arrays.asList(mbeanType.getMethods());
+
+        final List<Method> methods = newList();
+        getAnnotatedMethods(mbeanType, methods);
+        return methods;
     }
 
     final PerInterface<M> getPerInterface(Class<?> mbeanInterface)
@@ -232,8 +268,11 @@
             MBeanAnalyzer<M> analyzer) throws IntrospectionException {
         final MBeanInfoMaker maker = new MBeanInfoMaker();
         analyzer.visit(maker);
-        final String description =
+        final String defaultDescription =
                 "Information on the management interface of the MBean";
+        String description = Introspector.descriptionForElement(mbeanInterface);
+        if (description == null)
+            description = defaultDescription;
         return maker.makeMBeanInfo(mbeanInterface, description);
     }
 
@@ -407,7 +446,15 @@
     throws NotCompliantMBeanException {
         MBeanInfo mbi =
                 getClassMBeanInfo(resource.getClass(), perInterface);
-        MBeanNotificationInfo[] notifs = findNotifications(resource);
+        MBeanNotificationInfo[] notifs;
+        try {
+            notifs = findNotifications(resource);
+        } catch (RuntimeException e) {
+            NotCompliantMBeanException x =
+                    new NotCompliantMBeanException(e.getMessage());
+            x.initCause(e);
+            throw x;
+        }
         Descriptor d = getSpecificMBeanDescriptor();
         boolean anyNotifs = (notifs != null && notifs.length > 0);
         if (!anyNotifs && ImmutableDescriptor.EMPTY_DESCRIPTOR.equals(d))
@@ -460,13 +507,43 @@
         }
     }
 
+    /*
+     * Add to "methods" every public method that has the @ManagedAttribute
+     * or @ManagedOperation annotation, in the given class or any of
+     * its superclasses or superinterfaces.
+     *
+     * We always add superclass or superinterface methods first, so that
+     * the stable sort used by eliminateCovariantMethods will put the
+     * method from the most-derived class last.  This means that we will
+     * see the version of the @ManagedAttribute (or ...Operation) annotation
+     * from that method, which might have a different description or whatever.
+     */
+    private static void getAnnotatedMethods(Class<?> c, List<Method> methods)
+    throws Exception {
+        Class<?> sup = c.getSuperclass();
+        if (sup != null)
+            getAnnotatedMethods(sup, methods);
+        Class<?>[] intfs = c.getInterfaces();
+        for (Class<?> intf : intfs)
+            getAnnotatedMethods(intf, methods);
+        for (Method m : c.getMethods()) {
+            // We are careful not to add m if it is inherited from a parent
+            // class or interface, because duplicate methods lead to nasty
+            // behaviour in eliminateCovariantMethods.
+            if (m.getDeclaringClass() == c &&
+                    (m.isAnnotationPresent(ManagedAttribute.class) ||
+                     m.isAnnotationPresent(ManagedOperation.class)))
+                methods.add(m);
+        }
+    }
+
     static MBeanNotificationInfo[] findNotifications(Object moi) {
         if (!(moi instanceof NotificationBroadcaster))
             return null;
         MBeanNotificationInfo[] mbn =
                 ((NotificationBroadcaster) moi).getNotificationInfo();
         if (mbn == null || mbn.length == 0)
-            return null;
+            return findNotificationsFromAnnotations(moi.getClass());
         MBeanNotificationInfo[] result =
                 new MBeanNotificationInfo[mbn.length];
         for (int i = 0; i < mbn.length; i++) {
@@ -478,11 +555,81 @@
         return result;
     }
 
+    private static MBeanNotificationInfo[] findNotificationsFromAnnotations(
+            Class<?> mbeanClass) {
+        Class<?> c = getAnnotatedNotificationInfoClass(mbeanClass);
+        if (c == null)
+            return null;
+        NotificationInfo ni = c.getAnnotation(NotificationInfo.class);
+        NotificationInfos nis = c.getAnnotation(NotificationInfos.class);
+        List<NotificationInfo> list = newList();
+        if (ni != null)
+            list.add(ni);
+        if (nis != null)
+            list.addAll(Arrays.asList(nis.value()));
+        if (list.isEmpty())
+            return null;
+        List<MBeanNotificationInfo> mbnis = newList();
+        for (NotificationInfo x : list) {
+            // The Descriptor includes any fields explicitly specified by
+            // x.descriptorFields(), plus any fields from the contained
+            // @Description annotation.
+            Descriptor d = new ImmutableDescriptor(x.descriptorFields());
+            d = ImmutableDescriptor.union(
+                    d, Introspector.descriptorForAnnotation(x.description()));
+            MBeanNotificationInfo mbni = new MBeanNotificationInfo(
+                    x.types(), x.notificationClass().getName(),
+                    x.description().value(), d);
+            mbnis.add(mbni);
+        }
+        return mbnis.toArray(new MBeanNotificationInfo[mbnis.size()]);
+    }
+
+    private static final Map<Class<?>, WeakReference<Class<?>>>
+            annotatedNotificationInfoClasses = newWeakHashMap();
+
+    private static Class<?> getAnnotatedNotificationInfoClass(Class<?> baseClass) {
+        synchronized (annotatedNotificationInfoClasses) {
+            WeakReference<Class<?>> wr =
+                    annotatedNotificationInfoClasses.get(baseClass);
+            if (wr != null)
+                return wr.get();
+            Class<?> c = null;
+            if (baseClass.isAnnotationPresent(NotificationInfo.class) ||
+                    baseClass.isAnnotationPresent(NotificationInfos.class)) {
+                c = baseClass;
+            } else {
+                Class<?>[] intfs = baseClass.getInterfaces();
+                for (Class<?> intf : intfs) {
+                    Class<?> c1 = getAnnotatedNotificationInfoClass(intf);
+                    if (c1 != null) {
+                        if (c != null) {
+                            throw new IllegalArgumentException(
+                                    "Class " + baseClass.getName() + " inherits " +
+                                    "@NotificationInfo(s) from both " +
+                                    c.getName() + " and " + c1.getName());
+                        }
+                        c = c1;
+                    }
+                }
+            }
+            // Record the result of the search.  If no @NotificationInfo(s)
+            // were found, c is null, and we store a WeakReference(null).
+            // This prevents us from having to search again and fail again.
+            annotatedNotificationInfoClasses.put(baseClass,
+                    new WeakReference<Class<?>>(c));
+            return c;
+        }
+    }
+
     private static MBeanConstructorInfo[] findConstructors(Class<?> c) {
         Constructor[] cons = c.getConstructors();
         MBeanConstructorInfo[] mbc = new MBeanConstructorInfo[cons.length];
         for (int i = 0; i < cons.length; i++) {
-            final String descr = "Public constructor of the MBean";
+            String descr = "Public constructor of the MBean";
+            Description d = cons[i].getAnnotation(Description.class);
+            if (d != null)
+                descr = d.value();
             mbc[i] = new MBeanConstructorInfo(descr, cons[i]);
         }
         return mbc;
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MBeanSupport.java	Wed Jul 05 16:39:18 2017 +0200
@@ -263,10 +263,14 @@
         return resource.getClass().getName();
     }
 
-    public final Object getResource() {
+    public final Object getWrappedObject() {
         return resource;
     }
 
+    public final ClassLoader getWrappedClassLoader() {
+        return resource.getClass().getClassLoader();
+    }
+
     public final Class<?> getMBeanInterface() {
         return perInterface.getMBeanInterface();
     }
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanIntrospector.java	Wed Jul 05 16:39:18 2017 +0200
@@ -35,6 +35,7 @@
 import java.lang.reflect.Type;
 import java.util.Map;
 import java.util.WeakHashMap;
+import javax.management.Description;
 import javax.management.Descriptor;
 import javax.management.ImmutableDescriptor;
 import javax.management.IntrospectionException;
@@ -43,6 +44,7 @@
 import javax.management.MBeanException;
 import javax.management.MBeanOperationInfo;
 import javax.management.MBeanParameterInfo;
+import javax.management.ManagedOperation;
 import javax.management.NotCompliantMBeanException;
 import javax.management.openmbean.MXBeanMappingFactory;
 import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
@@ -180,7 +182,10 @@
         final boolean isWritable = (setter != null);
         final boolean isIs = isReadable && getName(getter).startsWith("is");
 
-        final String description = attributeName;
+        final String description = getAttributeDescription(
+                attributeName, attributeName,
+                getter == null ? null : getter.getMethod(),
+                setter == null ? null : setter.getMethod());
 
         final OpenType<?> openType;
         final Type originalType;
@@ -229,13 +234,17 @@
     MBeanOperationInfo getMBeanOperationInfo(String operationName,
             ConvertingMethod operation) {
         final Method method = operation.getMethod();
-        final String description = operationName;
+        String description = operationName;
         /* Ideally this would be an empty string, but
-           OMBOperationInfo constructor forbids that.  Also, we
-           could consult an annotation to get a useful
-           description.  */
+           OMBOperationInfo constructor forbids that.  */
+        Description d = method.getAnnotation(Description.class);
+        if (d != null)
+            description = d.value();
 
-        final int impact = MBeanOperationInfo.UNKNOWN;
+        int impact = MBeanOperationInfo.UNKNOWN;
+        ManagedOperation annot = method.getAnnotation(ManagedOperation.class);
+        if (annot != null)
+            impact = annot.impact().getCode();
 
         final OpenType<?> returnType = operation.getOpenReturnType();
         final Type originalReturnType = operation.getGenericReturnType();
@@ -247,8 +256,15 @@
         boolean openParameterTypes = true;
         Annotation[][] annots = method.getParameterAnnotations();
         for (int i = 0; i < paramTypes.length; i++) {
-            final String paramName = "p" + i;
-            final String paramDescription = paramName;
+            String paramName = Introspector.nameForParameter(annots[i]);
+            if (paramName == null)
+                paramName = "p" + i;
+
+            String paramDescription =
+                    Introspector.descriptionForParameter(annots[i]);
+            if (paramDescription == null)
+                paramDescription = paramName;
+
             final OpenType<?> openType = paramTypes[i];
             final Type originalType = originalParamTypes[i];
             Descriptor descriptor =
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanSupport.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/MXBeanSupport.java	Wed Jul 05 16:39:18 2017 +0200
@@ -161,7 +161,7 @@
 
         synchronized (lock) {
             this.mxbeanLookup = MXBeanLookup.Plain.lookupFor(server);
-            this.mxbeanLookup.addReference(name, getResource());
+            this.mxbeanLookup.addReference(name, getWrappedObject());
             this.objectName = name;
         }
     }
@@ -170,7 +170,7 @@
     public void unregister() {
         synchronized (lock) {
             if (mxbeanLookup != null) {
-                if (mxbeanLookup.removeReference(objectName, getResource()))
+                if (mxbeanLookup.removeReference(objectName, getWrappedObject()))
                     objectName = null;
             }
             // XXX: need to revisit the whole register/unregister logic in
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/NotifySupport.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.jmx.mbeanserver;
+
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.DynamicMBean;
+import javax.management.DynamicWrapperMBean;
+import javax.management.InvalidAttributeValueException;
+import javax.management.ListenerNotFoundException;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanRegistration;
+import javax.management.MBeanServer;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationEmitter;
+import javax.management.NotificationFilter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+
+/**
+ * Create wrappers for DynamicMBean that implement NotificationEmitter
+ * and SendNotification.
+ */
+public class NotifySupport
+        implements DynamicMBean2, NotificationEmitter, MBeanRegistration {
+
+    private final DynamicMBean mbean;
+    private final NotificationBroadcasterSupport nbs;
+
+    public static DynamicMBean wrap(
+            DynamicMBean mbean, NotificationBroadcasterSupport nbs) {
+        return new NotifySupport(mbean, nbs);
+    }
+
+    private NotifySupport(DynamicMBean mbean, NotificationBroadcasterSupport nbs) {
+        this.mbean = mbean;
+        this.nbs = nbs;
+    }
+
+    public static NotificationBroadcasterSupport getNB(DynamicMBean mbean) {
+        if (mbean instanceof NotifySupport)
+            return ((NotifySupport) mbean).nbs;
+        else
+            return null;
+    }
+
+    public String getClassName() {
+        if (mbean instanceof DynamicMBean2)
+            return ((DynamicMBean2) mbean).getClassName();
+        Object w = mbean;
+        if (w instanceof DynamicWrapperMBean)
+            w = ((DynamicWrapperMBean) w).getWrappedObject();
+        return w.getClass().getName();
+    }
+
+    public void preRegister2(MBeanServer mbs, ObjectName name) throws Exception {
+        if (mbean instanceof DynamicMBean2)
+            ((DynamicMBean2) mbean).preRegister2(mbs, name);
+    }
+
+    public void registerFailed() {
+        if (mbean instanceof DynamicMBean2)
+            ((DynamicMBean2) mbean).registerFailed();
+    }
+
+    public Object getWrappedObject() {
+        if (mbean instanceof DynamicWrapperMBean)
+            return ((DynamicWrapperMBean) mbean).getWrappedObject();
+        else
+            return mbean;
+    }
+
+    public ClassLoader getWrappedClassLoader() {
+        if (mbean instanceof DynamicWrapperMBean)
+            return ((DynamicWrapperMBean) mbean).getWrappedClassLoader();
+        else
+            return mbean.getClass().getClassLoader();
+    }
+
+    public Object getAttribute(String attribute) throws AttributeNotFoundException,
+                                                        MBeanException,
+                                                        ReflectionException {
+        return mbean.getAttribute(attribute);
+    }
+
+    public void setAttribute(Attribute attribute) throws AttributeNotFoundException,
+                                                         InvalidAttributeValueException,
+                                                         MBeanException,
+                                                         ReflectionException {
+        mbean.setAttribute(attribute);
+    }
+
+    public AttributeList setAttributes(AttributeList attributes) {
+        return mbean.setAttributes(attributes);
+    }
+
+    public Object invoke(String actionName, Object[] params, String[] signature)
+            throws MBeanException, ReflectionException {
+        return mbean.invoke(actionName, params, signature);
+    }
+
+    public MBeanInfo getMBeanInfo() {
+        return mbean.getMBeanInfo();
+    }
+
+    public AttributeList getAttributes(String[] attributes) {
+        return mbean.getAttributes(attributes);
+    }
+
+    public void removeNotificationListener(NotificationListener listener,
+                                           NotificationFilter filter,
+                                           Object handback) throws ListenerNotFoundException {
+        nbs.removeNotificationListener(listener, filter, handback);
+    }
+
+    public void removeNotificationListener(NotificationListener listener)
+            throws ListenerNotFoundException {
+        nbs.removeNotificationListener(listener);
+    }
+
+    public MBeanNotificationInfo[] getNotificationInfo() {
+        return nbs.getNotificationInfo();
+    }
+
+    public void addNotificationListener(NotificationListener listener,
+                                        NotificationFilter filter,
+                                        Object handback) {
+        nbs.addNotificationListener(listener, filter, handback);
+    }
+
+    public ObjectName preRegister(MBeanServer server, ObjectName name) throws Exception {
+        if (mbr() != null)
+            return mbr().preRegister(server, name);
+        else
+            return name;
+    }
+
+    public void postRegister(Boolean registrationDone) {
+        if (mbr() != null)
+            mbr().postRegister(registrationDone);
+    }
+
+    public void preDeregister() throws Exception {
+        if (mbr() != null)
+            mbr().preDeregister();
+    }
+
+    public void postDeregister() {
+        if (mbr() != null)
+            mbr().postDeregister();
+    }
+
+    private MBeanRegistration mbr() {
+        if (mbean instanceof MBeanRegistration)
+            return (MBeanRegistration) mbean;
+        else
+            return null;
+    }
+}
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Repository.java	Wed Jul 05 16:39:18 2017 +0200
@@ -29,6 +29,7 @@
 import static com.sun.jmx.defaults.JmxProperties.MBEANSERVER_LOGGER;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -39,7 +40,6 @@
 import javax.management.DynamicMBean;
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.InstanceNotFoundException;
-import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 import javax.management.QueryExp;
 import javax.management.RuntimeOperationsException;
@@ -52,6 +52,27 @@
  */
 public class Repository {
 
+    /**
+     * An interface that allows the caller to get some control
+     * over the registration.
+     * @see #addMBean
+     * @see #remove
+     */
+    public interface RegistrationContext {
+        /**
+         * Called by {@link #addMBean}.
+         * Can throw a RuntimeOperationsException to cancel the
+         * registration.
+         */
+        public void registering();
+
+        /**
+         * Called by {@link #remove}.
+         * Any exception thrown by this method will be ignored.
+         */
+        public void unregistered();
+    }
+
     // Private fields -------------------------------------------->
 
     /**
@@ -115,7 +136,6 @@
         /**
          * Builds a new ObjectNamePattern object from an ObjectName pattern
          * constituents.
-         * @param domain pattern.getDomain().
          * @param propertyListPattern pattern.isPropertyListPattern().
          * @param propertyValuePattern pattern.isPropertyValuePattern().
          * @param canonicalProps pattern.getCanonicalKeyPropertyListString().
@@ -216,16 +236,6 @@
         }
     }
 
-    private void addNewDomMoi(final DynamicMBean object, final String dom,
-                              final ObjectName name) {
-        final Map<String,NamedObject> moiTb =
-            new HashMap<String,NamedObject>();
-        moiTb.put(name.getCanonicalKeyPropertyListString(),
-                  new NamedObject(name, object));
-        domainTb.put(dom, moiTb);
-        nbElements++;
-    }
-
     /** Match a string against a shell-style pattern.  The only pattern
         characters recognised are <code>?</code>, standing for any one
         character, and <code>*</code>, standing for any string of
@@ -306,6 +316,50 @@
         }
     }
 
+    private void addNewDomMoi(final DynamicMBean object,
+                              final String dom,
+                              final ObjectName name,
+                              final RegistrationContext context) {
+        final Map<String,NamedObject> moiTb =
+            new HashMap<String,NamedObject>();
+        final String key = name.getCanonicalKeyPropertyListString();
+        addMoiToTb(object,name,key,moiTb,context);
+        domainTb.put(dom, moiTb);
+        nbElements++;
+    }
+
+    private void registering(RegistrationContext context) {
+        if (context == null) return;
+        try {
+            context.registering();
+        } catch (RuntimeOperationsException x) {
+            throw x;
+        } catch (RuntimeException x) {
+            throw new RuntimeOperationsException(x);
+        }
+    }
+
+    private void unregistering(RegistrationContext context, ObjectName name) {
+        if (context == null) return;
+        try {
+            context.unregistered();
+        } catch (Exception x) {
+            // shouldn't come here...
+            MBEANSERVER_LOGGER.log(Level.FINE,
+                    "Unexpected exception while unregistering "+name,
+                    x);
+        }
+    }
+
+    private void addMoiToTb(final DynamicMBean object,
+            final ObjectName name,
+            final String key,
+            final Map<String,NamedObject> moiTb,
+            final RegistrationContext context) {
+        registering(context);
+        moiTb.put(key,new NamedObject(name, object));
+    }
+
     /**
      * Retrieves the named object contained in repository
      * from the given objectname.
@@ -355,12 +409,12 @@
         domainTb = new HashMap<String,Map<String,NamedObject>>(5);
 
         if (domain != null && domain.length() != 0)
-            this.domain = domain;
+            this.domain = domain.intern(); // we use == domain later on...
         else
             this.domain = ServiceName.DOMAIN;
 
-        // Creates an new hastable for the default domain
-        domainTb.put(this.domain.intern(), new HashMap<String,NamedObject>());
+        // Creates a new hashtable for the default domain
+        domainTb.put(this.domain, new HashMap<String,NamedObject>());
     }
 
     /**
@@ -395,10 +449,21 @@
     /**
      * Stores an MBean associated with its object name in the repository.
      *
-     * @param object MBean to be stored in the repository.
-     * @param name MBean object name.
+     * @param object  MBean to be stored in the repository.
+     * @param name    MBean object name.
+     * @param context A registration context. If non null, the repository
+     *                will call {@link RegistrationContext#registering()
+     *                context.registering()} from within the repository
+     *                lock, when it has determined that the {@code object}
+     *                can be stored in the repository with that {@code name}.
+     *                If {@link RegistrationContext#registering()
+     *                context.registering()} throws an exception, the
+     *                operation is abandonned, the MBean is not added to the
+     *                repository, and a {@link RuntimeOperationsException}
+     *                is thrown.
      */
-    public void addMBean(final DynamicMBean object, ObjectName name)
+    public void addMBean(final DynamicMBean object, ObjectName name,
+            final RegistrationContext context)
         throws InstanceAlreadyExistsException {
 
         if (MBEANSERVER_LOGGER.isLoggable(Level.FINER)) {
@@ -431,7 +496,7 @@
 
         lock.writeLock().lock();
         try {
-            // Domain cannot be JMImplementation if entry does not exists
+            // Domain cannot be JMImplementation if entry does not exist
             if ( !to_default_domain &&
                     dom.equals("JMImplementation") &&
                     domainTb.containsKey("JMImplementation")) {
@@ -440,21 +505,21 @@
                         "Repository: domain name cannot be JMImplementation"));
             }
 
-            // If domain not already exists, add it to the hash table
+            // If domain does not already exist, add it to the hash table
             final Map<String,NamedObject> moiTb = domainTb.get(dom);
             if (moiTb == null) {
-                addNewDomMoi(object, dom, name);
+                addNewDomMoi(object, dom, name, context);
                 return;
-            }
-
-            // Add instance if not already present
-            String cstr = name.getCanonicalKeyPropertyListString();
-            NamedObject elmt= moiTb.get(cstr);
-            if (elmt != null) {
-                throw new InstanceAlreadyExistsException(name.toString());
             } else {
-                nbElements++;
-                moiTb.put(cstr, new NamedObject(name, object));
+                // Add instance if not already present
+                String cstr = name.getCanonicalKeyPropertyListString();
+                NamedObject elmt= moiTb.get(cstr);
+                if (elmt != null) {
+                    throw new InstanceAlreadyExistsException(name.toString());
+                } else {
+                    nbElements++;
+                    addMoiToTb(object,name,cstr,moiTb,context);
+                }
             }
 
         } finally {
@@ -533,7 +598,7 @@
         // ":*", ":[key=value],*" : names in defaultDomain
         // "domain:*", "domain:[key=value],*" : names in the specified domain
 
-        // Surely one of the most frequent case ... query on the whole world
+        // Surely one of the most frequent cases ... query on the whole world
         ObjectName name;
         if (pattern == null ||
             pattern.getCanonicalName().length() == 0 ||
@@ -546,8 +611,7 @@
 
             // If pattern is not a pattern, retrieve this mbean !
             if (!name.isPattern()) {
-                final NamedObject no;
-                no = retrieveNamedObject(name);
+                final NamedObject no = retrieveNamedObject(name);
                 if (no != null) result.add(no);
                 return result;
             }
@@ -577,12 +641,22 @@
                 return result;
             }
 
+            if (!name.isDomainPattern()) {
+                final Map<String,NamedObject> moiTb = domainTb.get(name.getDomain());
+                if (moiTb == null) return Collections.emptySet();
+                if (allNames)
+                    result.addAll(moiTb.values());
+                else
+                    addAllMatching(moiTb, result, namePattern);
+                return result;
+            }
+
             // Pattern matching in the domain name (*, ?)
             char[] dom2Match = name.getDomain().toCharArray();
-            for (String domain : domainTb.keySet()) {
-                char[] theDom = domain.toCharArray();
+            for (String dom : domainTb.keySet()) {
+                char[] theDom = dom.toCharArray();
                 if (wildmatch(theDom, dom2Match)) {
-                    final Map<String,NamedObject> moiTb = domainTb.get(domain);
+                    final Map<String,NamedObject> moiTb = domainTb.get(dom);
                     if (allNames)
                         result.addAll(moiTb.values());
                     else
@@ -599,11 +673,21 @@
      * Removes an MBean from the repository.
      *
      * @param name name of the MBean to remove.
+     * @param context A registration context. If non null, the repository
+     *                will call {@link RegistrationContext#unregistered()
+     *                context.unregistered()} from within the repository
+     *                lock, just after the mbean associated with
+     *                {@code name} is removed from the repository.
+     *                If {@link RegistrationContext#unregistered()
+     *                context.unregistered()} is not expected to throw any
+     *                exception. If it does, the exception is logged
+     *                and swallowed.
      *
      * @exception InstanceNotFoundException The MBean does not exist in
      *            the repository.
      */
-    public void remove(final ObjectName name)
+    public void remove(final ObjectName name,
+            final RegistrationContext context)
         throws InstanceNotFoundException {
 
         // Debugging stuff
@@ -645,6 +729,9 @@
                 if (dom == domain)
                     domainTb.put(domain, new HashMap<String,NamedObject>());
             }
+
+            unregistering(context,name);
+
         } finally {
             lock.writeLock().unlock();
         }
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanIntrospector.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanIntrospector.java	Wed Jul 05 16:39:18 2017 +0200
@@ -35,6 +35,7 @@
 import javax.management.MBeanAttributeInfo;
 import javax.management.MBeanException;
 import javax.management.MBeanOperationInfo;
+import javax.management.ManagedOperation;
 import javax.management.NotCompliantMBeanException;
 import javax.management.NotificationBroadcaster;
 import javax.management.NotificationBroadcasterSupport;
@@ -118,22 +119,32 @@
 
     @Override
     MBeanAttributeInfo getMBeanAttributeInfo(String attributeName,
-            Method getter, Method setter) {
+            Method getter, Method setter) throws IntrospectionException {
 
-        final String description = "Attribute exposed for management";
-        try {
-            return new MBeanAttributeInfo(attributeName, description,
-                                          getter, setter);
-        } catch (IntrospectionException e) {
-            throw new RuntimeException(e); // should not happen
-        }
+        String description = getAttributeDescription(
+                attributeName, "Attribute exposed for management",
+                getter, setter);
+        return new MBeanAttributeInfo(attributeName, description,
+                                      getter, setter);
     }
 
     @Override
     MBeanOperationInfo getMBeanOperationInfo(String operationName,
             Method operation) {
-        final String description = "Operation exposed for management";
-        return new MBeanOperationInfo(description, operation);
+        final String defaultDescription = "Operation exposed for management";
+        String description = Introspector.descriptionForElement(operation);
+        if (description == null)
+            description = defaultDescription;
+
+        int impact = MBeanOperationInfo.UNKNOWN;
+        ManagedOperation annot = operation.getAnnotation(ManagedOperation.class);
+        if (annot != null)
+            impact = annot.impact().getCode();
+
+        MBeanOperationInfo mboi = new MBeanOperationInfo(description, operation);
+        return new MBeanOperationInfo(
+                mboi.getName(), mboi.getDescription(), mboi.getSignature(),
+                mboi.getReturnType(), impact, mboi.getDescriptor());
     }
 
     @Override
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanSupport.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/StandardMBeanSupport.java	Wed Jul 05 16:39:18 2017 +0200
@@ -41,26 +41,24 @@
 public class StandardMBeanSupport extends MBeanSupport<Method> {
 
     /**
-       <p>Construct a Standard MBean that wraps the given resource using the
-       given Standard MBean interface.</p>
-
-       @param resource the underlying resource for the new MBean.
-
-       @param mbeanInterface the interface to be used to determine
-       the MBean's management interface.
-
-       @param <T> a type parameter that allows the compiler to check
-       that {@code resource} implements {@code mbeanInterface},
-       provided that {@code mbeanInterface} is a class constant like
-       {@code SomeMBean.class}.
-
-       @throws IllegalArgumentException if {@code resource} is null or
-       if it does not implement the class {@code mbeanInterface} or if
-       that class is not a valid Standard MBean interface.
-    */
-    public <T> StandardMBeanSupport(T resource, Class<T> mbeanInterface)
+     * <p>Construct a Standard MBean that wraps the given resource using the
+     * given Standard MBean interface.</p>
+     *
+     * @param resource the underlying resource for the new MBean.
+     * @param mbeanInterfaceType the class or interface to be used to determine
+     *       the MBean's management interface.  An interface if this is a
+     *       classic Standard MBean; a class if this is a {@code @ManagedResource}.
+     * @param <T> a type parameter that allows the compiler to check
+     *       that {@code resource} implements {@code mbeanInterfaceType},
+     *       provided that {@code mbeanInterfaceType} is a class constant like
+     *       {@code SomeMBean.class}.
+     * @throws IllegalArgumentException if {@code resource} is null or
+     *       if it does not implement the class {@code mbeanInterfaceType} or if
+     *       that class is not a valid Standard MBean interface.
+     */
+    public <T> StandardMBeanSupport(T resource, Class<T> mbeanInterfaceType)
             throws NotCompliantMBeanException {
-        super(resource, mbeanInterface, (MXBeanMappingFactory) null);
+        super(resource, mbeanInterfaceType, (MXBeanMappingFactory) null);
     }
 
     @Override
@@ -86,13 +84,14 @@
     @Override
     public MBeanInfo getMBeanInfo() {
         MBeanInfo mbi = super.getMBeanInfo();
-        Class<?> resourceClass = getResource().getClass();
-        if (StandardMBeanIntrospector.isDefinitelyImmutableInfo(resourceClass))
+        Class<?> resourceClass = getWrappedObject().getClass();
+        if (!getMBeanInterface().isInterface() ||
+                StandardMBeanIntrospector.isDefinitelyImmutableInfo(resourceClass))
             return mbi;
         return new MBeanInfo(mbi.getClassName(), mbi.getDescription(),
                 mbi.getAttributes(), mbi.getConstructors(),
                 mbi.getOperations(),
-                MBeanIntrospector.findNotifications(getResource()),
+                MBeanIntrospector.findNotifications(getWrappedObject()),
                 mbi.getDescriptor());
     }
 }
--- a/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/jmx/mbeanserver/Util.java	Wed Jul 05 16:39:18 2017 +0200
@@ -38,6 +38,7 @@
 import java.util.Set;
 import java.util.SortedMap;
 import java.util.TreeMap;
+import java.util.WeakHashMap;
 import javax.management.MalformedObjectNameException;
 import javax.management.ObjectName;
 
@@ -71,6 +72,10 @@
         return new LinkedHashMap<K, V>();
     }
 
+    static <K, V> WeakHashMap<K, V> newWeakHashMap() {
+        return new WeakHashMap<K, V>();
+    }
+
     static <E> Set<E> newSet() {
         return new HashSet<E>();
     }
--- a/jdk/src/share/classes/com/sun/tools/jdi/EventSetImpl.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/EventSetImpl.java	Wed Jul 05 16:39:18 2017 +0200
@@ -208,8 +208,9 @@
         }
 
         public String toString() {
-            return eventName() + "@" + location().toString() +
-                                 " in thread " + thread().name();
+            return eventName() + "@" +
+                   ((location() == null) ? " null" : location().toString()) +
+                   " in thread " + thread().name();
         }
     }
 
--- a/jdk/src/share/classes/com/sun/tools/jdi/MonitorInfoImpl.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/MonitorInfoImpl.java	Wed Jul 05 16:39:18 2017 +0200
@@ -40,11 +40,12 @@
     int  stack_depth;
 
     MonitorInfoImpl(VirtualMachine vm, ObjectReference mon,
-                    ThreadReference thread, int dpth) {
+                    ThreadReferenceImpl thread, int dpth) {
         super(vm);
         this.monitor = mon;
         this.thread = thread;
         this.stack_depth = dpth;
+        thread.addListener(this);
     }
 
 
--- a/jdk/src/share/classes/com/sun/tools/jdi/ThreadReferenceImpl.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/ThreadReferenceImpl.java	Wed Jul 05 16:39:18 2017 +0200
@@ -35,12 +35,34 @@
     static final int SUSPEND_STATUS_SUSPENDED = 0x1;
     static final int SUSPEND_STATUS_BREAK = 0x2;
 
-    private ThreadGroupReference threadGroup;
     private int suspendedZombieCount = 0;
 
-    // This is cached only while the VM is suspended
-    private static class Cache extends ObjectReferenceImpl.Cache {
-        String name = null;
+    /*
+     * Some objects can only be created while a thread is suspended and are valid
+     * only while the thread remains suspended.  Examples are StackFrameImpl
+     * and MonitorInfoImpl.  When the thread resumes, these objects have to be
+     * marked as invalid so that their methods can throw
+     * InvalidStackFrameException if they are called.  To do this, such objects
+     * register themselves as listeners of the associated thread.  When the
+     * thread is resumed, its listeners are notified and mark themselves
+     * invalid.
+     * Also, note that ThreadReferenceImpl itself caches some info that
+     * is valid only as long as the thread is suspended.  When the thread
+     * is resumed, that cache must be purged.
+     * Lastly, note that ThreadReferenceImpl and its super, ObjectReferenceImpl
+     * cache some info that is only valid as long as the entire VM is suspended.
+     * If _any_ thread is resumed, this cache must be purged.  To handle this,
+     * both ThreadReferenceImpl and ObjectReferenceImpl register themselves as
+     * VMListeners so that they get notified when all threads are suspended and
+     * when any thread is resumed.
+     */
+
+    // This is cached for the life of the thread
+    private ThreadGroupReference threadGroup;
+
+    // This is cached only while this one thread is suspended.  Each time
+    // the thread is resumed, we clear this and start with a fresh one.
+    private static class LocalCache {
         JDWP.ThreadReference.Status status = null;
         List<StackFrame> frames = null;
         int framesStart = -1;
@@ -52,6 +74,17 @@
         boolean triedCurrentContended = false;
     }
 
+    private LocalCache localCache;
+
+    private void resetLocalCache() {
+        localCache = new LocalCache();
+    }
+
+    // This is cached only while all threads in the VM are suspended
+    // Yes, someone could change the name of a thread while it is suspended.
+    private static class Cache extends ObjectReferenceImpl.Cache {
+        String name = null;
+    }
     protected ObjectReferenceImpl.Cache newCache() {
         return new Cache();
     }
@@ -59,8 +92,10 @@
     // Listeners - synchronized on vm.state()
     private List<WeakReference<ThreadListener>> listeners = new ArrayList<WeakReference<ThreadListener>>();
 
+
     ThreadReferenceImpl(VirtualMachine aVm, long aRef) {
         super(aVm,aRef);
+        resetLocalCache();
         vm.state().addListener(this);
     }
 
@@ -72,10 +107,24 @@
      * VMListener implementation
      */
     public boolean vmNotSuspended(VMAction action) {
-        synchronized (vm.state()) {
-            processThreadAction(new ThreadAction(this,
-                                   ThreadAction.THREAD_RESUMABLE));
+        if (action.resumingThread() == null) {
+            // all threads are being resumed
+            synchronized (vm.state()) {
+                processThreadAction(new ThreadAction(this,
+                                            ThreadAction.THREAD_RESUMABLE));
+            }
+
         }
+
+        /*
+         * Othewise, only one thread is being resumed:
+         *   if it is us,
+         *      we have already done our processThreadAction to notify our
+         *      listeners when we processed the resume.
+         *   if it is not us,
+         *      we don't want to notify our listeners
+         *       because we are not being resumed.
+         */
         return super.vmNotSuspended(action);
     }
 
@@ -191,23 +240,19 @@
     }
 
     private JDWP.ThreadReference.Status jdwpStatus() {
-        JDWP.ThreadReference.Status status = null;
+        JDWP.ThreadReference.Status myStatus = localCache.status;
         try {
-            Cache local = (Cache)getCache();
-
-            if (local != null) {
-                status = local.status;
-            }
-            if (status == null) {
-                status = JDWP.ThreadReference.Status.process(vm, this);
-                if (local != null) {
-                    local.status = status;
+             if (myStatus == null) {
+                 myStatus = JDWP.ThreadReference.Status.process(vm, this);
+                if ((myStatus.suspendStatus & SUSPEND_STATUS_SUSPENDED) != 0) {
+                    // thread is suspended, we can cache the status.
+                    localCache.status = myStatus;
                 }
             }
-        } catch (JDWPException exc) {
+         } catch (JDWPException exc) {
             throw exc.toJDIException();
         }
-        return status;
+         return myStatus;
     }
 
     public int status() {
@@ -245,8 +290,7 @@
 
     public ThreadGroupReference threadGroup() {
         /*
-         * Thread group can't change, so it's cached more conventionally
-         * than other things in this class.
+         * Thread group can't change, so it's cached once and for all.
          */
         if (threadGroup == null) {
             try {
@@ -260,19 +304,10 @@
     }
 
     public int frameCount() throws IncompatibleThreadStateException  {
-        int frameCount = -1;
         try {
-            Cache local = (Cache)getCache();
-
-            if (local != null) {
-                frameCount = local.frameCount;
-            }
-            if (frameCount == -1) {
-                frameCount = JDWP.ThreadReference.FrameCount
+            if (localCache.frameCount == -1) {
+                localCache.frameCount = JDWP.ThreadReference.FrameCount
                                           .process(vm, this).frameCount;
-                if (local != null) {
-                    local.frameCount = frameCount;
-                }
             }
         } catch (JDWPException exc) {
             switch (exc.errorCode()) {
@@ -283,7 +318,7 @@
                 throw exc.toJDIException();
             }
         }
-        return frameCount;
+        return localCache.frameCount;
     }
 
     public List<StackFrame> frames() throws IncompatibleThreadStateException  {
@@ -297,23 +332,25 @@
 
     /**
      * Is the requested subrange within what has been retrieved?
-     * local is known to be non-null
+     * local is known to be non-null.  Should only be called from
+     * a sync method.
      */
-    private boolean isSubrange(Cache local,
-                               int start, int length, List frames) {
-        if (start < local.framesStart) {
+    private boolean isSubrange(LocalCache localCache,
+                               int start, int length) {
+        if (start < localCache.framesStart) {
             return false;
         }
         if (length == -1) {
-            return (local.framesLength == -1);
+            return (localCache.framesLength == -1);
         }
-        if (local.framesLength == -1) {
-            if ((start + length) > (local.framesStart + frames.size())) {
+        if (localCache.framesLength == -1) {
+            if ((start + length) > (localCache.framesStart +
+                                    localCache.frames.size())) {
                 throw new IndexOutOfBoundsException();
             }
             return true;
         }
-        return ((start + length) <= (local.framesStart + local.framesLength));
+        return ((start + length) <= (localCache.framesStart + localCache.framesLength));
     }
 
     public List<StackFrame> frames(int start, int length)
@@ -329,51 +366,42 @@
      * Private version of frames() allows "-1" to specify all
      * remaining frames.
      */
-    private List<StackFrame> privateFrames(int start, int length)
+    synchronized private List<StackFrame> privateFrames(int start, int length)
                               throws IncompatibleThreadStateException  {
-        List<StackFrame> frames = null;
+
+        // Lock must be held while creating stack frames so if that two threads
+        // do this at the same time, one won't clobber the subset created by the other.
+
         try {
-            Cache local = (Cache)getCache();
-
-            if (local != null) {
-                frames = local.frames;
-            }
-            if (frames == null || !isSubrange(local, start, length, frames)) {
+            if (localCache.frames == null || !isSubrange(localCache, start, length)) {
                 JDWP.ThreadReference.Frames.Frame[] jdwpFrames
                     = JDWP.ThreadReference.Frames.
-                          process(vm, this, start, length).frames;
+                    process(vm, this, start, length).frames;
                 int count = jdwpFrames.length;
-                frames = new ArrayList<StackFrame>(count);
+                localCache.frames = new ArrayList<StackFrame>(count);
 
-                // Lock must be held while creating stack frames.
-                // so that a resume will not resume a partially
-                // created stack.
-                synchronized (vm.state()) {
-                    for (int i = 0; i<count; i++) {
-                        if (jdwpFrames[i].location == null) {
-                            throw new InternalException("Invalid frame location");
-                        }
-                        StackFrame frame = new StackFrameImpl(vm, this,
-                                            jdwpFrames[i].frameID,
-                                            jdwpFrames[i].location);
-                        // Add to the frame list
-                        frames.add(frame);
+                for (int i = 0; i<count; i++) {
+                    if (jdwpFrames[i].location == null) {
+                        throw new InternalException("Invalid frame location");
                     }
+                    StackFrame frame = new StackFrameImpl(vm, this,
+                                                          jdwpFrames[i].frameID,
+                                                          jdwpFrames[i].location);
+                    // Add to the frame list
+                    localCache.frames.add(frame);
                 }
-                if (local != null) {
-                    local.frames = frames;
-                    local.framesStart = start;
-                    local.framesLength = length;
-                }
+                localCache.framesStart = start;
+                localCache.framesLength = length;
+                return Collections.unmodifiableList(localCache.frames);
             } else {
-                int fromIndex = start - local.framesStart;
+                int fromIndex = start - localCache.framesStart;
                 int toIndex;
                 if (length == -1) {
-                    toIndex = frames.size() - fromIndex;
+                    toIndex = localCache.frames.size() - fromIndex;
                 } else {
                     toIndex = fromIndex + length;
                 }
-                frames = frames.subList(fromIndex, toIndex);
+                return Collections.unmodifiableList(localCache.frames.subList(fromIndex, toIndex));
             }
         } catch (JDWPException exc) {
             switch (exc.errorCode()) {
@@ -384,28 +412,18 @@
                 throw exc.toJDIException();
             }
         }
-        return Collections.unmodifiableList(frames);
     }
 
     public List<ObjectReference> ownedMonitors()  throws IncompatibleThreadStateException  {
-        List<ObjectReference> monitors = null;
         try {
-            Cache local = (Cache)getCache();
-
-            if (local != null) {
-                monitors = local.ownedMonitors;
-            }
-            if (monitors == null) {
-                monitors = Arrays.asList(
+            if (localCache.ownedMonitors == null) {
+                localCache.ownedMonitors = Arrays.asList(
                                  (ObjectReference[])JDWP.ThreadReference.OwnedMonitors.
                                          process(vm, this).owned);
-                if (local != null) {
-                    local.ownedMonitors = monitors;
-                    if ((vm.traceFlags & vm.TRACE_OBJREFS) != 0) {
-                        vm.printTrace(description() +
-                                      " temporarily caching owned monitors"+
-                                      " (count = " + monitors.size() + ")");
-                    }
+                if ((vm.traceFlags & vm.TRACE_OBJREFS) != 0) {
+                    vm.printTrace(description() +
+                                  " temporarily caching owned monitors"+
+                                  " (count = " + localCache.ownedMonitors.size() + ")");
                 }
             }
         } catch (JDWPException exc) {
@@ -417,29 +435,22 @@
                 throw exc.toJDIException();
             }
         }
-        return monitors;
+        return localCache.ownedMonitors;
     }
 
     public ObjectReference currentContendedMonitor()
                               throws IncompatibleThreadStateException  {
-        ObjectReference monitor = null;
         try {
-            Cache local = (Cache)getCache();
-
-            if (local != null && local.triedCurrentContended) {
-                monitor = local.contendedMonitor;
-            } else {
-                monitor = JDWP.ThreadReference.CurrentContendedMonitor.
+            if (localCache.contendedMonitor == null &&
+                !localCache.triedCurrentContended) {
+                localCache.contendedMonitor = JDWP.ThreadReference.CurrentContendedMonitor.
                     process(vm, this).monitor;
-                if (local != null) {
-                    local.triedCurrentContended = true;
-                    local.contendedMonitor = monitor;
-                    if ((monitor != null) &&
-                        ((vm.traceFlags & vm.TRACE_OBJREFS) != 0)) {
-                        vm.printTrace(description() +
-                              " temporarily caching contended monitor"+
-                              " (id = " + monitor.uniqueID() + ")");
-                    }
+                localCache.triedCurrentContended = true;
+                if ((localCache.contendedMonitor != null) &&
+                    ((vm.traceFlags & vm.TRACE_OBJREFS) != 0)) {
+                    vm.printTrace(description() +
+                                  " temporarily caching contended monitor"+
+                                  " (id = " + localCache.contendedMonitor.uniqueID() + ")");
                 }
             }
         } catch (JDWPException exc) {
@@ -450,40 +461,31 @@
                 throw exc.toJDIException();
             }
         }
-        return monitor;
+        return localCache.contendedMonitor;
     }
 
     public List<MonitorInfo> ownedMonitorsAndFrames()  throws IncompatibleThreadStateException  {
-        List<MonitorInfo> monitors = null;
         try {
-            Cache local = (Cache)getCache();
-
-            if (local != null) {
-                monitors = local.ownedMonitorsInfo;
-            }
-            if (monitors == null) {
+            if (localCache.ownedMonitorsInfo == null) {
                 JDWP.ThreadReference.OwnedMonitorsStackDepthInfo.monitor[] minfo;
                 minfo = JDWP.ThreadReference.OwnedMonitorsStackDepthInfo.process(vm, this).owned;
 
-                monitors = new ArrayList<MonitorInfo>(minfo.length);
+                localCache.ownedMonitorsInfo = new ArrayList<MonitorInfo>(minfo.length);
 
                 for (int i=0; i < minfo.length; i++) {
                     JDWP.ThreadReference.OwnedMonitorsStackDepthInfo.monitor mi =
                                                                          minfo[i];
                     MonitorInfo mon = new MonitorInfoImpl(vm, minfo[i].monitor, this, minfo[i].stack_depth);
-                    monitors.add(mon);
+                    localCache.ownedMonitorsInfo.add(mon);
                 }
 
-                if (local != null) {
-                    local.ownedMonitorsInfo = monitors;
-                    if ((vm.traceFlags & vm.TRACE_OBJREFS) != 0) {
-                        vm.printTrace(description() +
-                                      " temporarily caching owned monitors"+
-                                      " (count = " + monitors.size() + ")");
+                if ((vm.traceFlags & vm.TRACE_OBJREFS) != 0) {
+                    vm.printTrace(description() +
+                                  " temporarily caching owned monitors"+
+                                  " (count = " + localCache.ownedMonitorsInfo.size() + ")");
                     }
                 }
 
-            }
         } catch (JDWPException exc) {
             switch (exc.errorCode()) {
             case JDWP.Error.THREAD_NOT_SUSPENDED:
@@ -493,7 +495,7 @@
                 throw exc.toJDIException();
             }
         }
-        return monitors;
+        return localCache.ownedMonitorsInfo;
     }
 
     public void popFrames(StackFrame frame) throws IncompatibleThreadStateException {
@@ -511,7 +513,7 @@
     }
 
     public void forceEarlyReturn(Value  returnValue) throws InvalidTypeException,
-                                             ClassNotLoadedException,
+                                                            ClassNotLoadedException,
                                              IncompatibleThreadStateException {
         if (!vm.canForceEarlyReturn()) {
             throw new UnsupportedOperationException(
@@ -604,6 +606,9 @@
                     iter.remove();
                 }
             }
+
+            // Discard our local cache
+            resetLocalCache();
         }
     }
 }
--- a/jdk/src/share/classes/com/sun/tools/jdi/VMAction.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/VMAction.java	Wed Jul 05 16:39:18 2017 +0200
@@ -38,10 +38,18 @@
     static final int VM_NOT_SUSPENDED = 2;
 
     int id;
+    ThreadReference resumingThread;
 
     VMAction(VirtualMachine vm, int id) {
+        this(vm, null, id);
+    }
+
+    // For id = VM_NOT_SUSPENDED, if resumingThread != null, then it is
+    // the only thread that is being resumed.
+     VMAction(VirtualMachine vm,  ThreadReference resumingThread, int id) {
         super(vm);
         this.id = id;
+        this.resumingThread = resumingThread;
     }
     VirtualMachine vm() {
         return (VirtualMachine)getSource();
@@ -49,4 +57,8 @@
     int id() {
         return id;
     }
+
+    ThreadReference resumingThread() {
+        return resumingThread;
+    }
 }
--- a/jdk/src/share/classes/com/sun/tools/jdi/VMState.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/VMState.java	Wed Jul 05 16:39:18 2017 +0200
@@ -116,16 +116,25 @@
     }
 
     /**
-     * Tell listeners to invalidate suspend-sensitive caches.
+     * All threads are resuming
      */
-    synchronized void thaw() {
+    void thaw() {
+        thaw(null);
+    }
+
+    /**
+     * Tell listeners to invalidate suspend-sensitive caches.
+     * If resumingThread != null, then only that thread is being
+     * resumed.
+     */
+    synchronized void thaw(ThreadReference resumingThread) {
         if (cache != null) {
             if ((vm.traceFlags & vm.TRACE_OBJREFS) != 0) {
                 vm.printTrace("Clearing VM suspended cache");
             }
             disableCache();
         }
-        processVMAction(new VMAction(vm, VMAction.VM_NOT_SUSPENDED));
+        processVMAction(new VMAction(vm, resumingThread, VMAction.VM_NOT_SUSPENDED));
     }
 
     private synchronized void processVMAction(VMAction action) {
--- a/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java	Wed Jul 05 16:39:18 2017 +0200
@@ -146,8 +146,9 @@
     public boolean threadResumable(ThreadAction action) {
         /*
          * If any thread is resumed, the VM is considered not suspended.
+         * Just one thread is being resumed so pass it to thaw.
          */
-        state.thaw();
+        state.thaw(action.thread());
         return true;
     }
 
--- a/jdk/src/share/classes/java/nio/channels/SelectionKey.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/java/nio/channels/SelectionKey.java	Wed Jul 05 16:39:18 2017 +0200
@@ -191,7 +191,7 @@
      * @throws  IllegalArgumentException
      *          If a bit in the set does not correspond to an operation that
      *          is supported by this key's channel, that is, if
-     *          <tt>set & ~(channel().validOps()) != 0</tt>
+     *          <tt>(ops & ~channel().validOps()) != 0</tt>
      *
      * @throws  CancelledKeyException
      *          If this key has been cancelled
--- a/jdk/src/share/classes/javax/management/BinaryRelQueryExp.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/javax/management/BinaryRelQueryExp.java	Wed Jul 05 16:39:18 2017 +0200
@@ -192,6 +192,7 @@
         return "(" + exp1 + ") " + relOpString() + " (" + exp2 + ")";
     }
 
+    @Override
     String toQueryString() {
         return exp1 + " " + relOpString() + " " + exp2;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/management/Description.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.management;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.ResourceBundle;
+
+/**
+ * <p>The textual description of an MBean or part of an MBean.  This
+ * description is intended to be displayed to users to help them
+ * understand what the MBean does.  Ultimately it will be the value of
+ * the {@code getDescription()} method of an {@link MBeanInfo}, {@link
+ * MBeanAttributeInfo}, or similar.</p>
+ *
+ * <p>This annotation applies to Standard MBean interfaces and to
+ * MXBean interfaces, as well as to MBean classes defined using the
+ * {@link MBean @MBean} or {@link MXBean @MXBean} annotations.  For
+ * example, a Standard MBean might be defined like this:</p>
+ *
+ * <pre>
+ * <b>{@code @Description}</b>("Application configuration")
+ * public interface ConfigurationMBean {
+ *     <b>{@code @Description}</b>("Cache size in bytes")
+ *     public int getCacheSize();
+ *     public void setCacheSize(int size);
+ *
+ *     <b>{@code @Description}</b>("Last time the configuration was changed, " +
+ *                  "in milliseconds since 1 Jan 1970")
+ *     public long getLastChangedTime();
+ *
+ *     <b>{@code @Description}</b>("Save the configuration to a file")
+ *     public void save(
+ *         <b>{@code @Description}</b>("Optional name of the file, or null for the default name")
+ *         String fileName);
+ * }
+ * </pre>
+ *
+ * <p>The {@code MBeanInfo} for this MBean will have a {@link
+ * MBeanInfo#getDescription() getDescription()} that is {@code
+ * "Application configuration"}.  It will contain an {@code
+ * MBeanAttributeInfo} for the {@code CacheSize} attribute that is
+ * defined by the methods {@code getCacheSize} and {@code
+ * setCacheSize}, and another {@code MBeanAttributeInfo} for {@code
+ * LastChangedTime}.  The {@link MBeanAttributeInfo#getDescription()
+ * getDescription()} for {@code CacheSize} will be {@code "Cache size
+ * in bytes"}.  Notice that there is no need to add a
+ * {@code @Description} to both {@code getCacheSize} and {@code
+ * setCacheSize} - either alone will do.  But if you do add a
+ * {@code @Description} to both, it must be the same.</p>
+ *
+ * <p>The {@code MBeanInfo} will also contain an {@link
+ * MBeanOperationInfo} where {@link
+ * MBeanOperationInfo#getDescription() getDescription()} is {@code
+ * "Save the configuration to a file"}.  This {@code
+ * MBeanOperationInfo} will contain an {@link MBeanParameterInfo}
+ * where {@link MBeanParameterInfo#getDescription() getDescription()}
+ * is {@code "Optional name of the file, or null for the default
+ * name"}.</p>
+ *
+ * <p>The {@code @Description} annotation can also be applied to the
+ * public constructors of the implementation class.  Continuing the
+ * above example, the {@code Configuration} class implementing {@code
+ * ConfigurationMBean} might look like this:</p>
+ *
+ * <pre>
+ * public class Configuration implements ConfigurationMBean {
+ *     <b>{@code @Description}</b>("A Configuration MBean with the default file name")
+ *     public Configuration() {
+ *         this(DEFAULT_FILE_NAME);
+ *     }
+ *
+ *     <b>{@code @Description}</b>("A Configuration MBean with a specified file name")
+ *     public Configuration(
+ *         <b>{@code @Description}</b>("Name of the file the configuration is stored in")
+ *         String fileName) {...}
+ *     ...
+ * }
+ * </pre>
+ *
+ * <p>The {@code @Description} annotation also works in MBeans that
+ * are defined using the {@code @MBean} or {@code @MXBean} annotation
+ * on classes.  Here is an alternative implementation of {@code
+ * Configuration} that does not use an {@code ConfigurationMBean}
+ * interface.</p>
+ *
+ * <pre>
+ * <b>{@code @MBean}</b>
+ * <b>{@code @Description}</b>("Application configuration")
+ * public class Configuration {
+ *     <b>{@code @Description}</b>("A Configuration MBean with the default file name")
+ *     public Configuration() {
+ *         this(DEFAULT_FILE_NAME);
+ *     }
+ *
+ *     <b>{@code @Description}</b>("A Configuration MBean with a specified file name")
+ *     public Configuration(
+ *         <b>{@code @Description}</b>("Name of the file the configuration is stored in")
+ *         String fileName) {...}
+ *
+ *     <b>{@code @ManagedAttribute}</b>
+ *     <b>{@code @Description}</b>("Cache size in bytes")
+ *     public int getCacheSize() {...}
+ *     <b>{@code @ManagedAttribute}</b>
+ *     public void setCacheSize(int size) {...}
+ *
+ *     <b>{@code @ManagedOperation}</b>
+ *     <b>{@code @Description}</b>("Last time the configuration was changed, " +
+ *                  "in milliseconds since 1 Jan 1970")
+ *     public long getLastChangedTime() {...}
+ *
+ *     <b>{@code @ManagedOperation}</b>
+ *     <b>{@code @Description}</b>("Save the configuration to a file")
+ *     public void save(
+ *         <b>{@code @Description}</b>("Optional name of the file, or null for the default name")
+ *         String fileName) {...}
+ *     ...
+ * }
+ * </pre>
+ */
+@Documented
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER,
+         ElementType.TYPE})
+public @interface Description {
+    /**
+     * <p>The description.</p>
+     */
+    String value();
+
+    /**
+     * <p>The base name for the {@link ResourceBundle} in which the key given in
+     * the {@code descriptionResourceKey} field can be found, for example
+     * {@code "com.example.myapp.MBeanResources"}.  If a non-default value
+     * is supplied for this element, it will appear in the
+     * <a href="Descriptor.html#descriptionResourceBundleBaseName"><!--
+     * -->{@code Descriptor}</a> for the annotated item.</p>
+     */
+    @DescriptorKey(
+        value = "descriptionResourceBundleBaseName", omitIfDefault = true)
+    String bundleBaseName() default "";
+
+    /**
+     * <p>A resource key for the description of this element.  In
+     * conjunction with the {@link #bundleBaseName bundleBaseName},
+     * this can be used to find a localized version of the description.
+     * If a non-default value
+     * is supplied for this element, it will appear in the
+     * <a href="Descriptor.html#descriptionResourceKey"><!--
+     * -->{@code Descriptor}</a> for the annotated item.</p>
+     */
+    @DescriptorKey(value = "descriptionResourceKey", omitIfDefault = true)
+    String key() default "";
+}
--- a/jdk/src/share/classes/javax/management/Descriptor.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/javax/management/Descriptor.java	Wed Jul 05 16:39:18 2017 +0200
@@ -38,6 +38,7 @@
 import java.util.ResourceBundle;
 
 import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.MXBeanMappingFactory;
 import javax.management.openmbean.OpenMBeanAttributeInfoSupport;
 import javax.management.openmbean.OpenMBeanOperationInfoSupport;
 import javax.management.openmbean.OpenMBeanParameterInfoSupport;
@@ -117,21 +118,19 @@
  * deprecation, for example {@code "1.3 Replaced by the Capacity
  * attribute"}.</td>
  *
- * <tr><td>descriptionResource<br>BundleBaseName</td><td>String</td><td>Any</td>
+ * <tr id="descriptionResourceBundleBaseName">
+ * <td>descriptionResource<br>BundleBaseName</td><td>String</td><td>Any</td>
  *
  * <td>The base name for the {@link ResourceBundle} in which the key given in
  * the {@code descriptionResourceKey} field can be found, for example
- * {@code "com.example.myapp.MBeanResources"}.  The meaning of this
- * field is defined by this specification but the field is not set or
- * used by the JMX API itself.</td>
+ * {@code "com.example.myapp.MBeanResources"}.</td>
  *
- * <tr><td>descriptionResourceKey</td><td>String</td><td>Any</td>
+ * <tr id="descriptionResourceKey">
+ * <td>descriptionResourceKey</td><td>String</td><td>Any</td>
  *
  * <td>A resource key for the description of this element.  In
  * conjunction with the {@code descriptionResourceBundleBaseName},
- * this can be used to find a localized version of the description.
- * The meaning of this field is defined by this specification but the
- * field is not set or used by the JMX API itself.</td>
+ * this can be used to find a localized version of the description.</td>
  *
  * <tr><td>enabled</td><td>String</td>
  * <td>MBeanAttributeInfo<br>MBeanNotificationInfo<br>MBeanOperationInfo</td>
@@ -216,6 +215,14 @@
  * StandardMBean} class will have this field in its MBeanInfo
  * Descriptor.</td>
  *
+ * <tr><td id="mxbeanMappingFactoryClass"><i>mxbeanMappingFactoryClass</i>
+ * </td><td>String</td>
+ * <td>MBeanInfo</td>
+ *
+ * <td>The name of the {@link MXBeanMappingFactory} class that was used for this
+ * MXBean, if it was not the {@linkplain MXBeanMappingFactory#DEFAULT default}
+ * one.</td>
+ *
  * <tr><td><a name="openType"><i>openType</i></a><td>{@link OpenType}</td>
  * <td>MBeanAttributeInfo<br>MBeanOperationInfo<br>MBeanParameterInfo</td>
  *
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/management/DescriptorFields.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.management;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Annotation that adds fields to a {@link Descriptor}.  This can be the
+ * Descriptor for an MBean, or for an attribute, operation, or constructor
+ * in an MBean, or for a parameter of an operation or constructor.</p>
+ *
+ * <p>Consider this Standard MBean interface, for example:</p>
+ *
+ * <pre>
+ * public interface CacheControlMBean {
+ *     <b>&#64;DescriptorFields("units=bytes")</b>
+ *     public long getCacheSize();
+ * }
+ * </pre>
+ *
+ * <p>When a Standard MBean is made using this interface, the usual rules
+ * mean that it will have an attribute called {@code CacheSize} of type
+ * {@code long}.  The {@code DescriptorFields} annotation will ensure
+ * that the {@link MBeanAttributeInfo} for this attribute will have a
+ * {@code Descriptor} that has a field called {@code units} with
+ * corresponding value {@code bytes}.</p>
+ *
+ * <p>Similarly, if the interface looks like this:</p>
+ *
+ * <pre>
+ * public interface CacheControlMBean {
+ *     <b>&#64;DescriptorFields({"units=bytes", "since=1.5"})</b>
+ *     public long getCacheSize();
+ * }
+ * </pre>
+ *
+ * <p>then the resulting {@code Descriptor} will contain the following
+ * fields:</p>
+ *
+ * <table border="2">
+ * <tr><th>Name</th><th>Value</th></tr>
+ * <tr><td>units</td><td>"bytes"</td></tr>
+ * <tr><td>since</td><td>"1.5"</td></tr>
+ * </table>
+ *
+ * <p>The {@code @DescriptorFields} annotation can be applied to:</p>
+ *
+ * <ul>
+ * <li>a Standard MBean or MXBean interface;
+ * <li>a method in such an interface;
+ * <li>a parameter of a method in a Standard MBean or MXBean interface
+ * when that method is an operation (not a getter or setter for an attribute);
+ * <li>a public constructor in the class that implements a Standard MBean
+ * or MXBean;
+ * <li>a parameter in such a constructor.
+ * </ul>
+ *
+ * <p>Other uses of the annotation will either fail to compile or be
+ * ignored.</p>
+ *
+ * <p>Interface annotations are checked only on the exact interface
+ * that defines the management interface of a Standard MBean or an
+ * MXBean, not on its parent interfaces.  Method annotations are
+ * checked only in the most specific interface in which the method
+ * appears; in other words, if a child interface overrides a method
+ * from a parent interface, only {@code @DescriptorFields} annotations in
+ * the method in the child interface are considered.
+ *
+ * <p>The Descriptor fields contributed in this way must be consistent
+ * with each other and with any fields contributed by {@link
+ * DescriptorKey &#64;DescriptorKey} annotations.  That is, two
+ * different annotations, or two members of the same annotation, must
+ * not define a different value for the same Descriptor field.  Fields
+ * from annotations on a getter method must also be consistent with
+ * fields from annotations on the corresponding setter method.</p>
+ *
+ * <p>The Descriptor resulting from these annotations will be merged
+ * with any Descriptor fields provided by the implementation, such as
+ * the <a href="Descriptor.html#immutableInfo">{@code
+ * immutableInfo}</a> field for an MBean.  The fields from the annotations
+ * must be consistent with these fields provided by the implementation.</p>
+ *
+ * <h4>{@literal @DescriptorFields and @DescriptorKey}</h4>
+ *
+ * <p>The {@link DescriptorKey @DescriptorKey} annotation provides
+ * another way to use annotations to define Descriptor fields.
+ * <code>&#64;DescriptorKey</code> requires more work but is also more
+ * robust, because there is less risk of mistakes such as misspelling
+ * the name of the field or giving an invalid value.
+ * <code>&#64;DescriptorFields</code> is more convenient but includes
+ * those risks.  <code>&#64;DescriptorFields</code> is more
+ * appropriate for occasional use, but for a Descriptor field that you
+ * add in many places, you should consider a purpose-built annotation
+ * using <code>&#64;DescriptorKey</code>.
+ *
+ * @since 1.7
+ */
+@Documented
+@Inherited  // for @MBean and @MXBean classes
+@Target({ElementType.CONSTRUCTOR, ElementType.METHOD,
+         ElementType.PARAMETER, ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+public @interface DescriptorFields {
+    /**
+     * <p>The descriptor fields.  Each element of the string looks like
+     * {@code "name=value"}.</p>
+     */
+    public String[] value();
+}
--- a/jdk/src/share/classes/javax/management/DescriptorKey.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/javax/management/DescriptorKey.java	Wed Jul 05 16:39:18 2017 +0200
@@ -33,6 +33,11 @@
  * an MBean, or for an attribute, operation, or constructor in an
  * MBean, or for a parameter of an operation or constructor.</p>
  *
+ * <p>(The {@link DescriptorFields @DescriptorFields} annotation
+ * provides another way to add fields to a {@code Descriptor}.  See
+ * the documentation for that annotation for a comparison of the
+ * two possibilities.)</p>
+ *
  * <p>Consider this annotation for example:</p>
  *
  * <pre>
@@ -57,7 +62,7 @@
  * <p>When a Standard MBean is made from the {@code CacheControlMBean},
  * the usual rules mean that it will have an attribute called
  * {@code CacheSize} of type {@code long}.  The {@code @Units}
- * attribute, given the above definition, will ensure that the
+ * annotation, given the above definition, will ensure that the
  * {@link MBeanAttributeInfo} for this attribute will have a
  * {@code Descriptor} that has a field called {@code units} with
  * corresponding value {@code bytes}.</p>
@@ -125,12 +130,13 @@
  * the method in the child interface are considered.
  *
  * <p>The Descriptor fields contributed in this way by different
- * annotations on the same program element must be consistent.  That
- * is, two different annotations, or two members of the same
- * annotation, must not define a different value for the same
- * Descriptor field.  Fields from annotations on a getter method must
- * also be consistent with fields from annotations on the
- * corresponding setter method.</p>
+ * annotations on the same program element must be consistent with
+ * each other and with any fields contributed by a {@link
+ * DescriptorFields &#64;DescriptorFields} annotation.  That is, two
+ * different annotations, or two members of the same annotation, must
+ * not define a different value for the same Descriptor field.  Fields
+ * from annotations on a getter method must also be consistent with
+ * fields from annotations on the corresponding setter method.</p>
  *
  * <p>The Descriptor resulting from these annotations will be merged
  * with any Descriptor fields provided by the implementation, such as
@@ -169,4 +175,36 @@
 @Target(ElementType.METHOD)
 public @interface DescriptorKey {
     String value();
+
+    /**
+     * <p>Do not include this field in the Descriptor if the annotation
+     * element has its default value.  For example, suppose {@code @Units} is
+     * defined like this:</p>
+     *
+     * <pre>
+     * &#64;Documented
+     * &#64;Target(ElementType.METHOD)
+     * &#64;Retention(RetentionPolicy.RUNTIME)
+     * public &#64;interface Units {
+     *     &#64;DescriptorKey("units")
+     *     String value();
+     *
+     *     <b>&#64;DescriptorKey(value = "descriptionResourceKey",
+     *                    omitIfDefault = true)</b>
+     *     String resourceKey() default "";
+     *
+     *     <b>&#64;DescriptorKey(value = "descriptionResourceBundleBaseName",
+     *                    omitIfDefault = true)</b>
+     *     String resourceBundleBaseName() default "";
+     * }
+     * </pre>
+     *
+     * <p>Then consider a usage such as {@code @Units("bytes")} or
+     * {@code @Units(value = "bytes", resourceKey = "")}, where the
+     * {@code resourceKey} and {@code resourceBundleBaseNames} elements
+     * have their default values.  In this case the Descriptor resulting
+     * from these annotations will not include a {@code descriptionResourceKey}
+     * or {@code descriptionResourceBundleBaseName} field.</p>
+     */
+    boolean omitIfDefault() default false;
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/management/DynamicWrapperMBean.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.management;
+
+/**
+ * <p>An MBean can implement this interface to affect how the MBeanServer's
+ * {@link MBeanServer#getClassLoaderFor getClassLoaderFor} and
+ * {@link MBeanServer#isInstanceOf isInstanceOf} methods behave.
+ * If these methods should refer to a wrapped object rather than the
+ * MBean object itself, then the {@link #getWrappedObject} method should
+ * return that wrapped object.</p>
+ *
+ * @see MBeanServer#getClassLoaderFor
+ * @see MBeanServer#isInstanceOf
+ */
+public interface DynamicWrapperMBean extends DynamicMBean {
+    /**
+     * <p>The resource corresponding to this MBean.  This is the object whose
+     * class name should be reflected by the MBean's
+     * {@link MBeanServer#getMBeanInfo getMBeanInfo()}.<!--
+     * -->{@link MBeanInfo#getClassName getClassName()} for example.  For a "plain"
+     * DynamicMBean it will be "this".  For an MBean that wraps another
+     * object, in the manner of {@link javax.management.StandardMBean}, it will be the
+     * wrapped object.</p>
+     *
+     * @return The resource corresponding to this MBean.
+     */
+    public Object getWrappedObject();
+
+    /**
+     * <p>The {@code ClassLoader} for this MBean, which can be used to
+     * retrieve resources associated with the MBean for example.  Usually,
+     * it will be
+     * {@link #getWrappedObject()}.{@code getClass().getClassLoader()}.
+     *
+     * @return The {@code ClassLoader} for this MBean.
+     */
+    public ClassLoader getWrappedClassLoader();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/management/Impact.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.management;
+
+/**
+ * <p>Defines the impact of an MBean operation, in particular whether it
+ * has an effect on the MBean or simply returns information.  This enum
+ * is used in the {@link ManagedOperation @ManagedOperation} annotation.
+ * Its {@link #getCode()} method can be used to get an {@code int} suitable
+ * for use as the {@code impact} parameter in an {@link MBeanOperationInfo}
+ * constructor.</p>
+ */
+public enum Impact {
+    /**
+     * The operation is read-like: it returns information but does not change
+     * any state.
+     * @see MBeanOperationInfo#INFO
+     */
+    INFO(MBeanOperationInfo.INFO),
+
+    /**
+     * The operation is write-like: it has an effect but does not return
+     * any information from the MBean.
+     * @see MBeanOperationInfo#ACTION
+     */
+    ACTION(MBeanOperationInfo.ACTION),
+
+    /**
+     * The operation is both read-like and write-like: it has an effect,
+     * and it also returns information from the MBean.
+     * @see MBeanOperationInfo#ACTION_INFO
+     */
+    ACTION_INFO(MBeanOperationInfo.ACTION_INFO),
+
+    /**
+     * The impact of the operation is unknown or cannot be expressed
+     * using one of the other values.
+     * @see MBeanOperationInfo#UNKNOWN
+     */
+    UNKNOWN(MBeanOperationInfo.UNKNOWN);
+
+    private final int code;
+
+    /**
+     * An instance of this enumeration, with the corresponding {@code int}
+     * code used by the {@link MBeanOperationInfo} constructors.
+     *
+     * @param code the code used by the {@code MBeanOperationInfo} constructors.
+     */
+    Impact(int code) {
+        this.code = code;
+    }
+
+    /**
+     * The equivalent {@code int} code used by the {@link MBeanOperationInfo}
+     * constructors.
+     * @return the {@code int} code.
+     */
+    public int getCode() {
+        return code;
+    }
+
+    /**
+     * Return the {@code Impact} value corresponding to the given {@code int}
+     * code.  The {@code code} is the value that would be used in an
+     * {@code MBeanOperationInfo} constructor.
+     *
+     * @param code the {@code int} code.
+     *
+     * @return an {@code Impact} value {@code x} such that
+     * {@code code == x.}{@link #getCode()}, or {@code Impact.UNKNOWN}
+     * if there is no such value.
+     */
+    public static Impact forCode(int code) {
+        switch (code) {
+            case MBeanOperationInfo.ACTION: return ACTION;
+            case MBeanOperationInfo.INFO: return INFO;
+            case MBeanOperationInfo.ACTION_INFO: return ACTION_INFO;
+            default: return UNKNOWN;
+        }
+    }
+}
--- a/jdk/src/share/classes/javax/management/JMX.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/javax/management/JMX.java	Wed Jul 05 16:39:18 2017 +0200
@@ -26,6 +26,7 @@
 package javax.management;
 
 import com.sun.jmx.mbeanserver.Introspector;
+import com.sun.jmx.mbeanserver.MBeanInjector;
 import com.sun.jmx.remote.util.ClassLogger;
 import java.beans.BeanInfo;
 import java.beans.PropertyDescriptor;
@@ -130,6 +131,7 @@
      * </pre>
      *
      * @see javax.management.JMX.ProxyOptions
+     * @see javax.management.StandardMBean.Options
      */
     public static class MBeanOptions implements Serializable, Cloneable {
         private static final long serialVersionUID = -6380842449318177843L;
@@ -739,4 +741,28 @@
         // exactly the string "MXBean" since that would mean there
         // was no package name, which is pretty unlikely in practice.
     }
+
+    /**
+     * <p>Test if an MBean can emit notifications.  An MBean can emit
+     * notifications if either it implements {@link NotificationBroadcaster}
+     * (perhaps through its child interface {@link NotificationEmitter}), or
+     * it uses <a href="MBeanRegistration.html#injection">resource
+     * injection</a> to obtain an instance of {@link SendNotification}
+     * through which it can send notifications.</p>
+     *
+     * @param mbean an MBean object.
+     * @return true if the given object is a valid MBean that can emit
+     * notifications; false if the object is a valid MBean but that
+     * cannot emit notifications.
+     * @throws NotCompliantMBeanException if the given object is not
+     * a valid MBean.
+     */
+    public static boolean isNotificationSource(Object mbean)
+            throws NotCompliantMBeanException {
+        if (mbean instanceof NotificationBroadcaster)
+            return true;
+        Object resource = (mbean instanceof DynamicWrapperMBean) ?
+            ((DynamicWrapperMBean) mbean).getWrappedObject() : mbean;
+        return (MBeanInjector.injectsSendNotification(resource));
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/management/MBean.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.management;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Indicates that the annotated class is a Standard MBean.  A Standard
+ * MBean class can be defined as in this example:</p>
+ *
+ * <pre>
+ * {@code @MBean}
+ * public class Configuration {
+ *     {@link ManagedAttribute @ManagedAttribute}
+ *     public int getCacheSize() {...}
+ *     {@code @ManagedAttribute}
+ *     public void setCacheSize(int size);
+ *
+ *     {@code @ManagedAttribute}
+ *     public long getLastChangedTime();
+ *
+ *     {@link ManagedOperation @ManagedOperation}
+ *     public void save();
+ * }
+ * </pre>
+ *
+ * <p>The class must be public.  Public methods within the class can be
+ * annotated with {@code @ManagedOperation} to indicate that they are
+ * MBean operations.  Public getter and setter methods within the class
+ * can be annotated with {@code @ManagedAttribute} to indicate that they define
+ * MBean attributes.</p>
+ *
+ * <p>If the MBean is to be an MXBean rather than a Standard MBean, then
+ * the {@link MXBean @MXBean} annotation must be used instead of
+ * {@code @MBean}.</p>
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+@Inherited
+public @interface MBean {
+}
--- a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java	Wed Jul 05 16:39:18 2017 +0200
@@ -46,25 +46,30 @@
         new MBeanOperationInfo[0];
 
     /**
-     * Indicates that the operation is read-like,
-     * it basically returns information.
+     * Indicates that the operation is read-like:
+     * it returns information but does not change any state.
+     * @see Impact#INFO
      */
     public static final int INFO = 0;
 
     /**
-     * Indicates that the operation is a write-like,
-     * and would modify the MBean in some way, typically by writing some value
-     * or changing a configuration.
+     * Indicates that the operation is write-like: it has an effect but does
+     * not return any information from the MBean.
+     * @see Impact#ACTION
      */
     public static final int ACTION = 1;
 
     /**
-     * Indicates that the operation is both read-like and write-like.
+     * Indicates that the operation is both read-like and write-like:
+     * it has an effect, and it also returns information from the MBean.
+     * @see Impact#ACTION_INFO
      */
     public static final int ACTION_INFO = 2;
 
     /**
-     * Indicates that the operation has an "unknown" nature.
+     * Indicates that the impact of the operation is unknown or cannot be
+     * expressed using one of the other values.
+     * @see Impact#UNKNOWN
      */
     public static final int UNKNOWN = 3;
 
@@ -120,8 +125,9 @@
      * describing the parameters(arguments) of the method.  This may be
      * null with the same effect as a zero-length array.
      * @param type The type of the method's return value.
-     * @param impact The impact of the method, one of <CODE>INFO,
-     * ACTION, ACTION_INFO, UNKNOWN</CODE>.
+     * @param impact The impact of the method, one of
+     * {@link #INFO}, {@link #ACTION}, {@link #ACTION_INFO},
+     * {@link #UNKNOWN}.
      */
     public MBeanOperationInfo(String name,
                               String description,
@@ -140,8 +146,9 @@
      * describing the parameters(arguments) of the method.  This may be
      * null with the same effect as a zero-length array.
      * @param type The type of the method's return value.
-     * @param impact The impact of the method, one of <CODE>INFO,
-     * ACTION, ACTION_INFO, UNKNOWN</CODE>.
+     * @param impact The impact of the method, one of
+     * {@link #INFO}, {@link #ACTION}, {@link #ACTION_INFO},
+     * {@link #UNKNOWN}.
      * @param descriptor The descriptor for the operation.  This may be null
      * which is equivalent to an empty descriptor.
      *
@@ -319,9 +326,14 @@
 
         for (int i = 0; i < classes.length; i++) {
             Descriptor d = Introspector.descriptorForAnnotations(annots[i]);
-            final String pn = "p" + (i + 1);
-            params[i] =
-                new MBeanParameterInfo(pn, classes[i].getName(), "", d);
+            String description = Introspector.descriptionForParameter(annots[i]);
+            if (description == null)
+                description = "";
+            String name = Introspector.nameForParameter(annots[i]);
+            if (name == null)
+                name = "p" + (i + 1);
+            params[i] = new MBeanParameterInfo(
+                    name, classes[i].getName(), description, d);
         }
 
         return params;
--- a/jdk/src/share/classes/javax/management/MBeanRegistration.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/javax/management/MBeanRegistration.java	Wed Jul 05 16:39:18 2017 +0200
@@ -27,9 +27,101 @@
 
 
 /**
- * Can be implemented by an MBean in order to
+ * <p>Can be implemented by an MBean in order to
  * carry out operations before and after being registered or unregistered from
- * the MBean server.
+ * the MBean Server.  An MBean can also implement this interface in order
+ * to get a reference to the MBean Server and/or its name within that
+ * MBean Server.</p>
+ *
+ * <h4 id="injection">Resource injection</h4>
+ *
+ * <p>As an alternative to implementing {@code MBeanRegistration}, if all that
+ * is needed is the MBean Server or ObjectName then an MBean can use
+ * <em>resource injection</em>.</p>
+ *
+ * <p>If a field in the MBean object has type {@link ObjectName} and has
+ * the {@link javax.annotation.Resource &#64;Resource} annotation,
+ * then the {@code ObjectName} under which the MBean is registered is
+ * assigned to that field during registration.  Likewise, if a field has type
+ * {@link MBeanServer} and the <code>&#64;Resource</code> annotation, then it will
+ * be set to the {@code MBeanServer} in which the MBean is registered.</p>
+ *
+ * <p>For example:</p>
+ *
+ * <pre>
+ * public Configuration implements ConfigurationMBean {
+ *     &#64;Resource
+ *     private volatile MBeanServer mbeanServer;
+ *     &#64;Resource
+ *     private volatile ObjectName objectName;
+ *     ...
+ *     void unregisterSelf() throws Exception {
+ *         mbeanServer.unregisterMBean(objectName);
+ *     }
+ * }
+ * </pre>
+ *
+ * <p>Resource injection can also be used on fields of type
+ * {@link SendNotification} to simplify notification sending.  Such a field
+ * will get a reference to an object of type {@code SendNotification} when
+ * the MBean is registered, and it can use this reference to send notifications.
+ * For example:</p>
+ *
+ * <pre>
+ * public Configuration implements ConfigurationMBean {
+ *     &#64;Resource
+ *     private volatile SendNotification sender;
+ *     ...
+ *     private void updated() {
+ *         Notification n = new Notification(...);
+ *         sender.sendNotification(n);
+ *     }
+ * }
+ * </pre>
+ *
+ * <p>A field to be injected must not be static.  It is recommended that
+ * such fields be declared {@code volatile}.</p>
+ *
+ * <p>It is also possible to use the <code>&#64;Resource</code> annotation on
+ * methods. Such a method must have a {@code void} return type and a single
+ * argument of the appropriate type, for example {@code ObjectName}.</p>
+ *
+ * <p>Any number of fields and methods may have the <code>&#64;Resource</code>
+ * annotation.  All fields and methods with type {@code ObjectName}
+ * (for example) will receive the same {@code ObjectName} value.</p>
+ *
+ * <p>Resource injection is available for all types of MBeans, not just
+ * Standard MBeans.</p>
+ *
+ * <p>If an MBean implements the {@link DynamicWrapperMBean} interface then
+ * resource injection happens on the object returned by that interface's
+ * {@link DynamicWrapperMBean#getWrappedObject() getWrappedObject()} method
+ * rather than on the MBean object itself.
+ *
+ * <p>Resource injection happens after the {@link #preRegister preRegister}
+ * method is called (if any), and before the MBean is actually registered
+ * in the MBean Server. If a <code>&#64;Resource</code> method throws
+ * an exception, the effect is the same as if {@code preRegister} had
+ * thrown the exception. In particular it will prevent the MBean from being
+ * registered.</p>
+ *
+ * <p>Resource injection can be used on a field or method where the type
+ * is a parent of the injected type, if the injected type is explicitly
+ * specified in the <code>&#64;Resource</code> annotation.  For example:</p>
+ *
+ * <pre>
+ *     &#64;Resource(type = MBeanServer.class)
+ *     private volatile MBeanServerConnection mbsc;
+ * </pre>
+ *
+ * <p>Formally, suppose <em>R</em> is the type in the <code>&#64;Resource</code>
+ * annotation and <em>T</em> is the type of the method parameter or field.
+ * Then one of <em>R</em> and <em>T</em> must be a subtype of the other
+ * (or they must be the same type).  Injection happens if this subtype
+ * is {@code MBeanServer}, {@code ObjectName}, or {@code SendNotification}.
+ * Otherwise the <code>&#64;Resource</code> annotation is ignored.</p>
+ *
+ * <p>Resource injection in MBeans is new in version 2.0 of the JMX API.</p>
  *
  * @since 1.5
  */
@@ -38,12 +130,12 @@
 
     /**
      * Allows the MBean to perform any operations it needs before
-     * being registered in the MBean server.  If the name of the MBean
+     * being registered in the MBean Server.  If the name of the MBean
      * is not specified, the MBean can provide a name for its
      * registration.  If any exception is raised, the MBean will not be
-     * registered in the MBean server.
+     * registered in the MBean Server.
      *
-     * @param server The MBean server in which the MBean will be registered.
+     * @param server The MBean Server in which the MBean will be registered.
      *
      * @param name The object name of the MBean.  This name is null if
      * the name parameter to one of the <code>createMBean</code> or
@@ -57,7 +149,7 @@
      * the returned value.
      *
      * @exception java.lang.Exception This exception will be caught by
-     * the MBean server and re-thrown as an {@link
+     * the MBean Server and re-thrown as an {@link
      * MBeanRegistrationException}.
      */
     public ObjectName preRegister(MBeanServer server,
--- a/jdk/src/share/classes/javax/management/MBeanServer.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/javax/management/MBeanServer.java	Wed Jul 05 16:39:18 2017 +0200
@@ -61,7 +61,7 @@
  * <CODE>ObjectName</CODE> is: <BR>
  * <CODE>JMImplementation:type=MBeanServerDelegate</CODE>.</p>
  *
- * <p>An object obtained from the {@link
+ * <p id="security">An object obtained from the {@link
  * MBeanServerFactory#createMBeanServer(String) createMBeanServer} or
  * {@link MBeanServerFactory#newMBeanServer(String) newMBeanServer}
  * methods of the {@link MBeanServerFactory} class applies security
@@ -661,13 +661,16 @@
                    ReflectionException;
 
     /**
-     * <p>Return the {@link java.lang.ClassLoader} that was used for
-     * loading the class of the named MBean.</p>
+     * <p>Return the {@link java.lang.ClassLoader} that was used for loading
+     * the class of the named MBean. If the MBean implements the {@link
+     * DynamicWrapperMBean} interface, then the returned value is the
+     * result of the {@link DynamicWrapperMBean#getWrappedClassLoader()}
+     * method.</p>
      *
      * @param mbeanName The ObjectName of the MBean.
      *
      * @return The ClassLoader used for that MBean.  If <var>l</var>
-     * is the MBean's actual ClassLoader, and <var>r</var> is the
+     * is the value specified by the rules above, and <var>r</var> is the
      * returned value, then either:
      *
      * <ul>
--- a/jdk/src/share/classes/javax/management/MBeanServerConnection.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/javax/management/MBeanServerConnection.java	Wed Jul 05 16:39:18 2017 +0200
@@ -839,6 +839,12 @@
      *
      * <p>Otherwise, the result is false.</p>
      *
+     * <p>If the MBean implements the {@link DynamicWrapperMBean}
+     * interface, then in the above rules X is the result of the MBean's {@link
+     * DynamicWrapperMBean#getWrappedObject() getWrappedObject()} method and L
+     * is the result of its {@link DynamicWrapperMBean#getWrappedClassLoader()
+     * getWrappedClassLoader()} method.
+     *
      * @param name The <CODE>ObjectName</CODE> of the MBean.
      * @param className The name of the class.
      *
--- a/jdk/src/share/classes/javax/management/MXBean.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/javax/management/MXBean.java	Wed Jul 05 16:39:18 2017 +0200
@@ -27,6 +27,7 @@
 
 import java.lang.annotation.Documented;
 import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
@@ -57,11 +58,13 @@
 import javax.management.openmbean.TabularType;
 
 /**
-    <p>Annotation to mark an interface explicitly as being an MXBean
-    interface, or as not being an MXBean interface.  By default, an
+    <p>Annotation to mark a class or interface explicitly as being an MXBean,
+    or as not being an MXBean.  By default, an
     interface is an MXBean interface if its name ends with {@code
-    MXBean}, as in {@code SomethingMXBean}.  The following interfaces
-    are MXBean interfaces:</p>
+    MXBean}, as in {@code SomethingMXBean}.  A class is never an MXBean by
+    default.</p>
+
+    <p>The following interfaces are MXBean interfaces:</p>
 
     <pre>
     public interface WhatsitMXBean {}
@@ -82,6 +85,11 @@
     public interface MisleadingMXBean {}
     </pre>
 
+    <p>A class can be annotated with {@code @MXBean} to indicate that it
+    is an MXBean.  In this case, its methods should have <code>&#64;{@link
+    ManagedAttribute}</code> or <code>&#64;{@link ManagedOperation}</code>
+    annotations, as described for <code>&#64;{@link MBean}</code>.</p>
+
     <h3 id="MXBean-spec">MXBean specification</h3>
 
     <p>The MXBean concept provides a simple way to code an MBean
@@ -1246,9 +1254,24 @@
    @since 1.6
 */
 
+/*
+ * This annotation is @Inherited because if an MXBean is defined as a
+ * class using annotations, then its subclasses are also MXBeans.
+ * For example:
+ * @MXBean
+ * public class Super {
+ *     @ManagedAttribute
+ *     public String getName() {...}
+ * }
+ * public class Sub extends Super {}
+ * Here Sub is an MXBean.
+ *
+ * The @Inherited annotation has no effect when applied to an interface.
+ */
 @Documented
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.TYPE)
+@Inherited
 public @interface MXBean {
     /**
        True if the annotated interface is an MXBean interface.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/management/ManagedAttribute.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.management;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Indicates that a method in an MBean class defines an MBean attribute.
+ * This annotation must be applied to a public method of a public class
+ * that is itself annotated with an {@link MBean @MBean} or
+ * {@link MXBean @MXBean} annotation, or inherits such an annotation from
+ * a superclass.</p>
+ *
+ * <p>The annotated method must be a getter or setter.  In other words,
+ * it must look like one of the following...</p>
+ *
+ * <pre>
+ * <i>T</i> get<i>Foo</i>()
+ * void set<i>Foo</i>(<i>T</i> param)
+ * </pre>
+ *
+ * <p>...where <i>{@code T}</i> is any type and <i>{@code Foo}</i> is the
+ * name of the attribute.  For any attribute <i>{@code Foo}</i>, if only
+ * a {@code get}<i>{@code Foo}</i> method has a {@code ManagedAttribute}
+ * annotation, then <i>{@code Foo}</i> is a read-only attribute.  If only
+ * a {@code set}<i>{@code Foo}</i> method has a {@code ManagedAttribute}
+ * annotation, then <i>{@code Foo}</i> is a write-only attribute.  If
+ * both {@code get}<i>{@code Foo}</i> and {@code set}<i>{@code Foo}</i>
+ * methods have the annotation, then <i>{@code Foo}</i> is a read-write
+ * attribute.  In this last case, the type <i>{@code T}</i> must be the
+ * same in both methods.</p>
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+@Documented
+public @interface ManagedAttribute {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/management/ManagedOperation.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.management;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Indicates that a method in an MBean class defines an MBean operation.
+ * This annotation can be applied to:</p>
+ *
+ * <ul>
+ * <li>A public method of a public class
+ * that is itself annotated with an {@link MBean @MBean} or
+ * {@link MXBean @MXBean} annotation, or inherits such an annotation from
+ * a superclass.</li>
+ * <li>A method of an MBean or MXBean interface.
+ * </ul>
+ *
+ * <p>Every method in an MBean or MXBean interface defines an MBean
+ * operation even without this annotation, but the annotation allows
+ * you to specify the impact of the operation:</p>
+ *
+ * <pre>
+ * public interface ConfigurationMBean {
+ *     {@code @ManagedOperation}(impact = {@link Impact#ACTION Impact.ACTION})
+ *     public void save();
+ *     ...
+ * }
+ * </pre>
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+@Documented
+public @interface ManagedOperation {
+    /**
+     * <p>The impact of this operation, as shown by
+     * {@link MBeanOperationInfo#getImpact()}.
+     */
+    Impact impact() default Impact.UNKNOWN;
+}
--- a/jdk/src/share/classes/javax/management/NotQueryExp.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/javax/management/NotQueryExp.java	Wed Jul 05 16:39:18 2017 +0200
@@ -91,6 +91,7 @@
         return "not (" + exp + ")";
     }
 
+    @Override
     String toQueryString() {
         return "not (" + Query.toString(exp) + ")";
     }
--- a/jdk/src/share/classes/javax/management/NotificationBroadcasterSupport.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/javax/management/NotificationBroadcasterSupport.java	Wed Jul 05 16:39:18 2017 +0200
@@ -58,7 +58,8 @@
  *
  * @since 1.5
  */
-public class NotificationBroadcasterSupport implements NotificationEmitter {
+public class NotificationBroadcasterSupport
+        implements NotificationEmitter, SendNotification {
     /**
      * Constructs a NotificationBroadcasterSupport where each listener is invoked by the
      * thread sending the notification. This constructor is equivalent to
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/management/NotificationInfo.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.management;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * <p>Specifies the kinds of notification an MBean can emit.  In both the
+ * following examples, the MBean emits notifications of type
+ * {@code "com.example.notifs.create"} and of type
+ * {@code "com.example.notifs.destroy"}:</p>
+ *
+ * <pre>
+ * // Example one: a Standard MBean
+ * {@code @NotificationInfo}(types={"com.example.notifs.create",
+ *                          "com.example.notifs.destroy"})
+ * public interface CacheMBean {...}
+ *
+ * public class Cache implements CacheMBean {...}
+ * </pre>
+ *
+ * <pre>
+ * // Example two: an annotated MBean
+ * {@link MBean @MBean}
+ * {@code @NotificationInfo}(types={"com.example.notifs.create",
+ *                          "com.example.notifs.destroy"})
+ * public class Cache {...}
+ * </pre>
+ *
+ * <p>Each {@code @NotificationInfo} produces an {@link
+ * MBeanNotificationInfo} inside the {@link MBeanInfo} of each MBean
+ * to which the annotation applies.</p>
+ *
+ * <p>If you need to specify different notification classes, or different
+ * descriptions for different notification types, then you can group
+ * several {@code @NotificationInfo} annotations into a containing
+ * {@link NotificationInfos @NotificationInfos} annotation.
+ *
+ * <p>The {@code NotificationInfo} and {@code NotificationInfos}
+ * annotations can be applied to the MBean implementation class, or to
+ * any parent class or interface.  These annotations on a class take
+ * precedence over annotations on any superclass or superinterface.
+ * If an MBean does not have these annotations on its class or any
+ * superclass, then superinterfaces are examined.  It is an error for
+ * more than one superinterface to have these annotations, unless one
+ * of them is a child of all the others.</p>
+ */
+@Documented
+@Inherited
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface NotificationInfo {
+    /**
+     * <p>The {@linkplain Notification#getType() notification types}
+     * that this MBean can emit.</p>
+     */
+    String[] types();
+
+    /**
+     * <p>The class that emitted notifications will have.  It is recommended
+     * that this be {@link Notification}, or one of its standard subclasses
+     * in the JMX API.</p>
+     */
+    Class<? extends Notification> notificationClass() default Notification.class;
+
+    /**
+     * <p>The description of this notification.  For example:
+     *
+     * <pre>
+     * {@code @NotificationInfo}(
+     *         types={"com.example.notifs.create"},
+     *         description={@code @Description}("object created"))
+     * </pre>
+     */
+    Description description() default @Description("");
+
+    /**
+     * <p>Additional descriptor fields for the derived {@code
+     * MBeanNotificationInfo}.  They are specified in the same way as
+     * for the {@link DescriptorFields @DescriptorFields} annotation,
+     * for example:</p>
+     * <pre>
+     * {@code @NotificationInfo}(
+     *         types={"com.example.notifs.create"},
+     *         descriptorFields={"severity=6"})
+     * </pre>
+     */
+    String[] descriptorFields() default {};
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/management/NotificationInfos.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.management;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import javax.management.remote.JMXConnectionNotification;
+
+/**
+ * <p>Specifies the kinds of notification an MBean can emit, when this
+ * cannot be represented by a single {@link NotificationInfo
+ * &#64;NotificationInfo} annotation.</p>
+ *
+ * <p>For example, this annotation specifies that an MBean can emit
+ * {@link AttributeChangeNotification} and {@link
+ * JMXConnectionNotification}:</p>
+ *
+ * <pre>
+ * {@code @NotificationInfos}(
+ *     {@code @NotificationInfo}(
+ *         types = {{@link AttributeChangeNotification#ATTRIBUTE_CHANGE}},
+ *         notificationClass = AttributeChangeNotification.class),
+ *     {@code @NotificationInfo}(
+ *         types = {{@link JMXConnectionNotification#OPENED},
+ *                  {@link JMXConnectionNotification#CLOSED}},
+ *         notificationClass = JMXConnectionNotification.class)
+ * )
+ * </pre>
+ *
+ * <p>If an MBean has both {@code NotificationInfo} and {@code
+ * NotificationInfos} on the same class or interface, the effect is
+ * the same as if the {@code NotificationInfo} were moved inside the
+ * {@code NotificationInfos}.</p>
+ */
+@Documented
+@Inherited
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface NotificationInfos {
+    /**
+     * <p>The {@link NotificationInfo} annotations.</p>
+     */
+    NotificationInfo[] value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/share/classes/javax/management/SendNotification.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javax.management;
+
+/**
+ * Interface implemented by objects that can be asked to send a notification.
+ */
+public interface SendNotification {
+    /**
+     * Sends a notification.
+     *
+     * @param notification The notification to send.
+     */
+    public void sendNotification(Notification notification);
+}
--- a/jdk/src/share/classes/javax/management/StandardEmitterMBean.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/javax/management/StandardEmitterMBean.java	Wed Jul 05 16:39:18 2017 +0200
@@ -25,6 +25,9 @@
 
 package javax.management;
 
+import com.sun.jmx.mbeanserver.MBeanInjector;
+import static javax.management.JMX.MBeanOptions;
+
 /**
  * <p>An MBean whose management interface is determined by reflection
  * on a Java interface, and that emits notifications.</p>
@@ -62,7 +65,7 @@
  * @since 1.6
  */
 public class StandardEmitterMBean extends StandardMBean
-        implements NotificationEmitter {
+        implements NotificationEmitter, SendNotification {
 
     private final NotificationEmitter emitter;
     private final MBeanNotificationInfo[] notificationInfo;
@@ -76,9 +79,10 @@
      * for {@code implementation} and {@code emitter} to be the same object.</p>
      *
      * <p>If {@code emitter} is an instance of {@code
-     * NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
+     * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
+     * then the MBean's {@link #sendNotification
      * sendNotification} method will call {@code emitter.}{@link
-     * NotificationBroadcasterSupport#sendNotification sendNotification}.</p>
+     * SendNotification#sendNotification sendNotification}.</p>
      *
      * <p>The array returned by {@link #getNotificationInfo()} on the
      * new MBean is a copy of the array returned by
@@ -90,20 +94,18 @@
      *
      * @param implementation the implementation of the MBean interface.
      * @param mbeanInterface a Standard MBean interface.
-     * @param emitter the object that will handle notifications.
+     * @param emitter the object that will handle notifications.  If null,
+     * a new {@code NotificationEmitter} will be constructed that also
+     * implements {@link SendNotification}.
      *
      * @throws IllegalArgumentException if the {@code mbeanInterface}
      *    does not follow JMX design patterns for Management Interfaces, or
      *    if the given {@code implementation} does not implement the
-     *    specified interface, or if {@code emitter} is null.
+     *    specified interface.
      */
     public <T> StandardEmitterMBean(T implementation, Class<T> mbeanInterface,
                                     NotificationEmitter emitter) {
-        super(implementation, mbeanInterface, false);
-        if (emitter == null)
-            throw new IllegalArgumentException("Null emitter");
-        this.emitter = emitter;
-        this.notificationInfo = emitter.getNotificationInfo();
+        this(implementation, mbeanInterface, false, emitter);
     }
 
     /**
@@ -118,9 +120,10 @@
      * same object.</p>
      *
      * <p>If {@code emitter} is an instance of {@code
-     * NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
+     * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
+     * then the MBean's {@link #sendNotification
      * sendNotification} method will call {@code emitter.}{@link
-     * NotificationBroadcasterSupport#sendNotification sendNotification}.</p>
+     * SendNotification#sendNotification sendNotification}.</p>
      *
      * <p>The array returned by {@link #getNotificationInfo()} on the
      * new MBean is a copy of the array returned by
@@ -134,21 +137,69 @@
      * @param mbeanInterface a Standard MBean interface.
      * @param isMXBean If true, the {@code mbeanInterface} parameter
      * names an MXBean interface and the resultant MBean is an MXBean.
-     * @param emitter the object that will handle notifications.
+     * @param emitter the object that will handle notifications.  If null,
+     * a new {@code NotificationEmitter} will be constructed that also
+     * implements {@link SendNotification}.
      *
      * @throws IllegalArgumentException if the {@code mbeanInterface}
      *    does not follow JMX design patterns for Management Interfaces, or
      *    if the given {@code implementation} does not implement the
-     *    specified interface, or if {@code emitter} is null.
+     *    specified interface.
      */
     public <T> StandardEmitterMBean(T implementation, Class<T> mbeanInterface,
                                     boolean isMXBean,
                                     NotificationEmitter emitter) {
-        super(implementation, mbeanInterface, isMXBean);
+        this(implementation, mbeanInterface,
+                isMXBean ? MBeanOptions.MXBEAN : null, emitter);
+    }
+
+    /**
+     * <p>Make an MBean whose management interface is specified by {@code
+     * mbeanInterface}, with the given implementation and options, and where
+     * notifications are handled by the given {@code NotificationEmitter}.
+     * Options select whether to make a Standard MBean or an MXBean, and
+     * whether the result of {@link #getWrappedObject()} is the {@code
+     * StandardEmitterMBean} object or the given implementation. The resultant
+     * MBean implements the {@code NotificationEmitter} interface by forwarding
+     * its methods to {@code emitter}. It is legal and useful for {@code
+     * implementation} and {@code emitter} to be the same object.</p>
+     *
+     * <p>If {@code emitter} is an instance of {@code
+     * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
+     * then the MBean's {@link #sendNotification
+     * sendNotification} method will call {@code emitter.}{@link
+     * SendNotification#sendNotification sendNotification}.</p>
+     *
+     * <p>The array returned by {@link #getNotificationInfo()} on the
+     * new MBean is a copy of the array returned by
+     * {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
+     * getNotificationInfo()} at the time of construction.  If the array
+     * returned by {@code emitter.getNotificationInfo()} later changes,
+     * that will have no effect on this object's
+     * {@code getNotificationInfo()}.</p>
+     *
+     * @param implementation the implementation of the MBean interface.
+     * @param mbeanInterface a Standard MBean interface.
+     * @param options MBeanOptions that control the operation of the resulting
+     * MBean.
+     * @param emitter the object that will handle notifications.  If null,
+     * a new {@code NotificationEmitter} will be constructed that also
+     * implements {@link SendNotification}.
+     *
+     * @throws IllegalArgumentException if the {@code mbeanInterface}
+     *    does not follow JMX design patterns for Management Interfaces, or
+     *    if the given {@code implementation} does not implement the
+     *    specified interface.
+     */
+    public <T> StandardEmitterMBean(T implementation, Class<T> mbeanInterface,
+                                    MBeanOptions options,
+                                    NotificationEmitter emitter) {
+        super(implementation, mbeanInterface, options);
         if (emitter == null)
-            throw new IllegalArgumentException("Null emitter");
+            emitter = defaultEmitter();
         this.emitter = emitter;
         this.notificationInfo = emitter.getNotificationInfo();
+        injectEmitter();
     }
 
     /**
@@ -159,9 +210,10 @@
      * by forwarding its methods to {@code emitter}.</p>
      *
      * <p>If {@code emitter} is an instance of {@code
-     * NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
+     * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
+     * then the MBean's {@link #sendNotification
      * sendNotification} method will call {@code emitter.}{@link
-     * NotificationBroadcasterSupport#sendNotification sendNotification}.</p>
+     * SendNotification#sendNotification sendNotification}.</p>
      *
      * <p>The array returned by {@link #getNotificationInfo()} on the
      * new MBean is a copy of the array returned by
@@ -175,20 +227,17 @@
      * the given {@code mbeanInterface}.</p>
      *
      * @param mbeanInterface a StandardMBean interface.
-     * @param emitter the object that will handle notifications.
+     * @param emitter the object that will handle notifications.  If null,
+     * a new {@code NotificationEmitter} will be constructed that also
+     * implements {@link SendNotification}.
      *
      * @throws IllegalArgumentException if the {@code mbeanInterface}
      *    does not follow JMX design patterns for Management Interfaces, or
-     *    if {@code this} does not implement the specified interface, or
-     *    if {@code emitter} is null.
+     *    if {@code this} does not implement the specified interface.
      */
     protected StandardEmitterMBean(Class<?> mbeanInterface,
                                    NotificationEmitter emitter) {
-        super(mbeanInterface, false);
-        if (emitter == null)
-            throw new IllegalArgumentException("Null emitter");
-        this.emitter = emitter;
-        this.notificationInfo = emitter.getNotificationInfo();
+        this(mbeanInterface, false, emitter);
     }
 
     /**
@@ -200,9 +249,10 @@
      * forwarding its methods to {@code emitter}.</p>
      *
      * <p>If {@code emitter} is an instance of {@code
-     * NotificationBroadcasterSupport} then the MBean's {@link #sendNotification
+     * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
+     * then the MBean's {@link #sendNotification
      * sendNotification} method will call {@code emitter.}{@link
-     * NotificationBroadcasterSupport#sendNotification sendNotification}.</p>
+     * SendNotification#sendNotification sendNotification}.</p>
      *
      * <p>The array returned by {@link #getNotificationInfo()} on the
      * new MBean is a copy of the array returned by
@@ -218,20 +268,86 @@
      * @param mbeanInterface a StandardMBean interface.
      * @param isMXBean If true, the {@code mbeanInterface} parameter
      * names an MXBean interface and the resultant MBean is an MXBean.
-     * @param emitter the object that will handle notifications.
+     * @param emitter the object that will handle notifications.  If null,
+     * a new {@code NotificationEmitter} will be constructed that also
+     * implements {@link SendNotification}.
      *
      * @throws IllegalArgumentException if the {@code mbeanInterface}
      *    does not follow JMX design patterns for Management Interfaces, or
-     *    if {@code this} does not implement the specified interface, or
-     *    if {@code emitter} is null.
+     *    if {@code this} does not implement the specified interface.
      */
     protected StandardEmitterMBean(Class<?> mbeanInterface, boolean isMXBean,
                                    NotificationEmitter emitter) {
-        super(mbeanInterface, isMXBean);
+        this(mbeanInterface, isMXBean ? MBeanOptions.MXBEAN : null, emitter);
+    }
+
+    /**
+     * <p>Make an MBean whose management interface is specified by {@code
+     * mbeanInterface}, with the given options, and where notifications are
+     * handled by the given {@code NotificationEmitter}. This constructor can
+     * be used to make either Standard MBeans or MXBeans. The resultant MBean
+     * implements the {@code NotificationEmitter} interface by forwarding its
+     * methods to {@code emitter}.</p>
+     *
+     * <p>If {@code emitter} is an instance of {@code
+     * SendNotification} (for example, a {@link NotificationBroadcasterSupport}),
+     * then the MBean's {@link #sendNotification
+     * sendNotification} method will call {@code emitter.}{@link
+     * SendNotification#sendNotification sendNotification}.</p>
+     *
+     * <p>The array returned by {@link #getNotificationInfo()} on the
+     * new MBean is a copy of the array returned by
+     * {@code emitter.}{@link NotificationBroadcaster#getNotificationInfo
+     * getNotificationInfo()} at the time of construction.  If the array
+     * returned by {@code emitter.getNotificationInfo()} later changes,
+     * that will have no effect on this object's
+     * {@code getNotificationInfo()}.</p>
+     *
+     * <p>This constructor must be called from a subclass that implements
+     * the given {@code mbeanInterface}.</p>
+     *
+     * @param mbeanInterface a StandardMBean interface.
+     * @param options MBeanOptions that control the operation of the resulting
+     * MBean.
+     * @param emitter the object that will handle notifications.  If null,
+     * a new {@code NotificationEmitter} will be constructed that also
+     * implements {@link SendNotification}.
+     *
+     * @throws IllegalArgumentException if the {@code mbeanInterface}
+     *    does not follow JMX design patterns for Management Interfaces, or
+     *    if {@code this} does not implement the specified interface.
+     */
+    protected StandardEmitterMBean(Class<?> mbeanInterface, MBeanOptions options,
+                                   NotificationEmitter emitter) {
+        super(mbeanInterface, options);
         if (emitter == null)
-            throw new IllegalArgumentException("Null emitter");
+            emitter = defaultEmitter();
         this.emitter = emitter;
         this.notificationInfo = emitter.getNotificationInfo();
+        injectEmitter();
+    }
+
+    private NotificationEmitter defaultEmitter() {
+        MBeanNotificationInfo[] mbnis = getNotificationInfo();
+        // Will be null unless getNotificationInfo() is overridden,
+        // since the notificationInfo field has not been set at this point.
+        if (mbnis == null)
+            mbnis = getMBeanInfo().getNotifications();
+        return new NotificationBroadcasterSupport(mbnis);
+    }
+
+    private void injectEmitter() {
+        if (emitter instanceof SendNotification) {
+            try {
+                Object resource = getImplementation();
+                SendNotification send = (SendNotification) emitter;
+                MBeanInjector.injectSendNotification(resource, send);
+            } catch (RuntimeException e) {
+                throw e;
+            } catch (Exception e) {
+                throw new IllegalArgumentException(e);
+            }
+        }
     }
 
     public void removeNotificationListener(NotificationListener listener)
@@ -259,10 +375,10 @@
     /**
      * <p>Sends a notification.</p>
      *
-     * <p>If the {@code emitter} parameter to the constructor was an
-     * instance of {@code NotificationBroadcasterSupport} then this
-     * method will call {@code emitter.}{@link
-     * NotificationBroadcasterSupport#sendNotification
+     * <p>If the {@code emitter} parameter to the constructor was
+     * an instance of {@link SendNotification}, such as {@link
+     * NotificationBroadcasterSupport}, then this method will call {@code
+     * emitter.}{@link SendNotification#sendNotification
      * sendNotification}.</p>
      *
      * @param n the notification to send.
@@ -271,13 +387,12 @@
      * constructor was not a {@code NotificationBroadcasterSupport}.
      */
     public void sendNotification(Notification n) {
-        if (emitter instanceof NotificationBroadcasterSupport)
-            ((NotificationBroadcasterSupport) emitter).sendNotification(n);
+        if (emitter instanceof SendNotification)
+            ((SendNotification) emitter).sendNotification(n);
         else {
             final String msg =
                 "Cannot sendNotification when emitter is not an " +
-                "instance of NotificationBroadcasterSupport: " +
-                emitter.getClass().getName();
+                "instance of SendNotification: " + emitter.getClass().getName();
             throw new ClassCastException(msg);
         }
     }
@@ -292,6 +407,7 @@
      * @param info The default MBeanInfo derived by reflection.
      * @return the MBeanNotificationInfo[] for the new MBeanInfo.
      */
+    @Override
     MBeanNotificationInfo[] getNotifications(MBeanInfo info) {
         return getNotificationInfo();
     }
--- a/jdk/src/share/classes/javax/management/StandardMBean.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/javax/management/StandardMBean.java	Wed Jul 05 16:39:18 2017 +0200
@@ -27,6 +27,7 @@
 
 import com.sun.jmx.mbeanserver.DescriptorCache;
 import com.sun.jmx.mbeanserver.Introspector;
+import com.sun.jmx.mbeanserver.MBeanInjector;
 import com.sun.jmx.mbeanserver.MBeanSupport;
 import com.sun.jmx.mbeanserver.MXBeanSupport;
 import com.sun.jmx.mbeanserver.StandardMBeanSupport;
@@ -125,7 +126,78 @@
  *
  * @since 1.5
  */
-public class StandardMBean implements DynamicMBean, MBeanRegistration {
+public class StandardMBean implements DynamicWrapperMBean, MBeanRegistration {
+
+    /**
+     * <p>Options controlling the behavior of {@code StandardMBean} instances.</p>
+     */
+    public static class Options extends JMX.MBeanOptions {
+        private static final long serialVersionUID = 5107355471177517164L;
+
+        private boolean wrappedVisible;
+
+        /**
+         * <p>Construct an {@code Options} object where all options have
+         * their default values.</p>
+         */
+        public Options() {}
+
+        @Override
+        public Options clone() {
+            return (Options) super.clone();
+        }
+
+        /**
+         * <p>Defines whether the {@link StandardMBean#getWrappedObject()
+         * getWrappedObject} method returns the wrapped object.</p>
+         *
+         * <p>If this option is true, then {@code getWrappedObject()} will return
+         * the same object as {@link StandardMBean#getImplementation()
+         * getImplementation}.  Otherwise, it will return the
+         * StandardMBean instance itself.  The setting of this option
+         * affects the behavior of {@link MBeanServer#getClassLoaderFor
+         * MBeanServer.getClassLoaderFor} and {@link MBeanServer#isInstanceOf
+         * MBeanServer.isInstanceOf}.  The default value is false for
+         * compatibility reasons, but true is a better value for most new code.</p>
+         *
+         * @return true if this StandardMBean's {@link
+         * StandardMBean#getWrappedObject getWrappedObject} returns the wrapped
+         * object.
+         */
+        public boolean isWrappedObjectVisible() {
+            return this.wrappedVisible;
+        }
+
+        /**
+         * <p>Set the {@link #isWrappedObjectVisible WrappedObjectVisible} option
+         * to the given value.</p>
+         * @param visible the new value.
+         */
+        public void setWrappedObjectVisible(boolean visible) {
+            this.wrappedVisible = visible;
+        }
+
+        // Canonical objects for each of (MXBean,!MXBean) x (WVisible,!WVisible)
+        private static final Options[] CANONICALS = {
+            new Options(), new Options(), new Options(), new Options(),
+        };
+        static {
+            CANONICALS[1].setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT);
+            CANONICALS[2].setWrappedObjectVisible(true);
+            CANONICALS[3].setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT);
+            CANONICALS[3].setWrappedObjectVisible(true);
+        }
+        @Override
+        MBeanOptions[] canonicals() {
+            return CANONICALS;
+        }
+
+        @Override
+        boolean same(MBeanOptions opts) {
+            return (super.same(opts) && opts instanceof Options &&
+                    ((Options) opts).wrappedVisible == wrappedVisible);
+        }
+    }
 
     private final static DescriptorCache descriptors =
         DescriptorCache.getInstance(JMX.proof);
@@ -347,7 +419,7 @@
      *        the management interface associated with the given
      *        implementation.
      * @param options MBeanOptions that control the operation of the resulting
-     *        MBean, as documented in the {@link MBeanOptions} class.
+     *        MBean.
      * @param <T> Allows the compiler to check
      * that {@code implementation} does indeed implement the class
      * described by {@code mbeanInterface}.  The compiler can only
@@ -381,7 +453,7 @@
      * @param mbeanInterface The Management Interface exported by this
      *        MBean.
      * @param options MBeanOptions that control the operation of the resulting
-     *        MBean, as documented in the {@link MBeanOptions} class.
+     *        MBean.
      *
      * @exception IllegalArgumentException if the <var>mbeanInterface</var>
      *    does not follow JMX design patterns for Management Interfaces, or
@@ -441,7 +513,67 @@
      * @see #setImplementation
      **/
     public Object getImplementation() {
-        return mbean.getResource();
+        return mbean.getWrappedObject();
+    }
+
+    /**
+     * <p>Get the wrapped implementation object or return this object.</p>
+     *
+     * <p>For compatibility reasons, this method only returns the wrapped
+     * implementation object if the {@link Options#isWrappedObjectVisible
+     * WrappedObjectVisible} option was specified when this StandardMBean
+     * was created.  Otherwise it returns {@code this}.</p>
+     *
+     * <p>If you want the MBeanServer's {@link MBeanServer#getClassLoaderFor
+     * getClassLoaderFor} and {@link MBeanServer#isInstanceOf
+     * isInstanceOf} methods to refer to the wrapped implementation and
+     * not this StandardMBean object, then you must set the
+     * {@code WrappedObjectVisible} option, for example using:</p>
+     *
+     * <pre>
+     * StandardMBean.Options opts = new StandardMBean.Options();
+     * opts.setWrappedObjectVisible(true);
+     * StandardMBean mbean = new StandardMBean(impl, MyMBean.class, opts);
+     * </pre>
+     *
+     * @return The wrapped implementation object, or this StandardMBean
+     * instance.
+     */
+    public Object getWrappedObject() {
+        if (options instanceof Options &&
+                ((Options) options).isWrappedObjectVisible())
+            return getImplementation();
+        else
+            return this;
+    }
+
+    /**
+     * <p>Get the ClassLoader of the wrapped implementation object or of this
+     * object.</p>
+     *
+     * <p>For compatibility reasons, this method only returns the ClassLoader
+     * of the wrapped implementation object if the {@link
+     * Options#isWrappedObjectVisible WrappedObjectVisible} option was
+     * specified when this StandardMBean was created. Otherwise it returns
+     * {@code this.getClass().getClassLoader()}.</p>
+     *
+     * <p>If you want the MBeanServer's {@link MBeanServer#getClassLoaderFor
+     * getClassLoaderFor} and {@link MBeanServer#isInstanceOf
+     * isInstanceOf} methods to refer to the wrapped implementation and
+     * not this StandardMBean object, then you must set the
+     * {@code WrappedObjectVisible} option, for example using:</p>
+     *
+     * <pre>
+     * StandardMBean.Options opts = new StandardMBean.Options();
+     * opts.setWrappedObjectVisible(true);
+     * StandardMBean mbean = new StandardMBean(impl, MyMBean.class, opts);
+     * </pre>
+     *
+     * @return The ClassLoader of the wrapped Cimplementation object, or of
+     * this StandardMBean instance.
+     */
+    public ClassLoader getWrappedClassLoader() {
+        return getWrappedObject().getClass().getClassLoader();
     }
 
     /**
@@ -457,7 +589,7 @@
      * @return The class of the implementation of this Standard MBean (or MXBean).
      **/
     public Class<?> getImplementationClass() {
-        return mbean.getResource().getClass();
+        return mbean.getWrappedObject().getClass();
     }
 
     /**
@@ -559,7 +691,7 @@
 
         MBeanSupport msupport = mbean;
         final MBeanInfo bi = msupport.getMBeanInfo();
-        final Object impl = msupport.getResource();
+        final Object impl = msupport.getWrappedObject();
 
         final boolean immutableInfo = immutableInfo(this.getClass());
 
@@ -1184,6 +1316,7 @@
     public ObjectName preRegister(MBeanServer server, ObjectName name)
             throws Exception {
         mbean.register(server, name);
+        MBeanInjector.inject(mbean.getWrappedObject(), server, name);
         return name;
     }
 
--- a/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/javax/management/modelmbean/RequiredModelMBean.java	Wed Jul 05 16:39:18 2017 +0200
@@ -23,7 +23,7 @@
  * have any questions.
  */
 /*
- * @author    IBM Corp.
+ * @(#)author    IBM Corp.
  *
  * Copyright IBM Corp. 1999-2000.  All rights reserved.
  */
@@ -55,6 +55,7 @@
 import javax.management.AttributeList;
 import javax.management.AttributeNotFoundException;
 import javax.management.Descriptor;
+import javax.management.DynamicWrapperMBean;
 import javax.management.InstanceNotFoundException;
 import javax.management.InvalidAttributeValueException;
 import javax.management.ListenerNotFoundException;
@@ -115,7 +116,7 @@
  */
 
 public class RequiredModelMBean
-    implements ModelMBean, MBeanRegistration, NotificationEmitter {
+    implements ModelMBean, MBeanRegistration, NotificationEmitter, DynamicWrapperMBean {
 
     /*************************************/
     /* attributes                        */
@@ -133,6 +134,9 @@
      * and operations will be executed */
     private Object managedResource = null;
 
+    /* true if getWrappedObject returns the wrapped resource */
+    private boolean visible;
+
     /* records the registering in MBeanServer */
     private boolean registered = false;
     private transient MBeanServer server = null;
@@ -318,9 +322,13 @@
      *
      * @param mr Object that is the managed resource
      * @param mr_type The type of reference for the managed resource.
-     *     <br>Can be: "ObjectReference", "Handle", "IOR", "EJBHandle",
-     *         or "RMIReference".
-     *     <br>In this implementation only "ObjectReference" is supported.
+     *     <br>Can be: "ObjectReference", "VisibleObjectReference",
+     *         "Handle", "IOR", "EJBHandle", or "RMIReference".
+     *     <br>In this implementation only "ObjectReference" and
+     *         "VisibleObjectReference" are supported.  The two
+     *         types are equivalent except for the behavior of the
+     *         {@link #getWrappedObject()} and {@link #getWrappedClassLoader()}
+     *         methods.
      *
      * @exception MBeanException The initializer of the object has
      *            thrown an exception.
@@ -340,10 +348,11 @@
                 "setManagedResource(Object,String)","Entry");
         }
 
+        visible = "visibleObjectReference".equalsIgnoreCase(mr_type);
+
         // check that the mr_type is supported by this JMXAgent
         // only "objectReference" is supported
-        if ((mr_type == null) ||
-            (! mr_type.equalsIgnoreCase("objectReference"))) {
+        if (!"objectReference".equalsIgnoreCase(mr_type) && !visible) {
             if (MODELMBEAN_LOGGER.isLoggable(Level.FINER)) {
                 MODELMBEAN_LOGGER.logp(Level.FINER,
                         RequiredModelMBean.class.getName(),
@@ -369,6 +378,51 @@
     }
 
     /**
+     * <p>Get the managed resource for this Model MBean. For compatibility
+     * reasons, the managed resource is only returned if the resource type
+     * specified to {@link #setManagedResource setManagedResource} was {@code
+     * "visibleObjectReference"}. Otherwise, {@code this} is returned.</p>
+     *
+     * @return The value that was specified to {@link #setManagedResource
+     * setManagedResource}, if the resource type is {@code
+     * "visibleObjectReference"}. Otherwise, {@code this}.
+     */
+    public Object getWrappedObject() {
+        if (visible)
+            return managedResource;
+        else
+            return this;
+    }
+
+    /**
+     * <p>Get the ClassLoader of the managed resource for this Model MBean. For
+     * compatibility reasons, the ClassLoader of the managed resource is only
+     * returned if the resource type specified to {@link #setManagedResource
+     * setManagedResource} was {@code "visibleObjectReference"}. Otherwise,
+     * {@code this.getClass().getClassLoader()} is returned.</p>
+     *
+     * @return The ClassLoader of the value that was specified to
+     * {@link #setManagedResource setManagedResource}, if the resource
+     * type is {@code "visibleObjectReference"}. Otherwise, {@code
+     * this.getClass().getClassLoader()}.
+     */
+    public ClassLoader getWrappedClassLoader() {
+        return getWrappedObject().getClass().getClassLoader();
+    }
+
+    private static boolean isTrue(Descriptor d, String field) {
+        if (d == null)
+            return false;
+        Object x = d.getFieldValue(field);
+        if (x instanceof Boolean)
+            return (Boolean) x;
+        if (!(x instanceof String))
+            return false;
+        String s = (String) x;
+        return ("true".equalsIgnoreCase(s) || "T".equalsIgnoreCase(s));
+    }
+
+    /**
      * <p>Instantiates this MBean instance with the data found for
      * the MBean in the persistent store.  The data loaded could include
      * attribute and operation values.</p>
--- a/jdk/src/share/classes/javax/management/monitor/package.html	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/javax/management/monitor/package.html	Wed Jul 05 16:39:18 2017 +0200
@@ -38,14 +38,17 @@
       so within the access control context of the
       {@link javax.management.monitor.Monitor#start} caller.</p>
 
-      <p>The value being monitored can be a simple value contained within a
-      complex type. For example, the {@link java.lang.management.MemoryMXBean
-      MemoryMXBean} defined in <tt>java.lang.management</tt> has an attribute
-      <tt>HeapMemoryUsage</tt> of type {@link java.lang.management.MemoryUsage
-      MemoryUsage}. To monitor the amount of <i>used</i> memory, described by
-      the <tt>used</tt> property of <tt>MemoryUsage</tt>, you could monitor
-      "<tt>HeapMemoryUsage.used</tt>". That string would be the argument to
-      {@link javax.management.monitor.MonitorMBean#setObservedAttribute(String)
+      <p id="complex">The value being monitored can be a simple value
+      contained within a complex type. For example, the {@link
+      java.lang.management.MemoryMXBean MemoryMXBean} defined in
+      <tt>java.lang.management</tt> has an attribute
+      <tt>HeapMemoryUsage</tt> of type {@link
+      java.lang.management.MemoryUsage MemoryUsage}. To monitor the
+      amount of <i>used</i> memory, described by the <tt>used</tt>
+      property of <tt>MemoryUsage</tt>, you could monitor
+      "<tt>HeapMemoryUsage.used</tt>". That string would be the
+      argument to {@link
+      javax.management.monitor.MonitorMBean#setObservedAttribute(String)
       setObservedAttribute}.</p>
 
       <p>The rules used to interpret an <tt>ObservedAttribute</tt> like
--- a/jdk/src/share/classes/javax/management/package.html	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/javax/management/package.html	Wed Jul 05 16:39:18 2017 +0200
@@ -56,41 +56,41 @@
 	resource.  It has a <em>management interface</em> consisting
 	of:</p>
 
-      <ul>
-	<li>named and typed attributes that can be read and/or
-	  written</li>
-	
-	<li>named and typed operations that can be invoked</li>
+        <ul>
+            <li>named and typed attributes that can be read and/or
+            written</li>
 
-	<li>typed notifications that can be emitted by the MBean.</li>
-      </ul>
+            <li>named and typed operations that can be invoked</li>
+
+            <li>typed notifications that can be emitted by the MBean.</li>
+        </ul>
 
-      <p>For example, an MBean representing an application's
-	configuration could have attributes representing the different
-	configuration items.  Reading the <code>CacheSize</code>
-	attribute would return the current value of that item.
-	Writing it would update the item, potentially changing the
-	behavior of the running application.  An operation such as
-	<code>save</code> could store the current configuration
-	persistently.  A notification such as
-	<code>ConfigurationChangedNotification</code> could be sent
-	every time the configuration is changed.</p>
+        <p>For example, an MBean representing an application's
+            configuration could have attributes representing the different
+            configuration items.  Reading the <code>CacheSize</code>
+            attribute would return the current value of that item.
+            Writing it would update the item, potentially changing the
+            behavior of the running application.  An operation such as
+            <code>save</code> could store the current configuration
+            persistently.  A notification such as
+            <code>ConfigurationChangedNotification</code> could be sent
+        every time the configuration is changed.</p>
 
-      <p>In the standard usage of the JMX API, MBeans are implemented
-	as Java objects.  However, as explained below, these objects are
-	not usually referenced directly.</p>
+        <p>In the standard usage of the JMX API, MBeans are implemented
+            as Java objects.  However, as explained below, these objects are
+        not usually referenced directly.</p>
 
 
-      <h3>Standard MBeans</h3>
+        <h3>Standard MBeans</h3>
 
-      <p>To make MBean implementation simple, the JMX API includes the
-	notion of <em>Standard MBeans</em>.  A Standard MBean is one
-	whose attributes and operations are deduced from a Java
-	interface using certain naming patterns, similar to those used
-	by JavaBeans<sup><font size="-1">TM</font></sup>.  For
-	example, consider an interface like this:</p>
+        <p>To make MBean implementation simple, the JMX API includes the
+            notion of <em>Standard MBeans</em>.  A Standard MBean is one
+            whose attributes and operations are deduced from a Java
+            interface using certain naming patterns, similar to those used
+            by JavaBeans<sup><font size="-1">TM</font></sup>.  For
+        example, consider an interface like this:</p>
 
-      <pre>
+        <pre>
     public interface ConfigurationMBean {
 	public int getCacheSize();
 	public void setCacheSize(int size);
@@ -128,107 +128,148 @@
 	class.</p>
 
 
-      <h3>MXBeans</h3>
-      
-      <p>An <em>MXBean</em> is a variant of Standard MBean where complex
-        types are mapped to a standard set of types defined in the
-        {@link javax.management.openmbean} package.  MXBeans are appropriate
-        if you would otherwise need to reference application-specific
-        classes in your MBean interface.  They are described in detail
-        in the specification for {@link javax.management.MXBean MXBean}.
+        <h3 id="stdannot">Defining Standard MBeans with annotations</h3>
 
+        <p>As an alternative to creating an interface such as
+            <code>ConfigurationMBean</code> and a class that implements it,
+            you can write just the class, and use annotations to pick out the
+            public methods that will make up the management interface. For
+            example, the following class has the same management interface
+            as a <code>Configuration</code> class that implements the
+        <code>ConfigurationMBean</code> interface above.</p>
 
-      <h3>Dynamic MBeans</h3>
+        <pre>
+    {@link javax.management.MBean @MBean}
+    public class Configuration {
+        {@link javax.management.ManagedAttribute @ManagedAttribute}
+        public int getCacheSize() {...}
+        &#64;ManagedAttribute
+        public void setCacheSize(int size) {...}
+
+        &#64;ManagedAttribute
+        public long getLastChangedTime() {...}
 
-      <p>A <em>Dynamic MBean</em> is an MBean that defines its
-	management interface at run-time.  For example, a configuration
-	MBean could determine the names and types of the attributes it
-	exposes by parsing an XML file.</p>
+        {@link javax.management.ManagedOperation @ManagedOperation}
+        public void save() {...}
+        ...
+    }
+        </pre>
 
-      <p>Any Java object of a class that implements the {@link
-	javax.management.DynamicMBean DynamicMBean} interface is a
-	Dynamic MBean.</p>
+        <p>This approach simplifies development, but it does have two
+            potential drawbacks.  First, if you run the Javadoc tool on
+            this class, the documentation of the management interface may
+            be mixed in with the documentation of non-management methods
+            in the class.  Second, you cannot make a proxy
+            as described <a href="#proxy">below</a> if you do not have an
+        interface like <code>ConfigurationMBean</code>.</p>
 
 
-      <h3>Open MBeans</h3>
+        <h3>MXBeans</h3>
 
-      <p>An <em>Open MBean</em> is a kind of Dynamic MBean where the
-	types of attributes and of operation parameters and return
-	values are built using a small set of predefined Java classes.
-	Open MBeans facilitate operation with remote management programs
-	that do not necessarily have access to application-specific
-	types, including non-Java programs.  Open MBeans are defined by
-	the package <a href="openmbean/package-summary.html"><code>
-	    javax.management.openmbean</code></a>.</p>
+        <p>An <em>MXBean</em> is a variant of Standard MBean where complex
+            types are mapped to a standard set of types defined in the
+            {@link javax.management.openmbean} package.  MXBeans are appropriate
+            if you would otherwise need to reference application-specific
+            classes in your MBean interface.  They are described in detail
+        in the specification for {@link javax.management.MXBean MXBean}.</p>
+
+        <p>You can define MXBeans using annotations as described
+            in the <a href="#stdannot">previous section</a>, but
+            using the <code>&#64;MXBean</code> annotation instead of
+        <code>&#64;MBean</code>.</p>
 
 
-      <h3>Model MBeans</h3>
+        <h3>Dynamic MBeans</h3>
 
-      <p>A <em>Model MBean</em> is a kind of Dynamic MBean that acts
-	as a bridge between the management interface and the
-	underlying managed resource.  Both the management interface and
-	the managed resource are specified as Java objects.  The same
-	Model MBean implementation can be reused many times with
-	different management interfaces and managed resources, and it can
-	provide common functionality such as persistence and caching.
-	Model MBeans are defined by the package
-	<a href="modelmbean/package-summary.html"><code>
-	    javax.management.modelmbean</code></a>.</p>
+        <p>A <em>Dynamic MBean</em> is an MBean that defines its
+            management interface at run-time.  For example, a configuration
+            MBean could determine the names and types of the attributes it
+        exposes by parsing an XML file.</p>
+
+        <p>Any Java object of a class that implements the {@link
+            javax.management.DynamicMBean DynamicMBean} interface is a
+        Dynamic MBean.</p>
 
 
-      <h2>MBean Server</h2>
-      
-      <p>To be useful, an MBean must be registered in an <em>MBean
-	  Server</em>.  An MBean Server is a repository of MBeans.
-	Usually the only access to the MBeans is through the MBean
-	Server.  In other words, code no longer accesses the Java
-	object implementing the MBean directly, but instead accesses
-	the MBean by name through the MBean Server.  Each MBean has a
-	unique name within the MBean Server, defined by the {@link
-	javax.management.ObjectName ObjectName} class.</p>
-      
-      <p>An MBean Server is an object implementing the interface
-        {@link javax.management.MBeanServer MBeanServer}.  
-        The most convenient MBean Server to use is the 
-        <em>Platform MBean Server</em>.  This is a
-	single MBean Server that can be shared by different managed
-	components running within the same Java Virtual Machine.  The
-	Platform MBean Server is accessed with the method {@link
-	java.lang.management.ManagementFactory#getPlatformMBeanServer()}.</p>
+        <h3>Open MBeans</h3>
+
+        <p>An <em>Open MBean</em> is a kind of Dynamic MBean where the
+            types of attributes and of operation parameters and return
+            values are built using a small set of predefined Java classes.
+            Open MBeans facilitate operation with remote management programs
+            that do not necessarily have access to application-specific
+            types, including non-Java programs.  Open MBeans are defined by
+            the package <a href="openmbean/package-summary.html"><code>
+        javax.management.openmbean</code></a>.</p>
+
 
-      <p>Application code can also create a new MBean Server, or
-	access already-created MBean Servers, using the {@link
-	javax.management.MBeanServerFactory MBeanServerFactory} class.</p>
+        <h3>Model MBeans</h3>
+
+        <p>A <em>Model MBean</em> is a kind of Dynamic MBean that acts
+            as a bridge between the management interface and the
+            underlying managed resource.  Both the management interface and
+            the managed resource are specified as Java objects.  The same
+            Model MBean implementation can be reused many times with
+            different management interfaces and managed resources, and it can
+            provide common functionality such as persistence and caching.
+            Model MBeans are defined by the package
+            <a href="modelmbean/package-summary.html"><code>
+        javax.management.modelmbean</code></a>.</p>
 
 
-      <h3>Creating MBeans in the MBean Server</h3>
+        <h2>MBean Server</h2>
 
-      <p>There are two ways to create an MBean.  One is to construct a
-	Java object that will be the MBean, then use the {@link
-	javax.management.MBeanServer#registerMBean registerMBean}
-	method to register it in the MBean Server.  The other is to
-	create and register the MBean in a single operation using one
-	of the {@link javax.management.MBeanServer#createMBean(String,
-	javax.management.ObjectName) createMBean} methods.</p>
+        <p>To be useful, an MBean must be registered in an <em>MBean
+            Server</em>.  An MBean Server is a repository of MBeans.
+            Usually the only access to the MBeans is through the MBean
+            Server.  In other words, code no longer accesses the Java
+            object implementing the MBean directly, but instead accesses
+            the MBean by name through the MBean Server.  Each MBean has a
+            unique name within the MBean Server, defined by the {@link
+        javax.management.ObjectName ObjectName} class.</p>
 
-      <p>The <code>registerMBean</code> method is simpler for local
-	use, but cannot be used remotely.  The
-	<code>createMBean</code> method can be used remotely, but
-	sometimes requires attention to class loading issues.</p>
+        <p>An MBean Server is an object implementing the interface
+            {@link javax.management.MBeanServer MBeanServer}.
+            The most convenient MBean Server to use is the
+            <em>Platform MBean Server</em>.  This is a
+            single MBean Server that can be shared by different managed
+            components running within the same Java Virtual Machine.  The
+            Platform MBean Server is accessed with the method {@link
+        java.lang.management.ManagementFactory#getPlatformMBeanServer()}.</p>
 
-      <p>An MBean can perform actions when it is registered in or
-	unregistered from an MBean Server if it implements the {@link
-	javax.management.MBeanRegistration MBeanRegistration}
-	interface.</p>
+        <p>Application code can also create a new MBean Server, or
+            access already-created MBean Servers, using the {@link
+        javax.management.MBeanServerFactory MBeanServerFactory} class.</p>
 
 
-      <h3>Accessing MBeans in the MBean Server</h3>
+        <h3>Creating MBeans in the MBean Server</h3>
+
+        <p>There are two ways to create an MBean.  One is to construct a
+            Java object that will be the MBean, then use the {@link
+            javax.management.MBeanServer#registerMBean registerMBean}
+            method to register it in the MBean Server.  The other is to
+            create and register the MBean in a single operation using one
+            of the {@link javax.management.MBeanServer#createMBean(String,
+        javax.management.ObjectName) createMBean} methods.</p>
 
-      <p>Given an <code>ObjectName</code> <code>name</code> and an
-	<code>MBeanServer</code> <code>mbs</code>, you can access
-	attributes and operations as in this example:</p>
+        <p>The <code>registerMBean</code> method is simpler for local
+            use, but cannot be used remotely.  The
+            <code>createMBean</code> method can be used remotely, but
+        sometimes requires attention to class loading issues.</p>
 
-      <pre>
+        <p>An MBean can perform actions when it is registered in or
+            unregistered from an MBean Server if it implements the {@link
+            javax.management.MBeanRegistration MBeanRegistration}
+        interface.</p>
+
+
+        <h3>Accessing MBeans in the MBean Server</h3>
+
+        <p>Given an <code>ObjectName</code> <code>name</code> and an
+            <code>MBeanServer</code> <code>mbs</code>, you can access
+        attributes and operations as in this example:</p>
+
+        <pre>
     int cacheSize = mbs.getAttribute(name, "CacheSize");
     {@link javax.management.Attribute Attribute} newCacheSize =
     	new Attribute("CacheSize", new Integer(2000));
@@ -236,9 +277,9 @@
     mbs.invoke(name, "save", new Object[0], new Class[0]);
       </pre>
 
-      <p>Alternatively, if you have a Java interface that corresponds
-	to the management interface for the MBean, you can use an
-	<em>MBean proxy</em> like this:</p>
+        <p id="proxy">Alternatively, if you have a Java interface that
+            corresponds to the management interface for the MBean, you can use an
+        <em>MBean proxy</em> like this:</p>
 
       <pre>
     ConfigurationMBean conf =
@@ -264,66 +305,116 @@
 	perform the query.</p>
 
 
-      <h2>Notifications</h2>
-
-      <p>A <em>notification</em> is an instance of the {@link
-	javax.management.Notification Notification} class or a
-	subclass.  In addition to its Java class, it has a
-	<em>type</em> string that can distinguish it from other
-	notifications of the same class.</p>
-
-      <p>An MBean that will emit notifications must implement the
-	{@link javax.management.NotificationBroadcaster
-	NotificationBroadcaster} or {@link
-	javax.management.NotificationEmitter NotificationEmitter}
-	interface.  Usually, it does this by subclassing {@link
-	javax.management.NotificationBroadcasterSupport
-	NotificationBroadcasterSupport} or by delegating to an instance
-	of that class.</p>
+        <h3>MBean lifecycle and resource injection</h3>
 
-      <p>Notifications can be received by a <em>listener</em>, which
-	is an object that implements the {@link
-	javax.management.NotificationListener NotificationListener}
-	interface.  You can add a listener to an MBean with the method
-	{@link
-	javax.management.MBeanServer#addNotificationListener(ObjectName,
-	NotificationListener, NotificationFilter, Object)}.
-	You can optionally supply a <em>filter</em> to this method, to
-	select only notifications of interest.  A filter is an object
-	that implements the {@link javax.management.NotificationFilter
-	NotificationFilter} interface.</p>
+        <p>An MBean can implement the {@link javax.management.MBeanRegistration
+            MBeanRegistration} interface in order to be told when it is registered
+            and unregistered in the MBean Server. Additionally, the {@link
+            javax.management.MBeanRegistration#preRegister preRegister} method
+            allows the MBean to get a reference to the <code>MBeanServer</code>
+            object and to get its <code>ObjectName</code> within the MBean
+        Server.</p>
 
-      <p>An MBean can be a listener for notifications emitted by other
-	MBeans in the same MBean Server.  In this case, it implements
-	{@link javax.management.NotificationListener
-	NotificationListener} and the method {@link
-	javax.management.MBeanServer#addNotificationListener(ObjectName,
-	ObjectName, NotificationFilter, Object)} is used to listen.</p>
+        <p>If the only reason to implement <code>MBeanRegistration</code> is to
+            discover the <code>MBeanServer</code> and <code>ObjectName</code>, <a
+                href="MBeanRegistration.html#injection">resource injection</a> may be
+        more convenient.</p>
 
 
-      <h2>Remote Access to MBeans</h2>
+        <h2>Notifications</h2>
+
+        <p>A <em>notification</em> is an instance of the {@link
+            javax.management.Notification Notification} class or a
+            subclass.  In addition to its Java class, it has a
+            <em>type</em> string that can distinguish it from other
+        notifications of the same class.</p>
+
+        <p>If an MBean is to emit notifications, it must do one of two things.</p>
 
-      <p>An MBean Server can be accessed remotely through a
-	<em>connector</em>.  A connector allows a remote Java
-	application to access an MBean Server in essentially the same
-	way as a local one.  The package
-	<a href="remote/package-summary.html"><code>
-	    javax.management.remote</code></a> defines connectors.</p>
+        <ul>
+            <li>It can implement the interface {@link
+                javax.management.NotificationEmitter NotificationEmitter} (or
+                its parent {@link javax.management.NotificationBroadcaster
+                NotificationBroadcaster}), usually by subclassing
+                {@link javax.management.NotificationBroadcasterSupport
+                NotificationBroadcasterSupport} or delegating to an instance of
+            that class.</li>
+            <li>It can use <a href="MBeanRegistration.html#injection">resource
+                injection</a> to obtain a {@link javax.management.SendNotification
+                SendNotification} object that it can use to send
+            notifications.</li>
+        </ul>
+
+        <p>The two classes below illustrate these two techniques:</p>
+
+        <pre>
+    // Implementing NotificationEmitter (via NotificationBroadcasterSupport)
+    public class Configuration <b>extends NotificationBroadcasterSupport</b>
+            implements ConfigurationMBean {
+        ...
+        private void updated() {
+            Notification n = new Notification(...);
+            <b>{@link javax.management.NotificationBroadcasterSupport#sendNotification
+            sendNotification}(n)</b>;
+        }
+    }
 
-      <p>The JMX specification also defines the notion of an
-	<em>adaptor</em>.  An adaptor translates between requests in a
-	protocol such as SNMP or HTML and accesses to an MBean Server.
-	So for example an SNMP GET operation might result in a
-	<code>getAttribute</code> on the MBean Server.</p>
+    // Getting a SendNotification through resource injection
+    public class Configuration implements ConfigurationMBean {
+        <b>&#64;Resource</b>
+        private volatile SendNotification sender;
+        ...
+        private void updated() {
+            Notification n = new Notification(...);
+            <b>sender.sendNotification(n)</b>;
+        }
+    }
+        </pre>
+
+
+        <p>Notifications can be received by a <em>listener</em>, which
+            is an object that implements the {@link
+            javax.management.NotificationListener NotificationListener}
+            interface.  You can add a listener to an MBean with the method
+            {@link
+            javax.management.MBeanServer#addNotificationListener(ObjectName,
+            NotificationListener, NotificationFilter, Object)}.
+            You can optionally supply a <em>filter</em> to this method, to
+            select only notifications of interest.  A filter is an object
+            that implements the {@link javax.management.NotificationFilter
+        NotificationFilter} interface.</p>
 
-      <p id="spec">
-    @see <a href="{@docRoot}/../technotes/guides/jmx/index.html">
-      Java SE 6 Platform documentation on JMX technology</a>
-      in particular the 
-      <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
-      JMX Specification, version 1.4(pdf).</a> 
+        <p>An MBean can be a listener for notifications emitted by other
+            MBeans in the same MBean Server.  In this case, it implements
+            {@link javax.management.NotificationListener
+            NotificationListener} and the method {@link
+            javax.management.MBeanServer#addNotificationListener(ObjectName,
+        ObjectName, NotificationFilter, Object)} is used to listen.</p>
+
+
+        <h2>Remote Access to MBeans</h2>
 
-	@since 1.5
+        <p>An MBean Server can be accessed remotely through a
+            <em>connector</em>.  A connector allows a remote Java
+            application to access an MBean Server in essentially the same
+            way as a local one.  The package
+            <a href="remote/package-summary.html"><code>
+        javax.management.remote</code></a> defines connectors.</p>
+
+        <p>The JMX specification also defines the notion of an
+            <em>adaptor</em>.  An adaptor translates between requests in a
+            protocol such as SNMP or HTML and accesses to an MBean Server.
+            So for example an SNMP GET operation might result in a
+        <code>getAttribute</code> on the MBean Server.</p>
+
+        <p id="spec">
+        @see <a href="{@docRoot}/../technotes/guides/jmx/index.html">
+        Java SE 6 Platform documentation on JMX technology</a>
+        in particular the
+        <a href="{@docRoot}/../technotes/guides/jmx/JMX_1_4_specification.pdf">
+        JMX Specification, version 1.4(pdf).</a>
+
+        @since 1.5
 
     </body>
 </html>
--- a/jdk/src/share/classes/sun/nio/ch/SelectorImpl.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/src/share/classes/sun/nio/ch/SelectorImpl.java	Wed Jul 05 16:39:18 2017 +0200
@@ -142,18 +142,20 @@
         // Precondition: Synchronized on this, keys, and selectedKeys
         Set cks = cancelledKeys();
         synchronized (cks) {
-            Iterator i = cks.iterator();
-            while (i.hasNext()) {
-                SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
-                try {
-                    implDereg(ski);
-                } catch (SocketException se) {
-                    IOException ioe = new IOException(
-                        "Error deregistering key");
-                    ioe.initCause(se);
-                    throw ioe;
-                } finally {
-                    i.remove();
+            if (!cks.isEmpty()) {
+                Iterator i = cks.iterator();
+                while (i.hasNext()) {
+                    SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
+                    try {
+                        implDereg(ski);
+                    } catch (SocketException se) {
+                        IOException ioe = new IOException(
+                            "Error deregistering key");
+                        ioe.initCause(se);
+                        throw ioe;
+                    } finally {
+                        i.remove();
+                    }
                 }
             }
         }
--- a/jdk/test/com/sun/jdi/MonitorFrameInfo.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/test/com/sun/jdi/MonitorFrameInfo.java	Wed Jul 05 16:39:18 2017 +0200
@@ -25,7 +25,8 @@
  *  @test
  *  @bug 6230699
  *  @summary Test ThreadReference.ownedMonitorsAndFrames()
- *
+ *  @bug 6701700
+ *  @summary MonitorInfo objects aren't invalidated when the owning thread is resumed
  *  @author Swamy Venkataramanappa
  *
  *  @run build TestScaffold VMConnection TargetListener TargetAdapter
@@ -100,15 +101,15 @@
 
         if (!mainThread.frame(0).location().method().name()
                         .equals("foo3")) {
-            failure("frame failed");
+            failure("FAILED: frame failed");
         }
 
         if (mainThread.frames().size() != (initialSize + 3)) {
-            failure("frames size failed");
+            failure("FAILED: frames size failed");
         }
 
         if (mainThread.frames().size() != mainThread.frameCount()) {
-            failure("frames size not equal to frameCount");
+            failure("FAILED: frames size not equal to frameCount");
         }
 
         /* Test monitor frame info.
@@ -119,13 +120,32 @@
             if (monitors.size() != expectedCount) {
                 failure("monitors count is not equal to expected count");
             }
+            MonitorInfo mon = null;
             for (int j=0; j < monitors.size(); j++) {
-                MonitorInfo mon  = (MonitorInfo)monitors.get(j);
+                mon  = (MonitorInfo)monitors.get(j);
                 System.out.println("Monitor obj " + mon.monitor() + "depth =" +mon.stackDepth());
                 if (mon.stackDepth() != expectedDepth[j]) {
-                    failure("monitor stack depth is not equal to expected depth");
+                    failure("FAILED: monitor stack depth is not equal to expected depth");
                 }
             }
+
+            // The last gotten monInfo is in mon.   When we resume the thread,
+            // it should become invalid.  We will step out of the top frame
+            // so that the frame depth in this mon object will no longer be correct.
+            // That is why the monInfo's have to become invalid when the thread is
+            // resumed.
+            stepOut(mainThread);
+            boolean ok = false;
+            try {
+                System.out.println("*** Saved Monitor obj " + mon.monitor() + "depth =" +mon.stackDepth());
+            } catch(InvalidStackFrameException ee) {
+                // ok
+                ok = true;
+                System.out.println("Got expected InvalidStackFrameException after a resume");
+            }
+            if (!ok) {
+                failure("FAILED: MonitorInfo object was not invalidated by a resume");
+            }
         } else {
             System.out.println("can not get monitors frame info");
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/jdi/ResumeOneThreadTest.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ *  @test
+ *  @bug 6700889
+ *  @summary  Thread resume invalidates all stack frames, even from other threads
+ *
+ *  @author jjh
+ *
+ *  @run build TestScaffold VMConnection TargetListener TargetAdapter
+ *  @run compile -g ResumeOneThreadTest.java
+ *  @run main ResumeOneThreadTest
+ */
+import com.sun.jdi.*;
+import com.sun.jdi.event.*;
+import com.sun.jdi.request.*;
+
+import java.util.*;
+
+class ResumeOneThreadTarg extends Thread {
+    static String name1 = "Thread 1";
+    static String name2 = "Thread 2";
+
+    public ResumeOneThreadTarg(String name) {
+        super(name);
+    }
+
+    public static void main(String[] args) {
+        System.out.println("    Debuggee: Howdy!");
+        ResumeOneThreadTarg t1 = new ResumeOneThreadTarg(name1);
+        ResumeOneThreadTarg t2 = new ResumeOneThreadTarg(name2);
+
+        t1.start();
+        t2.start();
+    }
+
+    // This just starts two threads. Each runs to a bkpt.
+    public void run() {
+        if (getName().equals(name1)) {
+            run1();
+        } else {
+            run2();
+        }
+    }
+
+    public void bkpt1(String p1) {
+        System.out.println("    Debuggee: bkpt 1");
+    }
+
+    public void run1() {
+        bkpt1("Hello Alviso!");
+    }
+
+
+
+    public void bkpt2() {
+        System.out.println("    Debuggee: bkpt 2");
+    }
+
+    public void run2() {
+        bkpt2();
+    }
+}
+
+/********** test program **********/
+
+public class ResumeOneThreadTest extends TestScaffold {
+    ReferenceType targetClass;
+    ThreadReference mainThread;
+
+    BreakpointRequest request1;
+    BreakpointRequest request2;
+
+    ThreadReference thread1 = null;
+    ThreadReference thread2 = null;;
+    boolean theVMisDead = false;
+
+    ResumeOneThreadTest (String args[]) {
+        super(args);
+    }
+
+    public static void main(String[] args)      throws Exception {
+        new ResumeOneThreadTest(args).startTests();
+    }
+
+
+    synchronized public void breakpointReached(BreakpointEvent event) {
+        println("-- Got bkpt at: " + event.location());
+        ThreadReference eventThread = event.thread();
+
+        if (eventThread.name().equals(ResumeOneThreadTarg.name1)) {
+            thread1 = eventThread;
+        }
+
+        if (eventThread.name().equals(ResumeOneThreadTarg.name2)) {
+            thread2 = eventThread;
+        }
+    }
+
+    public void vmDied(VMDeathEvent event) {
+        theVMisDead = true;
+    }
+
+    synchronized public void eventSetComplete(EventSet set) {
+        if (theVMisDead) {
+            return;
+        }
+        if (thread1 == null || thread2 == null) {
+            // Don't do a set.resume(), just let the other thread
+            // keep running until it hits its bkpt.
+            return;
+        }
+
+        // Both threads are stopped at their bkpts.  Get a StackFrame from
+        // Thread 1 then resume Thread 2 and verify that the saved StackFrame is
+        // still valid.
+
+        // suspend everything.
+        println("-- All threads suspended");
+        vm().suspend();
+
+        StackFrame t1sf0 = null;
+        try {
+            t1sf0 = thread1.frame(0);
+        } catch (IncompatibleThreadStateException ee) {
+            failure("FAILED: Exception: " + ee);
+        }
+
+        println("-- t1sf0 args: " + t1sf0.getArgumentValues());
+
+        // Ok, we have a StackFrame for thread 1.  Resume just thread 2
+        // Note that thread 2 has been suspended twice - by the SUSPEND_ALL
+        // bkpt, and by the above vm().suspend(), so we have to resume
+        // it twice.
+        request2.disable();
+
+        thread2.resume();
+        thread2.resume();
+        println("-- Did Resume on thread 2");
+
+        // Can we get frames for thread1?
+        try {
+            StackFrame t1sf0_1 = thread1.frame(0);
+            if (!t1sf0.equals(t1sf0_1)) {
+                failure("FAILED: Got a different frame 0 for thread 1 after resuming thread 2");
+            }
+        } catch (IncompatibleThreadStateException ee) {
+            failure("FAILED: Could not get frames for thread 1: Exception: " + ee);
+        } catch (Exception ee) {
+            failure("FAILED: Could not get frames for thread 1: Exception: " + ee);
+        }
+
+
+        try {
+            println("-- t1sf0 args: " + t1sf0.getArgumentValues());
+        } catch (InvalidStackFrameException ee) {
+            // This is the failure.
+            failure("FAILED Got InvalidStackFrameException");
+            vm().dispose();
+            throw(ee);
+        }
+
+        // Let the debuggee finish
+        request1.disable();
+        thread1.resume();
+        vm().resume();
+        println("--------------");
+    }
+
+    /********** test core **********/
+
+    protected void runTests() throws Exception {
+
+        /*
+         * Get to the top of main()
+         * to determine targetClass and mainThread
+         */
+        BreakpointEvent bpe = startToMain("ResumeOneThreadTarg");
+        targetClass = bpe.location().declaringType();
+        mainThread = bpe.thread();
+        EventRequestManager erm = vm().eventRequestManager();
+        final Thread mainThread = Thread.currentThread();
+
+        /*
+         * Set event requests
+         */
+
+        Location loc1 = findMethod(targetClass, "bkpt1", "(Ljava/lang/String;)V").location();
+        request1 = erm.createBreakpointRequest(loc1);
+        request1.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
+        request1.enable();
+
+        Location loc2 = findMethod(targetClass, "bkpt2", "()V").location();
+        request2 = erm.createBreakpointRequest(loc2);
+        request2.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
+        request2.enable();
+
+        /*
+         * resume the target, listening for events
+         */
+        listenUntilVMDisconnect();
+        /*
+         * deal with results of test
+         * if anything has called failure("foo") testFailed will be true
+         */
+        if (!testFailed) {
+            println("ResumeOneThreadTest: passed");
+        } else {
+            throw new Exception("ResumeOneThreadTest: failed");
+        }
+    }
+}
--- a/jdk/test/com/sun/jdi/SourceNameFilterTest.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/test/com/sun/jdi/SourceNameFilterTest.java	Wed Jul 05 16:39:18 2017 +0200
@@ -23,7 +23,7 @@
 
 /**
  *  @test
- *  @bug 4836939
+ *  @bug 4836939 6646613
  *  @summary JDI add addSourceNameFilter to ClassPrepareRequest
  *
  *  @author jjh
@@ -31,7 +31,11 @@
  *  @run build TestScaffold VMConnection TargetListener TargetAdapter
  *  @run compile -g SourceNameFilterTest.java
  *  @run main SourceNameFilterTest
+ *  @run compile -g:none SourceNameFilterTest.java
+ *  @run main SourceNameFilterTest
  */
+// The compile -g:none suppresses the lineNumber table to trigger bug 6646613.
+
 import com.sun.jdi.*;
 import com.sun.jdi.event.*;
 import com.sun.jdi.request.*;
@@ -84,7 +88,6 @@
     boolean gotEvent1 = false;
     boolean gotEvent2 = false;
     boolean gotEvent3 = false;
-
     ClassPrepareRequest cpReq;
     boolean shouldResume = false;
     SourceNameFilterTest (String args[]) {
@@ -151,6 +154,18 @@
          */
         BreakpointEvent bpe = startToMain("SourceNameFilterTarg");
         targetClass = bpe.location().declaringType();
+        boolean noSourceName = false;
+        try {
+            targetClass.sourceName();
+        } catch (AbsentInformationException ee) {
+            noSourceName = true;
+        }
+        if (noSourceName) {
+            println("-- Running with no source names");
+        } else {
+            println("-- Running with source names");
+        }
+
         mainThread = bpe.thread();
         EventRequestManager erm = vm().eventRequestManager();
         addListener(this);
@@ -175,7 +190,9 @@
 
         /*
          * This should cause us to get a class prepare event for
-         * LoadedLater3
+         * LoadedLater3 except in the case where -g:none
+         * was used to compile so that there is no LineNumberTable
+         * and therefore, no source name for the class.
          */
         cpReq = erm.createClassPrepareRequest();
         cpReq.addSourceNameFilter("SourceNameFilterTest.java");
@@ -186,17 +203,21 @@
 
         if (!gotEvent1) {
             failure("failure: Did not get a class prepare request " +
-                    "for Loadedlater1");
+                    "for LoadedLater1");
         }
 
         if (gotEvent2) {
             failure("failure: Did get a class prepare request " +
-                    "for Loadedlater2");
+                    "for LoadedLater2");
         }
 
-        if (!gotEvent3) {
+        if (gotEvent3 && noSourceName) {
+            failure("failure: Did get a class prepare request " +
+                    "for LoadedLater3");
+        }
+        else if (!gotEvent3 && !noSourceName) {
             failure("failure: Did not get a class prepare request " +
-                    "for Loadedlater3");
+                    "for LoadedLater3");
         }
 
         /*
--- a/jdk/test/com/sun/jdi/VMConnection.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/test/com/sun/jdi/VMConnection.java	Wed Jul 05 16:39:18 2017 +0200
@@ -115,7 +115,7 @@
             return cmdLine;
         }
         // Insert the options at position 1.  Blanks in args are not allowed!
-        String[] v1 = opts.split(" ");
+        String[] v1 = opts.split(" +");
         String[] retVal = new String[cmdLine.length + v1.length];
         retVal[0] = cmdLine[0];
         System.arraycopy(v1, 0, retVal, 1, v1.length);
--- a/jdk/test/java/nio/channels/FileChannel/ExpandingMap.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/test/java/nio/channels/FileChannel/ExpandingMap.java	Wed Jul 05 16:39:18 2017 +0200
@@ -22,7 +22,7 @@
  */
 
 /* @test
- * @bug 4938372
+ * @bug 4938372 6541641
  * @summary Flushing dirty pages prior to unmap can cause Cleaner thread to
  *          abort VM if memory system has pages locked
  */
@@ -39,7 +39,7 @@
 
 public class ExpandingMap {
 
-    public static void main(String[] args) throws IOException {
+    public static void main(String[] args) throws Exception {
 
         int initialSize = 20480*1024;
         int maximumMapSize = 16*1024*1024;
@@ -103,6 +103,13 @@
             }
         }
 
+        fc.close();
+        // cleanup the ref to mapped buffers so they can be GCed
+        for (int i = 0; i < buffers.length; i++)
+            buffers[i] = null;
+        System.gc();
+        // Take a nap to wait for the Cleaner to cleanup those unrefed maps
+        Thread.sleep(1000);
         System.out.println("TEST PASSED");
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/channels/Selector/Wakeup.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2001-2003 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 6405995
+ * @summary Unit test for selector wakeup and interruption
+ * @library ..
+ */
+
+import java.io.*;
+import java.net.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.util.Random;
+
+public class Wakeup {
+
+    static void sleep(int millis) {
+        try {
+            Thread.sleep(millis);
+        } catch (InterruptedException x) {
+            x.printStackTrace();
+        }
+    }
+
+    static class Sleeper extends TestThread {
+        volatile boolean started = false;
+        volatile int entries = 0;
+        volatile int wakeups = 0;
+        volatile boolean wantInterrupt = false;
+        volatile boolean gotInterrupt = false;
+        volatile Exception exception = null;
+        volatile boolean closed = false;
+        Object gate = new Object();
+
+        Selector sel;
+
+        Sleeper(Selector sel) {
+            super("Sleeper", System.err);
+            this.sel = sel;
+        }
+
+        public void go() throws Exception {
+            started = true;
+            for (;;) {
+                synchronized (gate) { }
+                entries++;
+                try {
+                    sel.select();
+                } catch (ClosedSelectorException x) {
+                    closed = true;
+                }
+                boolean intr = Thread.currentThread().isInterrupted();
+                wakeups++;
+                System.err.println("Wakeup " + wakeups
+                                   + (closed ? " (closed)" : "")
+                                   + (intr ? " (intr)" : ""));
+                if (wakeups > 1000)
+                    throw new Exception("Too many wakeups");
+                if (closed)
+                    return;
+                if (wantInterrupt) {
+                    while (!Thread.interrupted())
+                        Thread.yield();
+                    gotInterrupt = true;
+                    wantInterrupt = false;
+                }
+            }
+        }
+
+    }
+
+    private static int checkedWakeups = 0;
+
+    private static void check(Sleeper sleeper, boolean intr)
+        throws Exception
+    {
+        checkedWakeups++;
+        if (sleeper.wakeups > checkedWakeups) {
+            sleeper.finish(100);
+            throw new Exception("Sleeper has run ahead");
+        }
+        int n = 0;
+        while (sleeper.wakeups < checkedWakeups) {
+            sleep(50);
+            if ((n += 50) > 1000) {
+                sleeper.finish(100);
+                throw new Exception("Sleeper appears to be dead ("
+                                    + checkedWakeups + ")");
+            }
+        }
+        if (sleeper.wakeups > checkedWakeups) {
+            sleeper.finish(100);
+            throw new Exception("Too many wakeups: Expected "
+                                + checkedWakeups
+                                + ", got " + sleeper.wakeups);
+        }
+        if (intr) {
+            n = 0;
+            // Interrupts can sometimes be delayed, so wait
+            while (!sleeper.gotInterrupt) {
+                sleep(50);
+                if ((n += 50) > 1000) {
+                    sleeper.finish(100);
+                    throw new Exception("Interrupt never delivered");
+                }
+            }
+            sleeper.gotInterrupt = false;
+        }
+        System.err.println("Check " + checkedWakeups
+                           + (intr ? " (intr " + n + ")" : ""));
+    }
+
+    public static void main(String[] args) throws Exception {
+
+        Selector sel = Selector.open();
+
+        // Wakeup before select
+        sel.wakeup();
+
+        Sleeper sleeper = new Sleeper(sel);
+
+        sleeper.start();
+        while (!sleeper.started)
+            sleep(50);
+
+        check(sleeper, false);          // 1
+
+        for (int i = 2; i < 5; i++) {
+            // Wakeup during select
+            sel.wakeup();
+            check(sleeper, false);      // 2 .. 4
+        }
+
+        // Double wakeup
+        synchronized (sleeper.gate) {
+            sel.wakeup();
+            check(sleeper, false);      // 5
+            sel.wakeup();
+            sel.wakeup();
+        }
+        check(sleeper, false);          // 6
+
+        // Interrupt
+        synchronized (sleeper.gate) {
+            sleeper.wantInterrupt = true;
+            sleeper.interrupt();
+            check(sleeper, true);       // 7
+        }
+
+        // Interrupt before select
+        while (sleeper.entries < 8)
+            Thread.yield();
+        synchronized (sleeper.gate) {
+            sel.wakeup();
+            check(sleeper, false);      // 8
+            sleeper.wantInterrupt = true;
+            sleeper.interrupt();
+            sleep(50);
+        }
+        check(sleeper, true);           // 9
+
+        // Close during select
+        while (sleeper.entries < 10)
+            Thread.yield();
+        synchronized (sleeper.gate) {
+            sel.close();
+            check(sleeper, false);      // 10
+        }
+
+        if (sleeper.finish(200) == 0)
+            throw new Exception("Test failed");
+        if (!sleeper.closed)
+            throw new Exception("Selector not closed");
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/Introspector/AnnotatedMBeanTest.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,337 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test %M% %I%
+ * @bug 6323980
+ * @summary Test MBeans defined with &#64;MBean
+ * @author Eamonn McManus
+ * @run main/othervm -ea AnnotatedMBeanTest
+ */
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import javax.management.Attribute;
+import javax.management.Descriptor;
+import javax.management.DescriptorKey;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MXBean;
+import javax.management.MalformedObjectNameException;
+import javax.management.ManagedAttribute;
+import javax.management.ManagedOperation;
+import javax.management.MBean;
+import javax.management.ObjectName;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeType;
+
+public class AnnotatedMBeanTest {
+    private static MBeanServer mbs;
+    private static final ObjectName objectName;
+    static {
+        try {
+            objectName = new ObjectName("test:type=Test");
+        } catch (MalformedObjectNameException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (!AnnotatedMBeanTest.class.desiredAssertionStatus())
+            throw new Exception("Test must be run with -ea");
+
+        File policyFile = File.createTempFile("jmxperms", ".policy");
+        policyFile.deleteOnExit();
+        PrintWriter pw = new PrintWriter(policyFile);
+        pw.println("grant {");
+        pw.println("    permission javax.management.MBeanPermission \"*\", \"*\";");
+        pw.println("    permission javax.management.MBeanServerPermission \"*\";");
+        pw.println("    permission javax.management.MBeanTrustPermission \"*\";");
+        pw.println("};");
+        pw.close();
+
+        System.setProperty("java.security.policy", policyFile.getAbsolutePath());
+        System.setSecurityManager(new SecurityManager());
+
+        String failure = null;
+
+        for (Method m : AnnotatedMBeanTest.class.getDeclaredMethods()) {
+            if (Modifier.isStatic(m.getModifiers()) &&
+                    m.getName().startsWith("test") &&
+                    m.getParameterTypes().length == 0) {
+                mbs = MBeanServerFactory.newMBeanServer();
+                try {
+                    m.invoke(null);
+                    System.out.println(m.getName() + " OK");
+                } catch (InvocationTargetException ite) {
+                    System.out.println(m.getName() + " got exception:");
+                    Throwable t = ite.getCause();
+                    t.printStackTrace(System.out);
+                    failure = m.getName() + ": " + t.toString();
+                }
+            }
+        }
+        if (failure == null)
+            System.out.println("TEST PASSED");
+        else
+            throw new Exception("TEST FAILED: " + failure);
+    }
+
+    public static class Stats {
+        private final int used;
+        private final int size;
+        private final boolean interesting;
+
+        public Stats(int used, int size, boolean interesting) {
+            this.used = used;
+            this.size = size;
+            this.interesting = interesting;
+        }
+
+        public int getUsed() {
+            return used;
+        }
+
+        public int getSize() {
+            return size;
+        }
+
+        public boolean isInteresting() {
+            return interesting;
+        }
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    public static @interface Units {
+        @DescriptorKey("units")
+        String value();
+    }
+
+    @MBean
+    public static class Cache {
+        private int used = 23;
+        private int size = 99;
+
+        @ManagedAttribute
+        @Units("bytes")
+        public int getUsed() {
+            return used;
+        }
+
+        @ManagedAttribute
+        public int getSize() {
+            return size;
+        }
+
+        @ManagedAttribute
+        public void setSize(int x) {
+            this.size = x;
+        }
+
+        @ManagedAttribute
+        public boolean isInteresting() {
+            return false;
+        }
+
+        @ManagedAttribute
+        public Stats getStats() {
+            return new Stats(used, size, false);
+        }
+
+        @ManagedOperation
+        public int dropOldest(int n) {
+            return 55;
+        }
+
+        private void irrelevantMethod() {}
+        private int getIrrelevant() {return 0;}
+        public int getIrrelevant2() {return 0;}
+
+        public int otherIrrelevantMethod() {return 5;}
+    }
+
+    public static class SubCache extends Cache {
+        // SubCache does not have the @MBean annotation
+        // but its parent does.  It doesn't add any @ManagedAttribute or
+        // @ManagedOperation methods, so its management interface
+        // should be the same.
+        private void irrelevantMethod2() {}
+        public int otherIrrelevantMethod3() {return 0;}
+
+        public int getX() {return 0;}
+        public void setX(int x) {}
+    }
+
+    @MXBean
+    public static class CacheMX {
+        private int used = 23;
+        private int size = 99;
+
+        @ManagedAttribute
+        @Units("bytes")
+        public int getUsed() {
+            return used;
+        }
+
+        @ManagedAttribute
+        public int getSize() {
+            return size;
+        }
+
+        @ManagedAttribute
+        public void setSize(int x) {
+            this.size = x;
+        }
+
+        @ManagedAttribute
+        public boolean isInteresting() {
+            return false;
+        }
+
+        @ManagedAttribute
+        public Stats getStats() {
+            return new Stats(used, size, false);
+        }
+
+        @ManagedOperation
+        public int dropOldest(int n) {
+            return 55;
+        }
+
+        private void irrelevantMethod() {}
+        private int getIrrelevant() {return 0;}
+        public int getIrrelevant2() {return 0;}
+
+        public int otherIrrelevantMethod() {return 5;}
+    }
+
+    public static class SubCacheMX extends CacheMX {
+        private void irrelevantMethod2() {}
+        public int otherIrrelevantMethod3() {return 0;}
+
+        public int getX() {return 0;}
+        public void setX(int x) {}
+    }
+
+    private static void testSimpleManagedResource() throws Exception {
+        testResource(new Cache(), false);
+    }
+
+    private static void testSubclassManagedResource() throws Exception {
+        testResource(new SubCache(), false);
+    }
+
+    private static void testMXBeanResource() throws Exception {
+        testResource(new CacheMX(), true);
+    }
+
+    private static void testSubclassMXBeanResource() throws Exception {
+        testResource(new SubCacheMX(), true);
+    }
+
+    private static void testResource(Object resource, boolean mx) throws Exception {
+        mbs.registerMBean(resource, objectName);
+
+        MBeanInfo mbi = mbs.getMBeanInfo(objectName);
+        assert mbi.getDescriptor().getFieldValue("mxbean").equals(Boolean.toString(mx));
+
+        MBeanAttributeInfo[] mbais = mbi.getAttributes();
+
+        assert mbais.length == 4: mbais.length;
+
+        for (MBeanAttributeInfo mbai : mbais) {
+            String name = mbai.getName();
+            if (name.equals("Used")) {
+                assert mbai.isReadable();
+                assert !mbai.isWritable();
+                assert !mbai.isIs();
+                assert mbai.getType().equals("int");
+                assert "bytes".equals(mbai.getDescriptor().getFieldValue("units"));
+            } else if (name.equals("Size")) {
+                assert mbai.isReadable();
+                assert mbai.isWritable();
+                assert !mbai.isIs();
+                assert mbai.getType().equals("int");
+            } else if (name.equals("Interesting")) {
+                assert mbai.isReadable();
+                assert !mbai.isWritable();
+                assert mbai.isIs();
+                assert mbai.getType().equals("boolean");
+            } else if (name.equals("Stats")) {
+                assert mbai.isReadable();
+                assert !mbai.isWritable();
+                assert !mbai.isIs();
+                Descriptor d = mbai.getDescriptor();
+                if (mx) {
+                    assert mbai.getType().equals(CompositeData.class.getName());
+                    assert d.getFieldValue("originalType").equals(Stats.class.getName());
+                    CompositeType ct = (CompositeType) d.getFieldValue("openType");
+                    Set<String> names = new HashSet<String>(
+                            Arrays.asList("used", "size", "interesting"));
+                    assert ct.keySet().equals(names) : ct.keySet();
+                } else {
+                    assert mbai.getType().equals(Stats.class.getName());
+                }
+            } else
+                assert false : name;
+        }
+
+        MBeanOperationInfo[] mbois = mbi.getOperations();
+
+        assert mbois.length == 1: mbois.length;
+
+        MBeanOperationInfo mboi = mbois[0];
+        assert mboi.getName().equals("dropOldest");
+        assert mboi.getReturnType().equals("int");
+        MBeanParameterInfo[] mbpis = mboi.getSignature();
+        assert mbpis.length == 1: mbpis.length;
+        assert mbpis[0].getType().equals("int");
+
+        assert mbs.getAttribute(objectName, "Used").equals(23);
+
+        assert mbs.getAttribute(objectName, "Size").equals(99);
+        mbs.setAttribute(objectName, new Attribute("Size", 55));
+        assert mbs.getAttribute(objectName, "Size").equals(55);
+
+        assert mbs.getAttribute(objectName, "Interesting").equals(false);
+
+        Object stats = mbs.getAttribute(objectName, "Stats");
+        assert (mx ? CompositeData.class : Stats.class).isInstance(stats) : stats.getClass();
+
+        int ret = (Integer) mbs.invoke(
+                objectName, "dropOldest", new Object[] {66}, new String[] {"int"});
+        assert ret == 55;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/Introspector/AnnotatedNotificationInfoTest.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test %M% %I%
+ * @bug 6323980
+ * @summary Test &#64;NotificationInfo annotation
+ * @author Eamonn McManus
+ * @run main/othervm -ea AnnotatedNotificationInfoTest
+ */
+
+import java.io.Serializable;
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.Field;
+import javax.annotation.Resource;
+import javax.management.AttributeChangeNotification;
+import javax.management.Description;
+import javax.management.Descriptor;
+import javax.management.ImmutableDescriptor;
+import javax.management.MBean;
+import javax.management.MBeanInfo;
+import javax.management.MBeanNotificationInfo;
+import javax.management.MBeanServer;
+import javax.management.MXBean;
+import javax.management.NotificationBroadcasterSupport;
+import javax.management.NotificationInfo;
+import javax.management.NotificationInfos;
+import javax.management.ObjectName;
+import javax.management.SendNotification;
+
+public class AnnotatedNotificationInfoTest {
+    // Data for the first test.  This tests that MBeanNotificationInfo
+    // is correctly derived from @NotificationInfo.
+    // Every static field called mbean* is expected to be an MBean
+    // with a single MBeanNotificationInfo that has the same value
+    // in each case.
+
+    @NotificationInfo(
+            types = {"foo", "bar"},
+            notificationClass = AttributeChangeNotification.class,
+            description = @Description(
+                value = "description",
+                bundleBaseName = "bundle",
+                key = "key"),
+            descriptorFields = {"foo=bar"})
+    public static interface Intf1MBean {}
+
+    public static class Intf1
+            extends NotificationBroadcasterSupport implements Intf1MBean {}
+
+    private static Object mbeanIntf1 = new Intf1();
+
+    @NotificationInfos(
+        @NotificationInfo(
+                types = {"foo", "bar"},
+                notificationClass = AttributeChangeNotification.class,
+                description = @Description(
+                    value = "description",
+                    bundleBaseName = "bundle",
+                    key = "key"),
+                descriptorFields = {"foo=bar"}))
+    public static interface Intf2MBean {}
+
+    public static class Intf2
+            extends NotificationBroadcasterSupport implements Intf2MBean {}
+
+    private static Object mbeanIntf2 = new Intf2();
+
+    @NotificationInfos({})
+    @NotificationInfo(
+            types = {"foo", "bar"},
+            notificationClass = AttributeChangeNotification.class,
+            description = @Description(
+                value = "description",
+                bundleBaseName = "bundle",
+                key = "key"),
+            descriptorFields = {"foo=bar"})
+    public static interface Intf3MBean {}
+
+    public static class Intf3
+            extends NotificationBroadcasterSupport implements Intf3MBean {}
+
+    private static Object mbeanIntf3 = new Intf3();
+
+    @NotificationInfo(
+            types = {"foo", "bar"},
+            notificationClass = AttributeChangeNotification.class,
+            description = @Description(
+                value = "description",
+                bundleBaseName = "bundle",
+                key = "key"),
+            descriptorFields = {"foo=bar"})
+    public static interface ParentIntf {}
+
+    public static interface Intf4MBean extends Serializable, ParentIntf, Cloneable {}
+
+    public static class Intf4
+            extends NotificationBroadcasterSupport implements Intf4MBean {}
+
+    private static Object mbeanIntf4 = new Intf4();
+
+    @NotificationInfo(
+            types = {"foo", "bar"},
+            notificationClass = AttributeChangeNotification.class,
+            description = @Description(
+                value = "description",
+                bundleBaseName = "bundle",
+                key = "key"),
+            descriptorFields = {"foo=bar"})
+    public static interface Intf5MXBean {}
+
+    public static class Intf5Impl
+            extends NotificationBroadcasterSupport implements Intf5MXBean {}
+
+    private static Object mbeanIntf5 = new Intf5Impl();
+
+    public static interface Impl1MBean {}
+
+    @NotificationInfo(
+            types = {"foo", "bar"},
+            notificationClass = AttributeChangeNotification.class,
+            description = @Description(
+                value = "description",
+                bundleBaseName = "bundle",
+                key = "key"),
+            descriptorFields = {"foo=bar"})
+    public static class Impl1
+            extends NotificationBroadcasterSupport implements Impl1MBean {}
+
+    private static Object mbeanImpl1 = new Impl1();
+
+    @NotificationInfo(
+            types = {"foo", "bar"},
+            notificationClass = AttributeChangeNotification.class,
+            description = @Description(
+                value = "description",
+                bundleBaseName = "bundle",
+                key = "key"),
+            descriptorFields = {"foo=bar"})
+    public static class ParentImpl extends NotificationBroadcasterSupport {}
+
+    public static interface Impl2MBean {}
+
+    public static class Impl2 extends ParentImpl implements Impl2MBean {}
+
+    private static Object mbeanImpl2 = new Impl2();
+
+    public static interface Impl3MXBean {}
+
+    @NotificationInfo(
+            types = {"foo", "bar"},
+            notificationClass = AttributeChangeNotification.class,
+            description = @Description(
+                value = "description",
+                bundleBaseName = "bundle",
+                key = "key"),
+            descriptorFields = {"foo=bar"})
+    public static class Impl3
+            extends NotificationBroadcasterSupport implements Impl3MXBean {}
+
+    private static Object mbeanImpl3 = new Impl3();
+
+    public static class Impl4 extends ParentImpl implements Impl3MXBean {}
+
+    private static Object mbeanImpl4 = new Impl4();
+
+    @MBean
+    @NotificationInfo(
+            types = {"foo", "bar"},
+            notificationClass = AttributeChangeNotification.class,
+            description = @Description(
+                value = "description",
+                bundleBaseName = "bundle",
+                key = "key"),
+            descriptorFields = {"foo=bar"})
+    public static class MBean1 extends NotificationBroadcasterSupport {}
+
+    private static Object mbeanMBean1 = new MBean1();
+
+    @MBean
+    public static class MBean2 extends ParentImpl {}
+
+    private static Object mbeanMBean2 = new MBean2();
+
+    // Following disabled until we support it
+//    @MBean
+//    @NotificationInfo(
+//            types = {"foo", "bar"},
+//            notificationClass = AttributeChangeNotification.class,
+//            description = @Description(
+//                value = "description",
+//                bundleBaseName = "bundle",
+//                key = "key"),
+//            descriptorFields = {"foo=bar"})
+//    public static class MBean3 {
+//        @Resource
+//        private volatile SendNotification send;
+//    }
+//
+//    private static Object mbeanMBean3 = new MBean3();
+
+    @MXBean
+    @NotificationInfo(
+            types = {"foo", "bar"},
+            notificationClass = AttributeChangeNotification.class,
+            description = @Description(
+                value = "description",
+                bundleBaseName = "bundle",
+                key = "key"),
+            descriptorFields = {"foo=bar"})
+    public static class MXBean1 extends NotificationBroadcasterSupport {}
+
+    private static Object mbeanMXBean1 = new MXBean1();
+
+    @MXBean
+    public static class MXBean2 extends ParentImpl {}
+
+    private static Object mbeanMXBean2 = new MXBean2();
+
+    public static void main(String[] args) throws Exception {
+        if (!AnnotatedNotificationInfoTest.class.desiredAssertionStatus())
+            throw new Exception("Test must be run with -ea");
+
+        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+        ObjectName on = new ObjectName("a:b=c");
+
+        Descriptor expectedDescriptor = new ImmutableDescriptor(
+                "foo=bar", "descriptionResourceBundleBaseName=bundle",
+                "descriptionResourceKey=key");
+        MBeanNotificationInfo expected = new MBeanNotificationInfo(
+                new String[] {"foo", "bar"},
+                AttributeChangeNotification.class.getName(),
+                "description",
+                expectedDescriptor);
+
+        System.out.println("Testing MBeans...");
+        for (Field mbeanField :
+                AnnotatedNotificationInfoTest.class.getDeclaredFields()) {
+            if (!mbeanField.getName().startsWith("mbean"))
+                continue;
+            System.out.println("..." + mbeanField.getName());
+            Object mbean = mbeanField.get(null);
+            mbs.registerMBean(mbean, on);
+            MBeanInfo mbi = mbs.getMBeanInfo(on);
+            MBeanNotificationInfo[] mbnis = mbi.getNotifications();
+            assert mbnis.length == 1 : mbnis.length;
+            assert mbnis[0].equals(expected) : mbnis[0];
+            mbs.unregisterMBean(on);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/Introspector/MBeanDescriptionTest.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,830 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test %M% %I%
+ * @bug 6323980
+ * @summary Test &#64;Description
+ * @author Eamonn McManus
+ */
+
+import java.lang.management.ManagementFactory;
+import javax.management.Description;
+import javax.management.IntrospectionException;
+import javax.management.MBean;
+import javax.management.MBeanAttributeInfo;
+import javax.management.MBeanConstructorInfo;
+import javax.management.MBeanFeatureInfo;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.MBeanServer;
+import javax.management.MXBean;
+import javax.management.ManagedAttribute;
+import javax.management.ManagedOperation;
+import javax.management.NotCompliantMBeanException;
+import javax.management.ObjectName;
+import javax.management.StandardMBean;
+
+public class MBeanDescriptionTest {
+    private static String failure;
+    private static final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
+    private static final ObjectName name;
+    static {
+        try {
+            name = new ObjectName("a:b=c");
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static interface Interface {
+        @Description("A description")
+        public String getA();
+
+        @Description("B description")
+        public int getB();
+        public void setB(int x);
+
+        public boolean isC();
+        @Description("C description")
+        public void setC(boolean x);
+
+        @Description("D description")
+        public void setD(float x);
+
+        @Description("H description")
+        public int getH();
+        @Description("H description")
+        public void setH(int x);
+
+        public String getE();
+
+        public int getF();
+        public void setF(int x);
+
+        public void setG(boolean x);
+
+        @Description("opA description")
+        public int opA(
+                @Description("p1 description")
+                int p1,
+                @Description("p2 description")
+                int p2);
+
+        public void opB(float x);
+    }
+
+    @Description("MBean description")
+    public static interface TestMBean extends Interface {}
+
+    public static class Test implements TestMBean {
+        @Description("0-arg constructor description")
+        public Test() {}
+
+        public Test(String why) {}
+
+        @Description("2-arg constructor description")
+        public Test(
+                @Description("p1 description")
+                int x,
+                @Description("p2 description")
+                String y) {
+        }
+
+        public String getA() {
+            return null;
+        }
+
+        public int getB() {
+            return 0;
+        }
+
+        public void setB(int x) {
+        }
+
+        public boolean isC() {
+            return false;
+        }
+
+        public void setC(boolean x) {
+        }
+
+        public void setD(float x) {
+        }
+
+        public String getE() {
+            return null;
+        }
+
+        public int getF() {
+            return 0;
+        }
+
+        public void setF(int x) {
+        }
+
+        public void setG(boolean x) {
+        }
+
+        public int getH() {
+            return 0;
+        }
+
+        public void setH(int x) {
+        }
+
+        public int opA(int p1, int p2) {
+            return 0;
+        }
+
+        public void opB(float x) {
+        }
+    }
+
+    public static class TestSub extends Test {
+        @Description("0-arg constructor description")
+        public TestSub() {}
+
+        public TestSub(String why) {}
+
+        @Description("2-arg constructor description")
+        public TestSub(
+                @Description("p1 description")
+                int x,
+                @Description("p2 description")
+                String y) {
+        }
+    }
+
+    public static class StandardSub extends StandardMBean implements TestMBean {
+        @Description("0-arg constructor description")
+        public StandardSub() {
+            super(TestMBean.class, false);
+        }
+
+        public StandardSub(String why) {
+            super(TestMBean.class, false);
+        }
+
+        @Description("2-arg constructor description")
+        public StandardSub(
+                @Description("p1 description")
+                int x,
+                @Description("p2 description")
+                String y) {
+            super(TestMBean.class, false);
+        }
+
+        public String getA() {
+            return null;
+        }
+
+        public int getB() {
+            return 0;
+        }
+
+        public void setB(int x) {
+        }
+
+        public boolean isC() {
+            return false;
+        }
+
+        public void setC(boolean x) {
+        }
+
+        public void setD(float x) {
+        }
+
+        public String getE() {
+            return null;
+        }
+
+        public int getF() {
+            return 0;
+        }
+
+        public void setF(int x) {
+        }
+
+        public void setG(boolean x) {
+        }
+
+        public int opA(int p1, int p2) {
+            return 0;
+        }
+
+        public void opB(float x) {
+        }
+
+        public int getH() {
+            return 0;
+        }
+
+        public void setH(int x) {
+        }
+    }
+
+    @Description("MBean description")
+    public static interface TestMXBean extends Interface {}
+
+    public static class TestMXBeanImpl implements TestMXBean {
+        @Description("0-arg constructor description")
+        public TestMXBeanImpl() {}
+
+        public TestMXBeanImpl(String why) {}
+
+        @Description("2-arg constructor description")
+        public TestMXBeanImpl(
+                @Description("p1 description")
+                int x,
+                @Description("p2 description")
+                String y) {
+        }
+
+        public String getA() {
+            return null;
+        }
+
+        public int getB() {
+            return 0;
+        }
+
+        public void setB(int x) {
+        }
+
+        public boolean isC() {
+            return false;
+        }
+
+        public void setC(boolean x) {
+        }
+
+        public void setD(float x) {
+        }
+
+        public String getE() {
+            return null;
+        }
+
+        public int getF() {
+            return 0;
+        }
+
+        public void setF(int x) {
+        }
+
+        public void setG(boolean x) {
+        }
+
+        public int opA(int p1, int p2) {
+            return 0;
+        }
+
+        public void opB(float x) {
+        }
+
+        public int getH() {
+            return 0;
+        }
+
+        public void setH(int x) {
+        }
+    }
+
+    public static class StandardMXSub extends StandardMBean implements TestMXBean {
+        @Description("0-arg constructor description")
+        public StandardMXSub() {
+            super(TestMXBean.class, true);
+        }
+
+        public StandardMXSub(String why) {
+            super(TestMXBean.class, true);
+        }
+
+        @Description("2-arg constructor description")
+        public StandardMXSub(
+                @Description("p1 description")
+                int x,
+                @Description("p2 description")
+                String y) {
+            super(TestMXBean.class, true);
+        }
+
+        public String getA() {
+            return null;
+        }
+
+        public int getB() {
+            return 0;
+        }
+
+        public void setB(int x) {
+        }
+
+        public boolean isC() {
+            return false;
+        }
+
+        public void setC(boolean x) {
+        }
+
+        public void setD(float x) {
+        }
+
+        public String getE() {
+            return null;
+        }
+
+        public int getF() {
+            return 0;
+        }
+
+        public void setF(int x) {
+        }
+
+        public void setG(boolean x) {
+        }
+
+        public int opA(int p1, int p2) {
+            return 0;
+        }
+
+        public void opB(float x) {
+        }
+
+        public int getH() {
+            return 0;
+        }
+
+        public void setH(int x) {
+        }
+    }
+
+    @MBean
+    @Description("MBean description")
+    public static class AnnotatedMBean {
+        @Description("0-arg constructor description")
+        public AnnotatedMBean() {}
+
+        public AnnotatedMBean(String why) {}
+
+        @Description("2-arg constructor description")
+        public AnnotatedMBean(
+                @Description("p1 description")
+                int x,
+                @Description("p2 description")
+                String y) {}
+
+        @ManagedAttribute
+        @Description("A description")
+        public String getA() {
+            return null;
+        }
+
+        @ManagedAttribute
+        @Description("B description")
+        public int getB() {
+            return 0;
+        }
+
+        @ManagedAttribute
+        public void setB(int x) {
+        }
+
+        @ManagedAttribute
+        public boolean isC() {
+            return false;
+        }
+
+        @ManagedAttribute
+        @Description("C description")
+        public void setC(boolean x) {
+        }
+
+        @ManagedAttribute
+        @Description("D description")
+        public void setD(float x) {
+        }
+
+        @ManagedAttribute
+        public String getE() {
+            return null;
+        }
+
+        @ManagedAttribute
+        public int getF() {
+            return 0;
+        }
+
+        @ManagedAttribute
+        public void setF(int x) {
+        }
+
+        @ManagedAttribute
+        public void setG(boolean x) {
+        }
+
+        @ManagedAttribute
+        @Description("H description")
+        public int getH() {
+            return 0;
+        }
+
+        @ManagedAttribute
+        @Description("H description")
+        public void setH(int x) {
+        }
+
+        @ManagedOperation
+        @Description("opA description")
+        public int opA(
+                @Description("p1 description") int p1,
+                @Description("p2 description") int p2) {
+            return 0;
+        }
+
+        @ManagedOperation
+        public void opB(float x) {
+        }
+    }
+
+    @MXBean
+    @Description("MBean description")
+    public static class AnnotatedMXBean {
+        @Description("0-arg constructor description")
+        public AnnotatedMXBean() {}
+
+        public AnnotatedMXBean(String why) {}
+
+        @Description("2-arg constructor description")
+        public AnnotatedMXBean(
+                @Description("p1 description")
+                int x,
+                @Description("p2 description")
+                String y) {}
+
+        @ManagedAttribute
+        @Description("A description")
+        public String getA() {
+            return null;
+        }
+
+        @ManagedAttribute
+        @Description("B description")
+        public int getB() {
+            return 0;
+        }
+
+        @ManagedAttribute
+        public void setB(int x) {
+        }
+
+        @ManagedAttribute
+        public boolean isC() {
+            return false;
+        }
+
+        @ManagedAttribute
+        @Description("C description")
+        public void setC(boolean x) {
+        }
+
+        @ManagedAttribute
+        @Description("D description")
+        public void setD(float x) {
+        }
+
+        @ManagedAttribute
+        public String getE() {
+            return null;
+        }
+
+        @ManagedAttribute
+        public int getF() {
+            return 0;
+        }
+
+        @ManagedAttribute
+        public void setF(int x) {
+        }
+
+        @ManagedAttribute
+        public void setG(boolean x) {
+        }
+
+        @ManagedAttribute
+        @Description("H description")
+        public int getH() {
+            return 0;
+        }
+
+        @ManagedAttribute
+        @Description("H description")
+        public void setH(int x) {
+        }
+
+        @ManagedOperation
+        @Description("opA description")
+        public int opA(
+                @Description("p1 description") int p1,
+                @Description("p2 description") int p2) {
+            return 0;
+        }
+
+        @ManagedOperation
+        public void opB(float x) {
+        }
+    }
+
+    // Negative tests follow.
+
+    // Inconsistent descriptions
+    public static interface BadInterface {
+        @Description("foo")
+        public String getFoo();
+        @Description("bar")
+        public void setFoo(String x);
+    }
+
+    public static interface BadMBean extends BadInterface {}
+
+    public static class Bad implements BadMBean {
+        public String getFoo() {
+            return null;
+        }
+
+        public void setFoo(String x) {
+        }
+    }
+
+    public static interface BadMXBean extends BadInterface {}
+
+    public static class BadMXBeanImpl implements BadMXBean {
+        public String getFoo() {
+            return null;
+        }
+
+        public void setFoo(String x) {
+        }
+    }
+
+    private static interface Defaults {
+        public String defaultAttributeDescription(String name);
+        public String defaultOperationDescription(String name);
+        public String defaultParameterDescription(int index);
+    }
+
+    private static class StandardDefaults implements Defaults {
+        public String defaultAttributeDescription(String name) {
+            return "Attribute exposed for management";
+        }
+
+        public String defaultOperationDescription(String name) {
+            return "Operation exposed for management";
+        }
+
+        public String defaultParameterDescription(int index) {
+            return "";
+        }
+    }
+    private static final Defaults standardDefaults = new StandardDefaults();
+
+    private static class MXBeanDefaults implements Defaults {
+        public String defaultAttributeDescription(String name) {
+            return name;
+        }
+
+        public String defaultOperationDescription(String name) {
+            return name;
+        }
+
+        public String defaultParameterDescription(int index) {
+            return "p" + index;
+        }
+    }
+    private static final Defaults mxbeanDefaults = new MXBeanDefaults();
+
+    private static class TestCase {
+        final String name;
+        final Object mbean;
+        final Defaults defaults;
+        TestCase(String name, Object mbean, Defaults defaults) {
+            this.name = name;
+            this.mbean = mbean;
+            this.defaults = defaults;
+        }
+    }
+
+    private static class ExceptionTest {
+        final String name;
+        final Object mbean;
+        ExceptionTest(String name, Object mbean) {
+            this.name = name;
+            this.mbean = mbean;
+        }
+    }
+
+    private static final TestCase[] tests = {
+        new TestCase("Standard MBean", new Test(), standardDefaults),
+        new TestCase("Standard MBean subclass", new TestSub(), standardDefaults),
+        new TestCase("StandardMBean delegating",
+                new StandardMBean(new Test(), TestMBean.class, false),
+                standardDefaults),
+        new TestCase("StandardMBean delegating to subclass",
+                new StandardMBean(new TestSub(), TestMBean.class, false),
+                standardDefaults),
+        new TestCase("StandardMBean subclass", new StandardSub(), standardDefaults),
+
+        new TestCase("MXBean", new TestMXBeanImpl(), mxbeanDefaults),
+        new TestCase("StandardMBean MXBean delegating",
+                new StandardMBean(new TestMXBeanImpl(), TestMXBean.class, true),
+                mxbeanDefaults),
+        new TestCase("StandardMBean MXBean subclass",
+                new StandardMXSub(), mxbeanDefaults),
+
+        new TestCase("@MBean", new AnnotatedMBean(), standardDefaults),
+        new TestCase("@MXBean", new AnnotatedMXBean(), mxbeanDefaults),
+        new TestCase("StandardMBean @MBean delegating",
+                new StandardMBean(new AnnotatedMBean(), null, false),
+                standardDefaults),
+        new TestCase("StandardMBean @MXBean delegating",
+                new StandardMBean(new AnnotatedMXBean(), null, true),
+                mxbeanDefaults),
+    };
+
+    private static final ExceptionTest[] exceptionTests = {
+        new ExceptionTest("Standard MBean with inconsistent get/set", new Bad()),
+        new ExceptionTest("MXBean with inconsistent get/set", new BadMXBeanImpl()),
+    };
+
+    public static void main(String[] args) throws Exception {
+        System.out.println("=== Testing correct MBeans ===");
+        for (TestCase test : tests) {
+            System.out.println("Testing " + test.name + "...");
+            mbs.registerMBean(test.mbean, name);
+            boolean expectConstructors =
+                    (test.mbean.getClass() != StandardMBean.class);
+            check(mbs.getMBeanInfo(name), test.defaults, expectConstructors);
+            mbs.unregisterMBean(name);
+        }
+        System.out.println();
+
+        System.out.println("=== Testing incorrect MBeans ===");
+        for (ExceptionTest test : exceptionTests) {
+            System.out.println("Testing " + test.name);
+            try {
+                mbs.registerMBean(test.mbean, name);
+                fail("Registration succeeded but should not have");
+                mbs.unregisterMBean(name);
+            } catch (NotCompliantMBeanException e) {
+                // OK
+            } catch (Exception e) {
+                fail("Registration failed with wrong exception: " +
+                        "expected NotCompliantMBeanException, got " +
+                        e.getClass().getName());
+            }
+        }
+        System.out.println();
+
+        if (failure == null)
+            System.out.println("TEST PASSED");
+        else
+            throw new Exception("TEST FAILED: " + failure);
+    }
+
+    private static void check(
+            MBeanInfo mbi, Defaults defaults, boolean expectConstructors)
+            throws Exception {
+        assertEquals("MBean description", mbi.getDescription());
+
+        // These attributes have descriptions
+        for (String attr : new String[] {"A", "B", "C", "D", "H"}) {
+            MBeanAttributeInfo mbai = getAttributeInfo(mbi, attr);
+            assertEquals(attr + " description", mbai.getDescription());
+        }
+
+        // These attributes don't have descriptions
+        for (String attr : new String[] {"E", "F", "G"}) {
+            // If we ever change the default description, we'll need to change
+            // this test accordingly.
+            MBeanAttributeInfo mbai = getAttributeInfo(mbi, attr);
+            assertEquals(
+                    defaults.defaultAttributeDescription(attr), mbai.getDescription());
+        }
+
+        // This operation has a description, as do its parameters
+        MBeanOperationInfo opA = getOperationInfo(mbi, "opA");
+        assertEquals("opA description", opA.getDescription());
+        checkSignature(opA.getSignature());
+
+        // This operation has the default description, as does its parameter
+        MBeanOperationInfo opB = getOperationInfo(mbi, "opB");
+        assertEquals(defaults.defaultOperationDescription("opB"), opB.getDescription());
+        MBeanParameterInfo opB0 = opB.getSignature()[0];
+        assertEquals(defaults.defaultParameterDescription(0), opB0.getDescription());
+
+        if (expectConstructors) {
+            // The 0-arg and 2-arg constructors have descriptions
+            MBeanConstructorInfo con0 = getConstructorInfo(mbi, 0);
+            assertEquals("0-arg constructor description", con0.getDescription());
+            MBeanConstructorInfo con2 = getConstructorInfo(mbi, 2);
+            assertEquals("2-arg constructor description", con2.getDescription());
+            checkSignature(con2.getSignature());
+
+            // The 1-arg constructor does not have a description.
+            // The default description for constructors and their
+            // parameters is the same for all types of MBean.
+            MBeanConstructorInfo con1 = getConstructorInfo(mbi, 1);
+            assertEquals("Public constructor of the MBean", con1.getDescription());
+            assertEquals("", con1.getSignature()[0].getDescription());
+        }
+    }
+
+    private static void checkSignature(MBeanParameterInfo[] params) {
+        for (int i = 0; i < params.length; i++) {
+            MBeanParameterInfo mbpi = params[i];
+            assertEquals("p" + (i+1) + " description", mbpi.getDescription());
+        }
+    }
+
+    private static MBeanAttributeInfo getAttributeInfo(MBeanInfo mbi, String attr)
+    throws Exception {
+        return getFeatureInfo(mbi.getAttributes(), attr);
+    }
+
+    private static MBeanOperationInfo getOperationInfo(MBeanInfo mbi, String op)
+    throws Exception {
+        return getFeatureInfo(mbi.getOperations(), op);
+    }
+
+    private static MBeanConstructorInfo getConstructorInfo(MBeanInfo mbi, int nparams)
+    throws Exception {
+        for (MBeanConstructorInfo mbci : mbi.getConstructors()) {
+            if (mbci.getSignature().length == nparams)
+                return mbci;
+        }
+        throw new Exception("Constructor not found: " + nparams);
+    }
+
+    private static <T extends MBeanFeatureInfo> T getFeatureInfo(
+            T[] features, String name) throws Exception {
+        for (T feature : features) {
+            if (feature.getName().equals(name))
+                return feature;
+        }
+        throw new Exception("Feature not found: " + name);
+    }
+
+    private static void assertEquals(Object expected, Object actual) {
+        if (!expected.equals(actual))
+            fail("Expected " + string(expected) + ", got " + string(actual));
+    }
+
+    private static String string(Object x) {
+        if (x instanceof String)
+            return quote((String) x);
+        else
+            return String.valueOf(x);
+    }
+
+    private static String quote(String s) {
+        return '"' + s.replace("\\", "\\\\").replace("\"", "\\\"") + '"';
+    }
+
+    private static void fail(String why) {
+        StackTraceElement[] stack = new Throwable().getStackTrace();
+        int n = 0;
+        for (StackTraceElement elmt : stack) {
+            String method = elmt.getMethodName();
+            if (method.equals("fail") || method.equals("assertEquals") ||
+                    method.equals("checkSignature"))
+                continue;
+            n = elmt.getLineNumber();
+            break;
+        }
+        System.out.println("FAILED: " + why + " (line " + n + ")");
+        failure = why;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/Introspector/ParameterNameTest.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test %M% %I%
+ * @bug 6323980
+ * @summary Test that parameter names can be specified with &#64;Name.
+ * @author Eamonn McManus
+ */
+
+import javax.management.MBean;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanParameterInfo;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MXBean;
+import javax.management.ObjectName;
+
+import annot.Name;
+import javax.management.ManagedOperation;
+
+public class ParameterNameTest {
+    public static interface NoddyMBean {
+        public int add(int x, @Name("y") int y);
+    }
+
+    public static class Noddy implements NoddyMBean {
+        public int add(int x, int y) {
+            return x + y;
+        }
+    }
+
+    public static interface NoddyMXBean {
+        public int add(int x, @Name("y") int y);
+    }
+
+    public static class NoddyImpl implements NoddyMXBean {
+        public int add(int x, int y) {
+            return x + y;
+        }
+    }
+
+    @MBean
+    public static class NoddyAnnot {
+        @ManagedOperation
+        public int add(int x, @Name("y") int y) {
+            return x + y;
+        }
+    }
+
+    @MXBean
+    public static class NoddyAnnotMX {
+        @ManagedOperation
+        public int add(int x, @Name("y") int y) {
+            return x + y;
+        }
+    }
+
+    private static final Object[] mbeans = {
+        new Noddy(), new NoddyImpl(), new NoddyAnnot(), new NoddyAnnotMX(),
+    };
+
+    public static void main(String[] args) throws Exception {
+        MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+        ObjectName name = new ObjectName("a:b=c");
+        for (Object mbean : mbeans) {
+            System.out.println("Testing " + mbean.getClass().getName());
+            mbs.registerMBean(mbean, name);
+            MBeanInfo mbi = mbs.getMBeanInfo(name);
+            MBeanOperationInfo[] mbois = mbi.getOperations();
+            assertEquals(1, mbois.length);
+            MBeanParameterInfo[] mbpis = mbois[0].getSignature();
+            assertEquals(2, mbpis.length);
+            boolean mx = Boolean.parseBoolean(
+                    (String) mbi.getDescriptor().getFieldValue("mxbean"));
+            assertEquals(mx ? "p0" : "p1", mbpis[0].getName());
+            assertEquals("y", mbpis[1].getName());
+            mbs.unregisterMBean(name);
+        }
+        System.out.println("TEST PASSED");
+    }
+
+    private static void assertEquals(Object expect, Object actual)
+    throws Exception {
+        boolean eq;
+        if (expect == null)
+            eq = (actual == null);
+        else
+            eq = expect.equals(actual);
+        if (!eq) {
+            throw new Exception(
+                    "TEST FAILED: expected " + expect + ", found " + actual);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/Introspector/ResourceInjectionTest.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,656 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test %M% %I%
+ * @bug 6323980
+ * @summary Test resource injection via &#64;Resource
+ * @author Eamonn McManus
+ * @run main/othervm -ea ResourceInjectionTest
+ */
+
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.Serializable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import javax.annotation.Resource;
+import javax.management.Attribute;
+import javax.management.AttributeList;
+import javax.management.AttributeNotFoundException;
+import javax.management.DynamicMBean;
+import javax.management.InstanceNotFoundException;
+import javax.management.MBean;
+import javax.management.MBeanException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanRegistrationException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MXBean;
+import javax.management.MalformedObjectNameException;
+import javax.management.ManagedAttribute;
+import javax.management.ManagedOperation;
+import javax.management.NotCompliantMBeanException;
+import javax.management.Notification;
+import javax.management.NotificationEmitter;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.ReflectionException;
+import javax.management.SendNotification;
+import javax.management.StandardEmitterMBean;
+import javax.management.StandardMBean;
+import javax.management.openmbean.MXBeanMappingFactory;
+
+public class ResourceInjectionTest {
+    private static MBeanServer mbs;
+    private static final ObjectName objectName;
+    static {
+        try {
+            objectName = new ObjectName("test:type=Test");
+        } catch (MalformedObjectNameException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /* This is somewhat nasty.  In the current state of affairs, a
+     * StandardEmitterMBean can only get the
+     * MBeanServer to rewrite the source of a Notification from
+     * the originating object's reference to its ObjectName IF
+     * StandardEmitterMBean.getResource() returns a reference to the
+     * wrapped object.  By default it doesn't, and you need to specify
+     * the option below to make it do so.  We may hope that this is
+     * obscure enough for users to run into it rarely if ever.
+     */
+    private static final StandardMBean.Options withWrappedVisible;
+    private static final StandardMBean.Options withWrappedVisibleMX;
+    static {
+        withWrappedVisible = new StandardMBean.Options();
+        withWrappedVisible.setWrappedObjectVisible(true);
+        withWrappedVisibleMX = withWrappedVisible.clone();
+        withWrappedVisibleMX.setMXBeanMappingFactory(MXBeanMappingFactory.DEFAULT);
+    }
+
+    @Retention(RetentionPolicy.RUNTIME)
+    private static @interface ExpectException {
+        Class<? extends Exception> value();
+    }
+
+    public static void main(String[] args) throws Exception {
+        if (!ResourceInjectionTest.class.desiredAssertionStatus())
+            throw new Exception("Test must be run with -ea");
+
+        File policyFile = File.createTempFile("jmxperms", ".policy");
+        policyFile.deleteOnExit();
+        PrintWriter pw = new PrintWriter(policyFile);
+        pw.println("grant {");
+        pw.println("    permission javax.management.MBeanPermission \"*\", \"*\";");
+        pw.println("    permission javax.management.MBeanServerPermission \"*\";");
+        pw.println("    permission javax.management.MBeanTrustPermission \"*\";");
+        pw.println("};");
+        pw.close();
+
+        System.setProperty("java.security.policy", policyFile.getAbsolutePath());
+        System.setSecurityManager(new SecurityManager());
+
+        String failure = null;
+
+        for (Method m : ResourceInjectionTest.class.getDeclaredMethods()) {
+            if (Modifier.isStatic(m.getModifiers()) &&
+                    m.getName().startsWith("test") &&
+                    m.getParameterTypes().length == 0) {
+                ExpectException expexc = m.getAnnotation(ExpectException.class);
+                mbs = MBeanServerFactory.newMBeanServer();
+                try {
+                    m.invoke(null);
+                    if (expexc != null) {
+                        failure =
+                                m.getName() + " did not got expected exception " +
+                                expexc.value().getName();
+                        System.out.println(failure);
+                    } else
+                        System.out.println(m.getName() + " OK");
+                } catch (InvocationTargetException ite) {
+                    Throwable t = ite.getCause();
+                    String prob = null;
+                    if (expexc != null) {
+                        if (expexc.value().isInstance(t)) {
+                            System.out.println(m.getName() + " OK (got expected " +
+                                    expexc.value().getName() + ")");
+                        } else
+                            prob = "got wrong exception";
+                    } else
+                        prob = "got exception";
+                    if (prob != null) {
+                        failure = m.getName() + ": " + prob + " " +
+                                t.getClass().getName();
+                        System.out.println(failure);
+                        t.printStackTrace(System.out);
+                    }
+                }
+            }
+        }
+        if (failure == null)
+            System.out.println("TEST PASSED");
+        else
+            throw new Exception("TEST FAILED: " + failure);
+    }
+
+    private static interface Send {
+        public void send();
+    }
+
+    // Test @Resource in MBean defined by annotations
+
+    @MBean
+    public static class Annotated {
+        @Resource
+        private volatile MBeanServer mbeanServer;
+        @Resource
+        private volatile ObjectName myName;
+
+        @ManagedAttribute
+        public ObjectName getMyName() {
+            return myName;
+        }
+
+        @ManagedOperation
+        public void unregisterSelf()
+        throws InstanceNotFoundException, MBeanRegistrationException {
+            mbeanServer.unregisterMBean(myName);
+        }
+    }
+
+    private static void testAnnotated() throws Exception {
+        testMBean(new Annotated());
+    }
+
+    private static void testAnnotatedWrapped() throws Exception {
+        testMBean(new StandardMBean(new Annotated(), null));
+    }
+
+    @MBean
+    public static class AnnotatedSend extends Annotated implements Send {
+        @Resource
+        private volatile SendNotification sender;
+
+        @ManagedOperation
+        public void send() {
+            sender.sendNotification(new Notification("type", this, 0L));
+        }
+    }
+
+    private static void testAnnotatedSend() throws Exception {
+        testMBean(new AnnotatedSend());
+    }
+
+    private static void testAnnotatedSendWrapped() throws Exception {
+        testMBean(new StandardEmitterMBean(
+                new AnnotatedSend(), null, withWrappedVisible, null));
+    }
+
+    // Test @Resource in MXBean defined by annotations
+
+    @MXBean
+    public static class AnnotatedMX {
+        @Resource
+        private volatile MBeanServer mbeanServer;
+        @Resource
+        private volatile ObjectName myName;
+
+        @ManagedAttribute
+        public ObjectName getMyName() {
+            return myName;
+        }
+
+        @ManagedOperation
+        public void unregisterSelf()
+        throws InstanceNotFoundException, MBeanRegistrationException {
+            mbeanServer.unregisterMBean(myName);
+        }
+    }
+
+    private static void testAnnotatedMX() throws Exception {
+        testMBean(new AnnotatedMX());
+    }
+
+    private static void testAnnotatedMXWrapped() throws Exception {
+        testMBean(new StandardMBean(new AnnotatedMX(), null, true));
+    }
+
+    public static class AnnotatedMXSend extends AnnotatedMX implements Send {
+        @Resource
+        private volatile SendNotification sender;
+
+        @ManagedOperation
+        public void send() {
+            sender.sendNotification(new Notification("type", this, 0L));
+        }
+    }
+
+    private static void testAnnotatedMXSend() throws Exception {
+        testMBean(new AnnotatedMXSend());
+    }
+
+    private static void testAnnotatedMXSendWrapped() throws Exception {
+        testMBean(new StandardEmitterMBean(
+                new AnnotatedMXSend(), null, withWrappedVisibleMX, null));
+    }
+
+    // Test @Resource in Standard MBean
+
+    public static interface SimpleStandardMBean {
+        public ObjectName getMyName();
+        public void unregisterSelf() throws Exception;
+    }
+
+    public static class SimpleStandard implements SimpleStandardMBean {
+        @Resource(type = MBeanServer.class)
+        private volatile Object mbeanServer;
+        @Resource(type = ObjectName.class)
+        private volatile Object myName;
+
+        public ObjectName getMyName() {
+            return (ObjectName) myName;
+        }
+
+        public void unregisterSelf() throws Exception {
+            ((MBeanServer) mbeanServer).unregisterMBean(getMyName());
+        }
+    }
+
+    private static void testStandard() throws Exception {
+        testMBean(new SimpleStandard());
+    }
+
+    private static void testStandardWrapped() throws Exception {
+        testMBean(new StandardMBean(new SimpleStandard(), SimpleStandardMBean.class));
+    }
+
+    public static interface SimpleStandardSendMBean extends SimpleStandardMBean {
+        public void send();
+    }
+
+    public static class SimpleStandardSend
+            extends SimpleStandard implements SimpleStandardSendMBean {
+        @Resource(type = SendNotification.class)
+        private volatile Object sender;
+
+        public void send() {
+            ((SendNotification) sender).sendNotification(
+                    new Notification("type", this, 0L));
+        }
+    }
+
+    private static void testStandardSend() throws Exception {
+        testMBean(new SimpleStandardSend());
+    }
+
+    private static void testStandardSendWrapped() throws Exception {
+        testMBean(new StandardEmitterMBean(
+                new SimpleStandardSend(), SimpleStandardSendMBean.class,
+                withWrappedVisible, null));
+    }
+
+    // Test @Resource in MXBean
+
+    public static interface SimpleMXBean {
+        public ObjectName getMyName();
+        public void unregisterSelf() throws Exception;
+    }
+
+    public static class SimpleMX implements SimpleMXBean {
+        @Resource(type = MBeanServer.class)
+        private volatile Object mbeanServer;
+        @Resource(type = ObjectName.class)
+        private volatile Object myName;
+
+        public ObjectName getMyName() {
+            return (ObjectName) myName;
+        }
+
+        public void unregisterSelf() throws Exception {
+            ((MBeanServer) mbeanServer).unregisterMBean(getMyName());
+        }
+    }
+
+    private static void testMX() throws Exception {
+        testMBean(new SimpleMX());
+    }
+
+    private static void testMXWrapped() throws Exception {
+        testMBean(new StandardMBean(new SimpleMX(), SimpleMXBean.class, true));
+    }
+
+    public static interface SimpleMXBeanSend extends SimpleMXBean {
+        public void send();
+    }
+
+    public MBeanServer getMbs() {
+        return mbs;
+    }
+
+    public static class SimpleMXSend extends SimpleMX implements SimpleMXBeanSend {
+        @Resource(type = SendNotification.class)
+        private volatile Object sender;
+
+        public void send() {
+            ((SendNotification) sender).sendNotification(
+                    new Notification("type", this, 0L));
+        }
+    }
+
+    private static void testMXSend() throws Exception {
+        testMBean(new SimpleMXSend());
+    }
+
+    private static void testMXSendWrapped() throws Exception {
+        testMBean(new StandardEmitterMBean(
+                new SimpleMXSend(), SimpleMXBeanSend.class,
+                withWrappedVisibleMX, null));
+    }
+
+    // Test @Resource in Dynamic MBean
+
+    private static class SimpleDynamic implements DynamicMBean {
+        private MBeanServer mbeanServer;
+        private ObjectName myName;
+
+        @Resource
+        private synchronized void setMBeanServer(MBeanServer mbs) {
+            mbeanServer = mbs;
+        }
+
+        @Resource(type = ObjectName.class)
+        private synchronized void setObjectName(Serializable name) {
+            myName = (ObjectName) name;
+        }
+
+        public synchronized Object getAttribute(String attribute)
+        throws AttributeNotFoundException {
+            if (attribute.equals("MyName"))
+                return myName;
+            throw new AttributeNotFoundException(attribute);
+        }
+
+        public void setAttribute(Attribute attribute)
+        throws AttributeNotFoundException {
+            throw new AttributeNotFoundException(attribute.getName());
+        }
+
+        public synchronized AttributeList getAttributes(String[] attributes) {
+            AttributeList list = new AttributeList();
+            for (String name : attributes) {
+                if (name.equals("MyName"))
+                    list.add(new Attribute("MyName", myName));
+            }
+            return list;
+        }
+
+        public AttributeList setAttributes(AttributeList attributes) {
+            return new AttributeList();
+        }
+
+        public synchronized Object invoke(
+                String actionName, Object[] params, String[] signature)
+        throws MBeanException, ReflectionException {
+            if (actionName.equals("unregisterSelf") &&
+                    (params == null || params.length == 0) &&
+                    (signature == null || signature.length == 0)) {
+                try {
+                    mbeanServer.unregisterMBean(myName);
+                    return null;
+                } catch (Exception x) {
+                    throw new MBeanException(x);
+                }
+            } else {
+                Exception x = new NoSuchMethodException(
+                        actionName + Arrays.toString(signature));
+                throw new MBeanException(x);
+            }
+        }
+
+        public MBeanInfo getMBeanInfo() {
+            DynamicMBean mbean = new StandardMBean(
+                    new SimpleStandard(), SimpleStandardMBean.class, false);
+            return mbean.getMBeanInfo();
+        }
+    }
+
+    private static void testDynamic() throws Exception {
+        testMBean(new SimpleDynamic());
+    }
+
+    private static class SimpleDynamicSend extends SimpleDynamic {
+        private SendNotification sender;
+
+        @Resource
+        private synchronized void setSender(SendNotification sender) {
+            this.sender = sender;
+        }
+
+        @Override
+        public synchronized Object invoke(
+                String actionName, Object[] params, String[] signature)
+        throws MBeanException, ReflectionException {
+            if (actionName.equals("send")) {
+                sender.sendNotification(new Notification("type", this, 0L));
+                return null;
+            } else
+                return super.invoke(actionName, params, signature);
+        }
+    }
+
+    private static void testDynamicSend() throws Exception {
+        testMBean(new SimpleDynamicSend());
+    }
+
+    // Test that @Resource classes don't have to be public
+    // They can even be defined within methods!
+    // But you can't have any @ManagedAttributes or @ManagedOperations
+    // in such MBeans so their utility is limited.
+
+    private static void testNonPublic() throws Exception {
+        @MBean
+        class NonPublic {
+            @Resource
+            ObjectName myName;
+        }
+        assert !Modifier.isPublic(NonPublic.class.getModifiers());
+        NonPublic mbean = new NonPublic();
+        mbs.registerMBean(mbean, objectName);
+        assert objectName.equals(mbean.myName);
+    }
+
+    // Test inheritance and multiple injections of the same value
+
+    private static class ManyResources extends AnnotatedSend {
+        @Resource
+        private volatile ObjectName myName;  // same name as in parent!
+        @Resource(type=ObjectName.class)
+        private volatile Object myOtherName;
+        private volatile ObjectName myThirdName;
+        private volatile ObjectName myFourthName;
+        private volatile int methodCalls;
+        @Resource
+        private volatile SendNotification send1;
+        @Resource(type = SendNotification.class)
+        private volatile Object send2;
+
+        @Resource
+        void setMyName(ObjectName name) {
+            myThirdName = name;
+            methodCalls++;
+        }
+
+        @Resource(type=ObjectName.class)
+        private void setMyNameAgain(ObjectName name) {
+            myFourthName = name;
+            methodCalls++;
+        }
+
+        void check() {
+            assert objectName.equals(myName) : myName;
+            for (ObjectName name : new ObjectName[] {
+                (ObjectName)myOtherName, myThirdName, myFourthName
+            }) {
+                assert myName == name : name;
+            }
+            assert methodCalls == 2 : methodCalls;
+            assert send1 != null && send2 == send1;
+        }
+    }
+
+    private static void testManyResources() throws Exception {
+        ManyResources mr = new ManyResources();
+        testMBean(mr);
+        mr.check();
+    }
+
+    // Test that method override doesn't lead to multiple calls of the same method
+
+    private static class ManyResourcesSub extends ManyResources {
+        private boolean called;
+
+        @Override
+        @Resource
+        void setMyName(ObjectName name) {
+            super.setMyName(name);
+            called = true;
+        }
+
+        void check2() {
+            assert called;
+        }
+    }
+
+    private static void testOverride() throws Exception {
+        ManyResourcesSub mrs = new ManyResourcesSub();
+        testMBean(mrs);
+        mrs.check();
+        mrs.check2();
+    }
+
+    // Test that @Resource is illegal on static fields
+
+    @MBean
+    public static class StaticResource {
+        @Resource
+        private static ObjectName name;
+    }
+
+    @ExpectException(NotCompliantMBeanException.class)
+    private static void testStaticResource() throws Exception {
+        testMBean(new StaticResource());
+    }
+
+    // Test that @Resource is illegal on static methods
+
+    @MBean
+    public static class StaticResourceMethod {
+        @Resource
+        private static void setObjectName(ObjectName name) {}
+    }
+
+    @ExpectException(NotCompliantMBeanException.class)
+    private static void testStaticResourceMethod() throws Exception {
+        testMBean(new StaticResourceMethod());
+    }
+
+    // Test that @Resource is illegal on methods that don't return void
+
+    @MBean
+    public static class NonVoidMethod {
+        @Resource
+        private String setObjectName(ObjectName name) {
+            return "oops";
+        }
+    }
+
+    @ExpectException(NotCompliantMBeanException.class)
+    private static void testNonVoidMethod() throws Exception {
+        testMBean(new NonVoidMethod());
+    }
+
+    // Test that @Resource is illegal on methods with no arguments
+
+    @MBean
+    public static class NoArgMethod {
+        @Resource(type=ObjectName.class)
+        private void setObjectName() {}
+    }
+
+    @ExpectException(NotCompliantMBeanException.class)
+    private static void testNoArgMethod() throws Exception {
+        testMBean(new NoArgMethod());
+    }
+
+    // Test that @Resource is illegal on methods with more than one argument
+
+    @MBean
+    public static class MultiArgMethod {
+        @Resource
+        private void setObjectName(ObjectName name, String what) {}
+    }
+
+    @ExpectException(NotCompliantMBeanException.class)
+    private static void testMultiArgMethod() throws Exception {
+        testMBean(new MultiArgMethod());
+    }
+
+    private static class CountListener implements NotificationListener {
+        volatile int count;
+        public void handleNotification(Notification notification, Object handback) {
+            count++;
+        }
+    }
+
+    private static void testMBean(Object mbean) throws Exception {
+        mbs.registerMBean(mbean, objectName);
+
+        final ObjectName name = (ObjectName) mbs.getAttribute(objectName, "MyName");
+        assert objectName.equals(name) : name;
+
+        if (mbean instanceof Send || mbean instanceof NotificationEmitter) {
+            assert mbs.isInstanceOf(name, NotificationEmitter.class.getName());
+            CountListener countL = new CountListener();
+            mbs.addNotificationListener(name, countL, null, null);
+            NotificationListener checkSource = new NotificationListener() {
+                public void handleNotification(Notification n, Object h) {
+                    assert n.getSource().equals(name) : n.getSource();
+                }
+            };
+            mbs.addNotificationListener(name, checkSource, null, null);
+            mbs.invoke(objectName, "send", null, null);
+            assert countL.count == 1;
+            mbs.removeNotificationListener(name, checkSource);
+            mbs.removeNotificationListener(name, countL, null, null);
+        }
+
+        mbs.invoke(objectName, "unregisterSelf", null, null);
+        assert !mbs.isRegistered(objectName);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/Introspector/annot/Name.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package annot;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Name {
+    String value();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/mxbean/ComparatorExceptionTest.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6601652
+ * @summary Test exception when SortedMap or SortedSet has non-null Comparator
+ * @author Eamonn McManus
+ */
+
+import java.util.SortedMap;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.ObjectName;
+
+public class ComparatorExceptionTest {
+    public static interface TestMXBean {
+        public SortedSet<String> getSortedSet();
+        public SortedMap<String, String> getSortedMap();
+    }
+
+    public static class TestImpl implements TestMXBean {
+        public SortedSet<String> getSortedSet() {
+            return new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
+        }
+
+        public SortedMap<String, String> getSortedMap() {
+            return new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
+        }
+    }
+
+    private static String failure;
+
+    private static void fail(String why) {
+        failure = "FAILED: " + why;
+        System.out.println(failure);
+    }
+
+    public static void main(String[] args) throws Exception {
+        MBeanServer mbs = MBeanServerFactory.newMBeanServer();
+        ObjectName name = new ObjectName("a:b=c");
+        mbs.registerMBean(new TestImpl(), name);
+
+        for (String attr : new String[] {"SortedSet", "SortedMap"}) {
+            try {
+                Object value = mbs.getAttribute(name, attr);
+                fail("get " + attr + " did not throw exception");
+            } catch (Exception e) {
+                Throwable t = e;
+                while (!(t instanceof IllegalArgumentException)) {
+                    if (t == null)
+                        break;
+                    t = t.getCause();
+                }
+                if (t != null)
+                    System.out.println("Correct exception for " + attr);
+                else {
+                    fail("get " + attr + " got wrong exception");
+                    e.printStackTrace(System.out);
+                }
+            }
+        }
+
+        if (failure != null)
+            throw new Exception(failure);
+    }
+}
--- a/jdk/test/javax/management/mxbean/MXBeanTest.java	Thu Jul 17 11:28:32 2008 -0700
+++ b/jdk/test/javax/management/mxbean/MXBeanTest.java	Wed Jul 05 16:39:18 2017 +0200
@@ -23,7 +23,7 @@
 
 /*
  * @test
- * @bug 6175517 6278707 6318827 6305746 6392303
+ * @bug 6175517 6278707 6318827 6305746 6392303 6600709
  * @summary General MXBean test.
  * @author Eamonn McManus
  * @run clean MXBeanTest MerlinMXBean TigerMXBean
@@ -40,7 +40,8 @@
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
-import javax.management.Attribute;
+import java.util.Map;
+import java.util.SortedMap;
 import javax.management.JMX;
 import javax.management.MBeanAttributeInfo;
 import javax.management.MBeanInfo;
@@ -55,10 +56,6 @@
 import javax.management.openmbean.ArrayType;
 import javax.management.openmbean.CompositeData;
 import javax.management.openmbean.CompositeDataInvocationHandler;
-import javax.management.openmbean.OpenMBeanAttributeInfo;
-import javax.management.openmbean.OpenMBeanInfo;
-import javax.management.openmbean.OpenMBeanOperationInfo;
-import javax.management.openmbean.OpenMBeanParameterInfo;
 import javax.management.openmbean.OpenType;
 import javax.management.openmbean.SimpleType;
 import javax.management.openmbean.TabularData;
@@ -81,10 +78,8 @@
 
         if (failures == 0)
             System.out.println("Test passed");
-        else {
-            System.out.println("TEST FAILURES: " + failures);
-            System.exit(1);
-        }
+        else
+            throw new Exception("TEST FAILURES: " + failures);
     }
 
     private static int failures = 0;
@@ -561,6 +556,11 @@
                 return false;
             return deepEqual(o1, o2, namedMXBeans);
         }
+        if (o1 instanceof Map) {
+            if (!(o2 instanceof Map))
+                return false;
+            return equalMap((Map) o1, (Map) o2, namedMXBeans);
+        }
         if (o1 instanceof CompositeData && o2 instanceof CompositeData) {
             return compositeDataEqual((CompositeData) o1, (CompositeData) o2,
                                       namedMXBeans);
@@ -600,6 +600,21 @@
         return true;
     }
 
+    private static boolean equalMap(Map<?,?> m1, Map<?,?> m2,
+                                    NamedMXBeans namedMXBeans) {
+        if (m1.size() != m2.size())
+            return false;
+        if ((m1 instanceof SortedMap) != (m2 instanceof SortedMap))
+            return false;
+        for (Object k1 : m1.keySet()) {
+            if (!m2.containsKey(k1))
+                return false;
+            if (!equal(m1.get(k1), m2.get(k1), namedMXBeans))
+                return false;
+        }
+        return true;
+    }
+
     // This is needed to work around a bug (5095277)
     // in CompositeDataSupport.equals
     private static boolean compositeDataEqual(CompositeData cd1,
@@ -655,7 +670,7 @@
     /* I wanted to call this method toString(Object), but oddly enough
        this meant that I couldn't call it from the inner class
        MXBeanImplInvocationHandler, because the inherited Object.toString()
-       prevented that.  Surprising behaviour.  */
+       prevented that.  */
     static String string(Object o) {
         if (o == null)
             return "null";
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/management/mxbean/SameObjectTwoNamesTest.java	Wed Jul 05 16:39:18 2017 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2007 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test SameObjectTwoNamesTest.java
+ * @bug 6283873
+ * @summary Check that registering the same MXBean under two different
+ * names produces an exception
+ * @author Alexander Shusherov
+ * @author Eamonn McManus
+ * @run main SameObjectTwoNamesTest
+ * @run main/othervm -Djmx.mxbean.multiname=true SameObjectTwoNamesTest
+ */
+
+import javax.management.InstanceAlreadyExistsException;
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.ObjectName;
+
+public class SameObjectTwoNamesTest {
+
+    public static void main(String[] args) throws Exception {
+        boolean expectException =
+                (System.getProperty("jmx.mxbean.multiname") == null);
+        try {
+            ObjectName objectName1 = new ObjectName("test:index=1");
+            ObjectName objectName2 = new ObjectName("test:index=2");
+            MBeanServer mbs = MBeanServerFactory.createMBeanServer();
+            MXBC_SimpleClass01 mxBeanObject = new MXBC_SimpleClass01();
+
+            mbs.registerMBean(mxBeanObject, objectName1);
+
+            mbs.registerMBean(mxBeanObject, objectName2);
+
+            if (expectException) {
+                throw new Exception("TEST FAILED: " +
+                        "InstanceAlreadyExistsException was not thrown");
+            } else
+                System.out.println("Correctly got no exception with compat property");
+        } catch (InstanceAlreadyExistsException e) {
+            if (expectException) {
+                System.out.println("Got expected InstanceAlreadyExistsException:");
+                e.printStackTrace(System.out);
+            } else {
+                throw new Exception(
+                        "TEST FAILED: Got exception even though compat property set", e);
+            }
+        }
+        System.out.println("TEST PASSED");
+    }
+
+    public interface MXBC_Simple01MXBean {}
+
+    public static class MXBC_SimpleClass01 implements MXBC_Simple01MXBean {}
+
+}