Merge
authorjwilhelm
Tue, 08 Sep 2015 16:10:36 +0200
changeset 32758 f443e49794a4
parent 32505 341ac0627cc0 (current diff)
parent 32641 ac2c73b45253 (diff)
child 32759 6c71f3070a52
Merge
jdk/make/lib/CoreLibraries.gmk
jdk/src/java.base/share/native/libjava/Image.c
jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/IIOPHelper.java
jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/IIOPProxy.java
jdk/src/java.management/share/classes/com/sun/jmx/remote/protocol/iiop/ClientProvider.java
jdk/src/java.management/share/classes/com/sun/jmx/remote/protocol/iiop/IIOPProxyImpl.java
jdk/src/java.management/share/classes/com/sun/jmx/remote/protocol/iiop/ProxyInputStream.java
jdk/src/java.management/share/classes/com/sun/jmx/remote/protocol/iiop/ServerProvider.java
jdk/test/javax/management/remote/mandatory/connection/NoIIOP.java
--- a/jdk/make/lib/CoreLibraries.gmk	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/make/lib/CoreLibraries.gmk	Tue Sep 08 16:10:36 2015 +0200
@@ -239,6 +239,48 @@
 
 ##########################################################################################
 
+$(eval $(call SetupNativeCompilation,BUILD_LIBJIMAGE, \
+    LIBRARY := jimage, \
+    OUTPUT_DIR := $(INSTALL_LIBRARIES_HERE), \
+    OPTIMIZATION := LOW, \
+    SRC := $(JDK_TOPDIR)/src/java.base/share/native/libjimage \
+        $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjimage, \
+    EXCLUDES := $(LIBJIMAGE_EXCLUDES), \
+    CFLAGS := $(CFLAGS_JDKLIB) \
+        $(JIMAGELIB_CPPFLAGS) \
+        -I$(JDK_TOPDIR)/src/java.base/share/native/libjava \
+        -I$(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS_TYPE)/native/libjava \
+        -I$(JDK_TOPDIR)/src/java.base/share/native/libjimage \
+        -I$(SUPPORT_OUTPUTDIR)/headers/java.base, \
+    CFLAGS_unix := -UDEBUG, \
+    MAPFILE := $(JDK_TOPDIR)/make/mapfiles/libjimage/mapfile-vers, \
+    LDFLAGS := $(LDFLAGS_JDKLIB) \
+        $(call SET_SHARED_LIBRARY_ORIGIN) \
+        $(EXPORT_JIMAGE_FUNCS), \
+    LDFLAGS_windows := -export:JIMAGE_Open -export:JIMAGE_Close \
+        -export:JIMAGE_PackageToModule \
+        -export:JIMAGE_FindResource -export:JIMAGE_GetResource \
+        -export:JIMAGE_ResourceIterator, \
+    LDFLAGS_SUFFIX_unix := -ljvm -ldl $(LIBCXX), \
+    LDFLAGS_SUFFIX_linux := , \
+    LDFLAGS_SUFFIX_solaris := -lc, \
+    LDFLAGS_SUFFIX_aix := ,\
+    LDFLAGS_SUFFIX_macosx := -lc++, \
+    LDFLAGS_SUFFIX_windows := jvm.lib, \
+    VERSIONINFO_RESOURCE := $(GLOBAL_VERSION_INFO_RESOURCE), \
+    RC_FLAGS := $(RC_FLAGS) \
+        -D "JDK_FNAME=jimage.dll" \
+        -D "JDK_INTERNAL_NAME=jimage" \
+        -D "JDK_FTYPE=0x2L", \
+    OBJECT_DIR := $(SUPPORT_OUTPUTDIR)/native/$(MODULE)/libjimage, \
+    DEBUG_SYMBOLS := $(DEBUG_ALL_BINARIES)))
+
+$(BUILD_LIBJIMAGE): $(BUILD_LIBJAVA)
+
+TARGETS += $(BUILD_LIBJIMAGE)
+
+##########################################################################################
+
 LIBJLI_SRC_DIRS := $(call FindSrcDirsForLib, java.base, jli)
 
 LIBJLI_CFLAGS := $(CFLAGS_JDKLIB)
--- a/jdk/make/mapfiles/libjava/mapfile-vers	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/make/mapfiles/libjava/mapfile-vers	Tue Sep 08 16:10:36 2015 +0200
@@ -240,16 +240,6 @@
 		Java_java_util_TimeZone_getSystemTimeZoneID;
 		Java_java_util_TimeZone_getSystemGMTOffsetID;
 		Java_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8;
-                Java_jdk_internal_jimage_ImageNativeSubstrate_openImage;
-                Java_jdk_internal_jimage_ImageNativeSubstrate_closeImage;
-                Java_jdk_internal_jimage_ImageNativeSubstrate_getIndexAddress;
-                Java_jdk_internal_jimage_ImageNativeSubstrate_getDataAddress;
-                Java_jdk_internal_jimage_ImageNativeSubstrate_read;
-                Java_jdk_internal_jimage_ImageNativeSubstrate_readCompressed;
-                Java_jdk_internal_jimage_ImageNativeSubstrate_getStringBytes;
-                Java_jdk_internal_jimage_ImageNativeSubstrate_getAttributes;
-                Java_jdk_internal_jimage_ImageNativeSubstrate_findAttributes;
-                Java_jdk_internal_jimage_ImageNativeSubstrate_attributeOffsets;
 		Java_sun_misc_MessageUtils_toStderr;
 		Java_sun_misc_MessageUtils_toStdout;
 		Java_sun_misc_NativeSignalHandler_handle0;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/make/mapfiles/libjimage/mapfile-vers	Tue Sep 08 16:10:36 2015 +0200
@@ -0,0 +1,55 @@
+#
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.  Oracle designates this
+# particular file as subject to the "Classpath" exception as provided
+# by Oracle in the LICENSE file that accompanied this code.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+#
+
+# Define public interface.
+
+SUNWprivate_1.1 {
+    global:
+        JNI_OnLoad;
+        Java_jdk_internal_jimage_ImageNativeSubstrate_openImage;
+        Java_jdk_internal_jimage_ImageNativeSubstrate_closeImage;
+        Java_jdk_internal_jimage_ImageNativeSubstrate_getIndexAddress;
+        Java_jdk_internal_jimage_ImageNativeSubstrate_getDataAddress;
+        Java_jdk_internal_jimage_ImageNativeSubstrate_read;
+        Java_jdk_internal_jimage_ImageNativeSubstrate_readCompressed;
+        Java_jdk_internal_jimage_ImageNativeSubstrate_getStringBytes;
+        Java_jdk_internal_jimage_ImageNativeSubstrate_getAttributes;
+        Java_jdk_internal_jimage_ImageNativeSubstrate_findAttributes;
+        Java_jdk_internal_jimage_ImageNativeSubstrate_attributeOffsets;
+        Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1Open;
+        Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1Close;
+        Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1FindResource;
+        Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1GetResource;
+        Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1PackageToModule;
+        Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1Resources;
+        JIMAGE_Open;
+        JIMAGE_Close;
+        JIMAGE_PackageToModule;
+        JIMAGE_FindResource;
+        JIMAGE_GetResource;
+        JIMAGE_ResourceIterator;
+    local:
+        *;
+};
--- a/jdk/make/mapfiles/libzip/reorder-sparc	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/make/mapfiles/libzip/reorder-sparc	Tue Sep 08 16:10:36 2015 +0200
@@ -12,6 +12,7 @@
 text: .text%addMetaName: OUTPUTDIR/zip_util.o;
 text: .text%ZIP_FindEntry;
 text: .text%ZIP_GetEntry;
+text: .text%ZIP_InflateFully;
 text: .text%ZIP_Lock;
 text: .text%ZIP_Unlock;
 text: .text%ZIP_FreeEntry;
--- a/jdk/make/mapfiles/libzip/reorder-sparcv9	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/make/mapfiles/libzip/reorder-sparcv9	Tue Sep 08 16:10:36 2015 +0200
@@ -11,6 +11,7 @@
 text: .text%addMetaName: OUTPUTDIR/zip_util.o;
 text: .text%ZIP_FindEntry;
 text: .text%ZIP_GetEntry;
+text: .text%ZIP_InflateFully;
 text: .text%ZIP_Lock;
 text: .text%ZIP_Unlock;
 text: .text%ZIP_FreeEntry;
--- a/jdk/make/mapfiles/libzip/reorder-x86	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/make/mapfiles/libzip/reorder-x86	Tue Sep 08 16:10:36 2015 +0200
@@ -12,6 +12,7 @@
 text: .text%addMetaName: OUTPUTDIR/zip_util.o;
 text: .text%ZIP_FindEntry;
 text: .text%ZIP_GetEntry;
+text: .text%ZIP_InflateFully;
 text: .text%ZIP_Lock;
 text: .text%ZIP_Unlock;
 text: .text%ZIP_FreeEntry;
--- a/jdk/make/netbeans/jmx/build.xml	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/make/netbeans/jmx/build.xml	Tue Sep 08 16:10:36 2015 +0200
@@ -63,8 +63,8 @@
     <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~ -->
     <!-- Call rmic-jmx subtargets -->
 
-    <target name="-rmic-jmx" depends="-init,-rmic-jmx-jrmp,-rmic-jmx-iiop"
-	    description="Calls -init,-rmic-jmx-jrmp,-rmic-jmx-iiop"
+    <target name="-rmic-jmx" depends="-init,-rmic-jmx-jrmp"
+	    description="Calls -init,-rmic-jmx-jrmp"
     />
 
 
@@ -90,44 +90,6 @@
 
     </target>
 
-
-    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
-    <!-- Generate RMI IIOP stub class files for remote objects -->
-
-    <target name="-rmic-jmx-iiop" depends="-init,-check-jmx-iiop-uptodate" unless="jmx-iiop-uptodate"
-            description="Generate RMI IIOP stub class files for remote objects. Do not keep generated java files." >
-
-	<rmic 	base="${classes.dir}"
-		includeAntRuntime="no"
-		includeJavaRuntime="no"
-		stubversion="1.2"
-		iiop="yes"
-		>
-	    <include name="javax/management/remote/rmi/RMIConnectionImpl.class" />
-	    <include name="javax/management/remote/rmi/RMIServerImpl.class" />
-	</rmic>
-
-    </target>
-
-
-    <!-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
-    <!-- Check if jmx rmic generated IIOP stub and tie class files are up to date -->
-
-    <target name="-check-jmx-iiop-uptodate" depends="-init">
-
-	<uptodate property="jmx-iiop-uptodate"
-		   srcfile="${classes.dir}/javax/management/remote/rmi/RMIConnectionImpl.class"
-		targetfile="${classes.dir}/org/omg/stub/javax/management/remote/rmi/_RMIConnectionImpl_Tie.class"
-	/>
-	<uptodate property="jmx-iiop-uptodate"
-		   srcfile="${classes.dir}/javax/management/remote/rmi/RMIServerImpl.class"
-		targetfile="${classes.dir}/org/omg/stub/javax/management/remote/rmi/_RMIServerImpl_Tie.class"
-	/>
-
-	<echo message="jmx-iiop-uptodate=${jmx-iiop-uptodate}" />
-
-    </target>
-
     <target name="-post-compile" depends="-init,-rmic-jmx"
             description="Jar JMX class files (including RMI stubs)" >
        <mkdir dir="${dist.dir}/lib"/>
--- a/jdk/make/rmic/Rmic-java.management.gmk	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/make/rmic/Rmic-java.management.gmk	Tue Sep 08 16:10:36 2015 +0200
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -32,38 +32,31 @@
 # Generate RMI stubs
 #
 
-# For RMI/IIOP call rmic a second time with -standardPackage option
-# so that *_tie classes are generated in package without the prefix
-# org.omg.stub (6375696)
 JMX_RMI_CLASSES := javax.management.remote.rmi.RMIConnectionImpl \
     javax.management.remote.rmi.RMIServerImpl
-GENRMIIIOPCLASSES :=
-ifneq ($(RMICONNECTOR_IIOP), false)
-  GENRMIIIOPCLASSES := $(RMICONNECTOR_IIOP)
-endif
-$(eval $(call SetupRMICompilation,RMI_IIOP, \
+
+# Generate into gensrc dir where sources get picked up for javadoc, then move the classes
+# into the stub classes dir.
+$(eval $(call SetupRMICompilation,RMI_GEN, \
     CLASSES := $(JMX_RMI_CLASSES), \
     CLASSES_DIR := $(CLASSES_DIR)/java.management, \
-    STUB_CLASSES_DIR := $(STUB_CLASSES_DIR)/java.management, \
+    STUB_CLASSES_DIR := $(RMIC_GENSRC_DIR), \
     RUN_V12 := true, \
-    RUN_IIOP := $(GENRMIIIOPCLASSES), \
-    RUN_IIOP_STDPKG := $(GENRMIIIOPCLASSES)))
+    KEEP_GENERATED := true, \
+))
 
-# Keep generated RMI/JRMP Stub source files and copy them to RMIC_GENSRC_DIR
-# so that javadoc can include them in the API (4997471)
-$(eval $(call SetupRMICompilation,RMI_SRC, \
-    CLASSES := $(JMX_RMI_CLASSES), \
-    CLASSES_DIR := $(CLASSES_DIR)/java.management, \
-    STUB_CLASSES_DIR := $(RMIC_GENSRC_DIR)/java.management, \
-    RUN_V12 := true, \
-    KEEP_GENERATED := true))
+# Find all classes generated and move them from the gensrc dir to the stub classes dir
+$(RMIC_GENSRC_DIR)/_classes.moved: $(RMI_GEN)
+	$(eval classfiles := $(shell $(FIND) $(RMIC_GENSRC_DIR) -name "*.class"))
+	$(foreach src, $(classfiles), \
+	    $(eval target := $(patsubst $(RMIC_GENSRC_DIR)/%, \
+	        $(STUB_CLASSES_DIR)/java.management/%, $(src))) \
+	    $(MKDIR) -p $(dir $(target)) ; \
+	    $(MV) $(src) $(target) $(NEWLINE))
+	$(TOUCH) $@
 
 ##########################################################################################
 
-$(RMIC_GENSRC_DIR)/_the.classes.removed: $(RMI_IIOP) $(RMI_SRC)
-	$(FIND) $(RMIC_GENSRC_DIR) -name "*.class" $(FIND_DELETE)
-	$(TOUCH) $@
-
-all: $(RMIC_GENSRC_DIR)/_the.classes.removed $(RMI_IIOP) $(RMI_SRC)
+all: $(RMIC_GENSRC_DIR)/_classes.moved $(RMI_GEN)
 
 .PHONY: all
--- a/jdk/src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/BasicImageReader.java	Tue Sep 08 16:10:36 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
 import java.util.Comparator;
 import java.util.stream.IntStream;
 
-public class BasicImageReader {
+public class BasicImageReader implements AutoCloseable {
     private final String imagePath;
     private final ImageSubstrate substrate;
     private final ByteOrder byteOrder;
--- a/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageNativeSubstrate.java	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/src/java.base/share/classes/jdk/internal/jimage/ImageNativeSubstrate.java	Tue Sep 08 16:10:36 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,18 @@
 import sun.misc.JavaNioAccess;
 import sun.misc.SharedSecrets;
 
-final class ImageNativeSubstrate implements ImageSubstrate {
+public final class ImageNativeSubstrate implements ImageSubstrate {
+    static {
+        java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<Void>() {
+                @Override
+                public Void run() {
+                    System.loadLibrary("jimage");
+                    return null;
+                }
+            });
+     }
+
     private static final JavaNioAccess NIOACCESS =
             SharedSecrets.getJavaNioAccess();
 
@@ -52,6 +63,20 @@
     native static long[] findAttributes(long id, byte[] path);
     native static int[] attributeOffsets(long id);
 
+    public native static long JIMAGE_Open(String path) throws IOException;
+    public native static void JIMAGE_Close(long jimageHandle);
+    public native static long JIMAGE_FindResource(long jimageHandle,
+                    String moduleName, String Version, String path,
+                    long[] size);
+    public native static long JIMAGE_GetResource(long jimageHandle,
+                    long locationHandle, byte[] buffer, long size);
+    // Get an array of names that match; return the count found upto array size
+    public native static int JIMAGE_Resources(long jimageHandle,
+                    String[] outputNames);
+    // Return the module name for the package
+    public native static String JIMAGE_PackageToModule(long imageHandle,
+                    String packageName);
+
     static ByteBuffer newDirectByteBuffer(long address, long capacity) {
         assert capacity < Integer.MAX_VALUE;
         return NIOACCESS.newDirectByteBuffer(address, (int)capacity, null);
--- a/jdk/src/java.base/share/native/include/jvm.h	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/src/java.base/share/native/include/jvm.h	Tue Sep 08 16:10:36 2015 +0200
@@ -557,48 +557,6 @@
 JVM_SupportsCX8(void);
 
 /*
- * jdk.internal.jimage
- */
-
-JNIEXPORT jlong JNICALL
-JVM_ImageOpen(JNIEnv *env, const char *nativePath, jboolean big_endian);
-
-JNIEXPORT void JNICALL
-JVM_ImageClose(JNIEnv *env, jlong id);
-
-JNIEXPORT jlong JNICALL
-JVM_ImageGetIndexAddress(JNIEnv *env, jlong id);
-
-JNIEXPORT jlong JNICALL
-JVM_ImageGetDataAddress(JNIEnv *env,jlong id);
-
-JNIEXPORT jboolean JNICALL
-JVM_ImageRead(JNIEnv *env, jlong id, jlong offset,
-            unsigned char* uncompressedAddress, jlong uncompressed_size);
-
-JNIEXPORT jboolean JNICALL
-JVM_ImageReadCompressed(JNIEnv *env, jlong id, jlong offset,
-            unsigned char* compressedBuffer, jlong compressed_size,
-            unsigned char* uncompressedBuffer, jlong uncompressed_size);
-
-JNIEXPORT const char* JNICALL
-JVM_ImageGetStringBytes(JNIEnv *env, jlong id, jint offset);
-
-JNIEXPORT jlong* JNICALL
-JVM_ImageGetAttributes(JNIEnv *env, jlong* rawAttributes, jlong id, jint offset);
-
-JNIEXPORT jsize JNICALL
-JVM_ImageGetAttributesCount(JNIEnv *env);
-
-JNIEXPORT jlong* JNICALL
-JVM_ImageFindAttributes(JNIEnv *env, jlong* rawAttributes, jbyte* rawBytes, jsize size, jlong id);
-
-JNIEXPORT jint* JNICALL
-JVM_ImageAttributeOffsets(JNIEnv *env, jint* rawOffsets, unsigned int length, jlong id);
-
-JNIEXPORT unsigned int JNICALL
-JVM_ImageAttributeOffsetsLength(JNIEnv *env, jlong id);
-/*
  * com.sun.dtrace.jsdt support
  */
 
--- a/jdk/src/java.base/share/native/libjava/Image.c	Thu Sep 03 15:48:24 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-#include <string.h>
-
-#include "jni.h"
-#include "jvm.h"
-#include "jdk_internal_jimage_ImageNativeSubstrate.h"
-
-JNIEXPORT jlong JNICALL
-Java_jdk_internal_jimage_ImageNativeSubstrate_openImage(JNIEnv *env,
-        jclass cls, jstring path, jboolean big_endian) {
-    const char *nativePath;
-    jlong ret;
-
-    nativePath = (*env)->GetStringUTFChars(env, path, NULL);
-    ret = JVM_ImageOpen(env, nativePath, big_endian);
-    (*env)->ReleaseStringUTFChars(env, path, nativePath);
-    return ret;
-}
-
-JNIEXPORT void JNICALL
-Java_jdk_internal_jimage_ImageNativeSubstrate_closeImage(JNIEnv *env,
-                                        jclass cls, jlong id) {
-    JVM_ImageClose(env, id);
-}
-
-JNIEXPORT jlong JNICALL
-Java_jdk_internal_jimage_ImageNativeSubstrate_getIndexAddress(JNIEnv *env,
-                jclass cls, jlong id) {
- return JVM_ImageGetIndexAddress(env, id);
-}
-
-JNIEXPORT jlong JNICALL
-Java_jdk_internal_jimage_ImageNativeSubstrate_getDataAddress(JNIEnv *env,
-                jclass cls, jlong id) {
- return JVM_ImageGetDataAddress(env, id);
-}
-
-JNIEXPORT jboolean JNICALL
-Java_jdk_internal_jimage_ImageNativeSubstrate_read(JNIEnv *env,
-                                        jclass cls, jlong id, jlong offset,
-        jobject uncompressedBuffer, jlong uncompressed_size) {
-    unsigned char* uncompressedAddress;
-
-    uncompressedAddress = (unsigned char*) (*env)->GetDirectBufferAddress(env, uncompressedBuffer);
-    if (uncompressedBuffer == NULL) {
-      return JNI_FALSE;
-    }
-    return JVM_ImageRead(env, id, offset, uncompressedAddress, uncompressed_size);
-}
-
-JNIEXPORT jboolean JNICALL
-Java_jdk_internal_jimage_ImageNativeSubstrate_readCompressed(JNIEnv *env,
-                                        jclass cls, jlong id, jlong offset,
-                                        jobject compressedBuffer, jlong compressed_size,
-        jobject uncompressedBuffer, jlong uncompressed_size) {
-    // Get address of read direct buffer.
-    unsigned char* compressedAddress;
-    unsigned char* uncompressedAddress;
-
-    compressedAddress = (unsigned char*) (*env)->GetDirectBufferAddress(env, compressedBuffer);
-    // Get address of decompression direct buffer.
-    uncompressedAddress = (unsigned char*) (*env)->GetDirectBufferAddress(env, uncompressedBuffer);
-    if (uncompressedBuffer == NULL || compressedBuffer == NULL) {
-      return JNI_FALSE;
-    }
-    return JVM_ImageReadCompressed(env, id, offset, compressedAddress, compressed_size,
-            uncompressedAddress, uncompressed_size);
-}
-
-JNIEXPORT jbyteArray JNICALL
-Java_jdk_internal_jimage_ImageNativeSubstrate_getStringBytes(JNIEnv *env,
-                                        jclass cls, jlong id, jint offset) {
-    const char* data;
-    size_t size;
-    jbyteArray byteArray;
-    jbyte* rawBytes;
-
-    data = JVM_ImageGetStringBytes(env, id, offset);
-    // Determine String length.
-    size = strlen(data);
-    // Allocate byte array.
-    byteArray = (*env)->NewByteArray(env, (jsize) size);
-    if (byteArray == NULL) {
-        return NULL;
-    }
-    // Get array base address.
-    rawBytes = (*env)->GetByteArrayElements(env, byteArray, NULL);
-    // Copy bytes from image string table.
-    memcpy(rawBytes, data, size);
-    // Release byte array base address.
-    (*env)->ReleaseByteArrayElements(env, byteArray, rawBytes, 0);
-    return byteArray;
-}
-
-JNIEXPORT jlongArray JNICALL
-Java_jdk_internal_jimage_ImageNativeSubstrate_getAttributes(JNIEnv *env,
-        jclass cls, jlong id, jint offset) {
-    // Allocate a jlong large enough for all location attributes.
-    jlongArray attributes;
-    jlong* rawAttributes;
-    jlong* ret;
-
-    attributes = (*env)->NewLongArray(env, JVM_ImageGetAttributesCount(env));
-    if (attributes == NULL) {
-        return NULL;
-    }
-    // Get base address for jlong array.
-    rawAttributes = (*env)->GetLongArrayElements(env, attributes, NULL);
-    ret = JVM_ImageGetAttributes(env, rawAttributes, id, offset);
-    // Release jlong array base address.
-    (*env)->ReleaseLongArrayElements(env, attributes, rawAttributes, 0);
-    return ret == NULL ? NULL : attributes;
-}
-
-JNIEXPORT jlongArray JNICALL
-Java_jdk_internal_jimage_ImageNativeSubstrate_findAttributes(JNIEnv *env,
-        jclass cls, jlong id, jbyteArray utf8) {
-    // Allocate a jlong large enough for all location attributes.
-    jsize count;
-    jlongArray attributes;
-    jlong* rawAttributes;
-    jsize size;
-    jbyte* rawBytes;
-    jlong* ret;
-
-    count = JVM_ImageGetAttributesCount(env);
-    attributes = (*env)->NewLongArray(env, JVM_ImageGetAttributesCount(env));
-    if (attributes == NULL) {
-        return NULL;
-    }
-    // Get base address for jlong array.
-    rawAttributes = (*env)->GetLongArrayElements(env, attributes, NULL);
-    size = (*env)->GetArrayLength(env, utf8);
-    rawBytes = (*env)->GetByteArrayElements(env, utf8, NULL);
-    ret = JVM_ImageFindAttributes(env, rawAttributes, rawBytes, size, id);
-    (*env)->ReleaseByteArrayElements(env, utf8, rawBytes, 0);
-    // Release jlong array base address.
-    (*env)->ReleaseLongArrayElements(env, attributes, rawAttributes, 0);
-    return ret == NULL ? NULL : attributes;
-
-}
-
-JNIEXPORT jintArray JNICALL
-Java_jdk_internal_jimage_ImageNativeSubstrate_attributeOffsets(JNIEnv *env,
-        jclass cls, jlong id) {
-    unsigned int length;
-    jintArray offsets;
-    jint* rawOffsets;
-    jint* ret;
-
-    length = JVM_ImageAttributeOffsetsLength(env, id);
-    offsets = (*env)->NewIntArray(env, length);
-    if (offsets == NULL) {
-        return NULL;
-    }
-    // Get base address of result.
-    rawOffsets = (*env)->GetIntArrayElements(env, offsets, NULL);
-    ret = JVM_ImageAttributeOffsets(env, rawOffsets, length, id);
-    if (length == 0) {
-        return NULL;
-    }
-    // Release result base address.
-    (*env)->ReleaseIntArrayElements(env, offsets, rawOffsets, 0);
-    return ret == NULL ? NULL : offsets;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libjimage/ImageNativeSubstrate.cpp	Tue Sep 08 16:10:36 2015 +0200
@@ -0,0 +1,598 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include <string.h>
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jdk_util.h"
+#include "endian.hpp"
+#include "imageDecompressor.hpp"
+#include "imageFile.hpp"
+#include "inttypes.hpp"
+#include "jimage.hpp"
+#include "osSupport.hpp"
+
+#include "jdk_internal_jimage_ImageNativeSubstrate.h"
+
+extern bool MemoryMapImage;
+
+// jdk.internal.jimage /////////////////////////////////////////////////////////
+
+// Java entry to open an image file for sharing.
+
+static jlong JIMAGE_Open(JNIEnv *env, const char *nativePath, jboolean big_endian) {
+    // Open image file for reading.
+    ImageFileReader* reader = ImageFileReader::open(nativePath, big_endian != JNI_FALSE);
+    // Return image ID as a jlong.
+    return ImageFileReader::readerToID(reader);
+}
+
+// Java entry for closing a shared image file.
+
+static void JIMAGE_Close(JNIEnv *env, jlong id) {
+    // Convert image ID to image reader structure.
+    ImageFileReader* reader = ImageFileReader::idToReader(id);
+    // If valid reader the close.
+    if (reader != NULL) {
+        ImageFileReader::close(reader);
+    }
+}
+
+// Java entry for accessing the base address of the image index.
+
+static jlong JIMAGE_GetIndexAddress(JNIEnv *env, jlong id) {
+    // Convert image ID to image reader structure.
+    ImageFileReader* reader = ImageFileReader::idToReader(id);
+    // If valid reader return index base address (as jlong) else zero.
+    return reader != NULL ? (jlong) reader->get_index_address() : 0L;
+}
+
+// Java entry for accessing the base address of the image data.
+
+static jlong JIMAGE_GetDataAddress(JNIEnv *env, jlong id) {
+    // Convert image ID to image reader structure.
+    ImageFileReader* reader = ImageFileReader::idToReader(id);
+    // If valid reader return data base address (as jlong) else zero.
+    return MemoryMapImage && reader != NULL ? (jlong) reader->get_data_address() : 0L;
+}
+
+// Java entry for reading an uncompressed resource from the image.
+
+static jboolean JIMAGE_Read(JNIEnv *env, jlong id, jlong offset,
+        unsigned char* uncompressedAddress, jlong uncompressed_size) {
+    // Convert image ID to image reader structure.
+    ImageFileReader* reader = ImageFileReader::idToReader(id);\
+  // If not a valid reader the fail the read.
+    if (reader == NULL) return false;
+    // Get the file offset of resource data.
+    u8 file_offset = reader->get_index_size() + offset;
+    // Check validity of arguments.
+    if (offset < 0 ||
+            uncompressed_size < 0 ||
+            file_offset > reader->file_size() - uncompressed_size) {
+        return false;
+    }
+    // Read file content into buffer.
+    return (jboolean) reader->read_at((u1*) uncompressedAddress, uncompressed_size,
+            file_offset);
+}
+
+// Java entry for reading a compressed resource from the image.
+
+static jboolean JIMAGE_ReadCompressed(JNIEnv *env,
+        jlong id, jlong offset,
+        unsigned char* compressedAddress, jlong compressed_size,
+        unsigned char* uncompressedAddress, jlong uncompressed_size) {
+    // Convert image ID to image reader structure.
+    ImageFileReader* reader = ImageFileReader::idToReader(id);
+    // If not a valid reader the fail the read.
+    if (reader == NULL) return false;
+    // Get the file offset of resource data.
+    u8 file_offset = reader->get_index_size() + offset;
+    // Check validity of arguments.
+    if (offset < 0 ||
+            compressed_size < 0 ||
+            uncompressed_size < 0 ||
+            file_offset > reader->file_size() - compressed_size) {
+        return false;
+    }
+
+    // Read file content into buffer.
+    bool is_read = reader->read_at(compressedAddress, compressed_size,
+            file_offset);
+    // If successfully read then decompress.
+    if (is_read) {
+        const ImageStrings strings = reader->get_strings();
+        ImageDecompressor::decompress_resource(compressedAddress, uncompressedAddress,
+                (u4) uncompressed_size, &strings);
+    }
+    return (jboolean) is_read;
+}
+
+// Java entry for retrieving UTF-8 bytes from image string table.
+
+static const char* JIMAGE_GetStringBytes(JNIEnv *env, jlong id, jint offset) {
+    // Convert image ID to image reader structure.
+    ImageFileReader* reader = ImageFileReader::idToReader(id);
+    // Fail if not valid reader.
+    if (reader == NULL) return NULL;
+    // Manage image string table.
+    ImageStrings strings = reader->get_strings();
+    // Retrieve string adrress from table.
+    const char* data = strings.get(offset);
+    return data;
+}
+
+// Utility function to copy location information into a jlong array.
+// WARNING: This function is experimental and temporary during JDK 9 development
+// cycle. It will not be supported in the eventual JDK 9 release.
+
+static void image_expand_location(JNIEnv *env, jlong* rawAttributes, ImageLocation& location) {
+    // Copy attributes from location.
+    for (int kind = ImageLocation::ATTRIBUTE_END + 1;
+            kind < ImageLocation::ATTRIBUTE_COUNT;
+            kind++) {
+        rawAttributes[kind] = location.get_attribute(kind);
+    }
+}
+
+// Java entry for retrieving location attributes for attribute offset.
+
+static jlong* JIMAGE_GetAttributes(JNIEnv *env, jlong* rawAttributes, jlong id, jint offset) {
+    // Convert image ID to image reader structure.
+    ImageFileReader* reader = ImageFileReader::idToReader(id);
+    // Fail if not valid reader.
+    if (reader == NULL) return NULL;
+    // Retrieve first byte address of resource's location attribute stream.
+    u1* data = reader->get_location_offset_data(offset);
+    // Fail if not valid offset.
+    if (data == NULL) return NULL;
+    // Expand stream into array.
+    ImageLocation location(data);
+    image_expand_location(env, rawAttributes, location);
+    return rawAttributes;
+}
+
+// Java entry for retrieving location attributes count for attribute offset.
+
+static jsize JIMAGE_GetAttributesCount(JNIEnv *env) {
+    return ImageLocation::ATTRIBUTE_COUNT;
+}
+
+// Java entry for retrieving location attributes for named resource.
+
+static jlong* JIMAGE_FindAttributes(JNIEnv *env, jlong* rawAttributes, jbyte* rawBytes, jsize size, jlong id) {
+    // Convert image ID to image reader structure.
+    ImageFileReader* reader = ImageFileReader::idToReader(id);
+    // Fail if not valid reader.
+    if (reader == NULL) return NULL;
+    // Convert byte array to a cstring.
+    char* path = new char[size + 1];
+    memcpy(path, rawBytes, size);
+    path[size] = '\0';
+    // Locate resource location data.
+    ImageLocation location;
+    bool found = reader->find_location(path, location);
+    delete path;
+    // Resource not found.
+    if (!found) return NULL;
+    // Expand stream into array.
+    image_expand_location(env, rawAttributes, location);
+    return rawAttributes;
+}
+
+// Java entry for retrieving all the attribute stream offsets from an image.
+
+static jint* JIMAGE_AttributeOffsets(JNIEnv *env, jint* rawOffsets, unsigned int length, jlong id) {
+    // Convert image ID to image reader structure.
+    ImageFileReader* reader = ImageFileReader::idToReader(id);
+    // Fail if not valid reader.
+    if (reader == NULL) return NULL;
+    // Determine endian for reader.
+    Endian* endian = reader->endian();
+    // Get base address of attribute stream offsets table.
+    u4* offsets_table = reader->offsets_table();
+    // Allocate int array result.
+    // Copy values to result (converting endian.)
+    for (u4 i = 0; i < length; i++) {
+        rawOffsets[i] = endian->get(offsets_table[i]);
+    }
+    return rawOffsets;
+}
+
+// Java entry for retrieving all the attribute stream offsets length from an image.
+
+static unsigned int JIMAGE_AttributeOffsetsLength(JNIEnv *env, jlong id) {
+    // Convert image ID to image reader structure.
+    ImageFileReader* reader = ImageFileReader::idToReader(id);
+    // Fail if not valid reader.
+    if (reader == NULL) return 0;
+    // Get perfect hash table length.
+    u4 length = reader->table_length();
+    return (jint) length;
+}
+
+JNIEXPORT jint JNICALL
+JNI_OnLoad(JavaVM *vm, void *reserved) {
+    JNIEnv *env;
+
+    if (vm->GetEnv((void**) &env, JNI_VERSION_1_2) != JNI_OK) {
+        return JNI_EVERSION; /* JNI version not supported */
+    }
+
+    return JNI_VERSION_1_2;
+}
+
+JNIEXPORT jlong JNICALL
+Java_jdk_internal_jimage_ImageNativeSubstrate_openImage(JNIEnv *env,
+        jclass cls, jstring path, jboolean big_endian) {
+    const char *nativePath;
+    jlong ret;
+
+    nativePath = env->GetStringUTFChars(path, NULL);
+    ret = JIMAGE_Open(env, nativePath, big_endian);
+    env->ReleaseStringUTFChars(path, nativePath);
+    return ret;
+}
+
+JNIEXPORT void JNICALL
+Java_jdk_internal_jimage_ImageNativeSubstrate_closeImage(JNIEnv *env,
+        jclass cls, jlong id) {
+    JIMAGE_Close(env, id);
+}
+
+JNIEXPORT jlong JNICALL
+Java_jdk_internal_jimage_ImageNativeSubstrate_getIndexAddress(JNIEnv *env,
+        jclass cls, jlong id) {
+    return JIMAGE_GetIndexAddress(env, id);
+}
+
+JNIEXPORT jlong JNICALL
+Java_jdk_internal_jimage_ImageNativeSubstrate_getDataAddress(JNIEnv *env,
+        jclass cls, jlong id) {
+    return JIMAGE_GetDataAddress(env, id);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_jdk_internal_jimage_ImageNativeSubstrate_read(JNIEnv *env,
+        jclass cls, jlong id, jlong offset,
+        jobject uncompressedBuffer, jlong uncompressed_size) {
+    unsigned char* uncompressedAddress;
+
+    uncompressedAddress = (unsigned char*) env->GetDirectBufferAddress(uncompressedBuffer);
+    if (uncompressedAddress == NULL) {
+        return JNI_FALSE;
+    }
+    return JIMAGE_Read(env, id, offset, uncompressedAddress, uncompressed_size);
+}
+
+JNIEXPORT jboolean JNICALL
+Java_jdk_internal_jimage_ImageNativeSubstrate_readCompressed(JNIEnv *env,
+        jclass cls, jlong id, jlong offset,
+        jobject compressedBuffer, jlong compressed_size,
+        jobject uncompressedBuffer, jlong uncompressed_size) {
+    // Get address of read direct buffer.
+    unsigned char* compressedAddress;
+    unsigned char* uncompressedAddress;
+
+    compressedAddress = (unsigned char*) env->GetDirectBufferAddress(compressedBuffer);
+    // Get address of decompression direct buffer.
+    uncompressedAddress = (unsigned char*) env->GetDirectBufferAddress(uncompressedBuffer);
+    if (compressedAddress == NULL || uncompressedAddress == NULL) {
+        return JNI_FALSE;
+    }
+    return JIMAGE_ReadCompressed(env, id, offset, compressedAddress, compressed_size,
+            uncompressedAddress, uncompressed_size);
+}
+
+JNIEXPORT jbyteArray JNICALL
+Java_jdk_internal_jimage_ImageNativeSubstrate_getStringBytes(JNIEnv *env,
+        jclass cls, jlong id, jint offset) {
+    const char* data;
+    size_t size;
+    jbyteArray byteArray;
+    jbyte* rawBytes;
+
+    data = JIMAGE_GetStringBytes(env, id, offset);
+    // Determine String length.
+    size = strlen(data);
+    // Allocate byte array.
+    byteArray = env->NewByteArray((jsize) size);
+    if (byteArray == NULL) {
+        return NULL;
+    }
+    // Get array base address.
+    rawBytes = env->GetByteArrayElements(byteArray, NULL);
+    // Copy bytes from image string table.
+    memcpy(rawBytes, data, size);
+    // Release byte array base address.
+    env->ReleaseByteArrayElements(byteArray, rawBytes, 0);
+    return byteArray;
+}
+
+JNIEXPORT jlongArray JNICALL
+Java_jdk_internal_jimage_ImageNativeSubstrate_getAttributes(JNIEnv *env,
+        jclass cls, jlong id, jint offset) {
+    // Allocate a jlong large enough for all location attributes.
+    jlongArray attributes;
+    jlong* rawAttributes;
+    jlong* ret;
+
+    attributes = env->NewLongArray(JIMAGE_GetAttributesCount(env));
+    if (attributes == NULL) {
+        return NULL;
+    }
+    // Get base address for jlong array.
+    rawAttributes = env->GetLongArrayElements(attributes, NULL);
+    ret = JIMAGE_GetAttributes(env, rawAttributes, id, offset);
+    // Release jlong array base address.
+    env->ReleaseLongArrayElements(attributes, rawAttributes, 0);
+    return ret == NULL ? NULL : attributes;
+}
+
+JNIEXPORT jlongArray JNICALL
+Java_jdk_internal_jimage_ImageNativeSubstrate_findAttributes(JNIEnv *env,
+        jclass cls, jlong id, jbyteArray utf8) {
+    // Allocate a jlong large enough for all location attributes.
+    jsize count;
+    jlongArray attributes;
+    jlong* rawAttributes;
+    jsize size;
+    jbyte* rawBytes;
+    jlong* ret;
+
+    count = JIMAGE_GetAttributesCount(env);
+    attributes = env->NewLongArray(JIMAGE_GetAttributesCount(env));
+    if (attributes == NULL) {
+        return NULL;
+    }
+    // Get base address for jlong array.
+    rawAttributes = env->GetLongArrayElements(attributes, NULL);
+    size = env->GetArrayLength(utf8);
+    rawBytes = env->GetByteArrayElements(utf8, NULL);
+    ret = JIMAGE_FindAttributes(env, rawAttributes, rawBytes, size, id);
+    env->ReleaseByteArrayElements(utf8, rawBytes, 0);
+    // Release jlong array base address.
+    env->ReleaseLongArrayElements(attributes, rawAttributes, 0);
+    return ret == NULL ? NULL : attributes;
+
+}
+
+JNIEXPORT jintArray JNICALL
+Java_jdk_internal_jimage_ImageNativeSubstrate_attributeOffsets(JNIEnv *env,
+        jclass cls, jlong id) {
+    unsigned int length;
+    jintArray offsets;
+    jint* rawOffsets;
+    jint* ret;
+
+    length = JIMAGE_AttributeOffsetsLength(env, id);
+    offsets = env->NewIntArray(length);
+    if (offsets == NULL) {
+        return NULL;
+    }
+    // Get base address of result.
+    rawOffsets = env->GetIntArrayElements(offsets, NULL);
+    ret = JIMAGE_AttributeOffsets(env, rawOffsets, length, id);
+    if (length == 0) {
+        return NULL;
+    }
+    // Release result base address.
+    env->ReleaseIntArrayElements(offsets, rawOffsets, 0);
+    return ret == NULL ? NULL : offsets;
+}
+
+/*
+ * Class:     jdk_internal_jimage_ImageNativeSubstrate
+ * Method:    JIMAGE_open
+ * Signature: (Ljava/lang/String;)J
+ */
+JNIEXPORT jlong JNICALL Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1Open
+(JNIEnv *env, jclass, jstring path) {
+    const char *nativePath = env->GetStringUTFChars(path, NULL);
+    if (nativePath == NULL)
+        return 0; // Exception already thrown
+    jint error;
+    jlong ret = (jlong) JIMAGE_Open(nativePath, &error);
+    env->ReleaseStringUTFChars(path, nativePath);
+    return ret;
+}
+
+/*
+ * Class:     jdk_internal_jimage_ImageNativeSubstrate
+ * Method:    JIMAGE_Close
+ * Signature: (J)J
+ */
+JNIEXPORT void JNICALL Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1Close
+(JNIEnv *env, jclass, jlong jimageHandle) {
+    JIMAGE_Close((JImageFile*) jimageHandle);
+}
+
+/*
+ * Class:     jdk_internal_jimage_ImageNativeSubstrate
+ * Method:    JIMAGE_FindResource
+ * Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;[J)J
+ */
+JNIEXPORT jlong JNICALL Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1FindResource
+(JNIEnv *env, jclass, jlong jimageHandle, jstring moduleName,
+        jstring version, jstring path, jlongArray output_size) {
+    const char *native_module = NULL;
+    const char *native_version = NULL;
+    const char *native_path = NULL;
+    jlong * native_array = NULL;
+    jlong size = 0;
+    jlong ret = 0;
+
+    do {
+        native_module = env->GetStringUTFChars(moduleName, NULL);
+        if (native_module == NULL)
+            break;
+        native_version = env->GetStringUTFChars(version, NULL);
+        if (native_version == NULL)
+            break;
+        native_path = env->GetStringUTFChars(path, NULL);
+        if (native_path == NULL)
+            break;
+        if (env->GetArrayLength(output_size) < 1)
+            break;
+        // Get base address for jlong array.
+        native_array = env->GetLongArrayElements(output_size, NULL);
+        if (native_array == NULL)
+            break;
+
+        ret = (jlong) JIMAGE_FindResource((JImageFile *) jimageHandle,
+                native_module, native_version, native_path, &size);
+        if (ret != 0)
+            *native_array = size;
+    } while (0);
+
+    if (native_array != NULL)
+        env->ReleaseLongArrayElements(output_size, native_array, 0);
+    if (native_path != NULL)
+        env->ReleaseStringUTFChars(path, native_path);
+    if (native_version != NULL)
+        env->ReleaseStringUTFChars(path, native_version);
+    if (native_module != NULL)
+        env->ReleaseStringUTFChars(path, native_module);
+
+    return ret;
+}
+
+/*
+ * Class:     jdk_internal_jimage_ImageNativeSubstrate
+ * Method:    JIMAGE_GetResource
+ * Signature: (JJ[BJ)J
+ */
+JNIEXPORT jlong JNICALL Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1GetResource
+(JNIEnv *env, jclass, jlong jimageHandle, jlong jlocationHandle, jbyteArray buffer, jlong size) {
+    jbyte * native_buffer = NULL;
+    jlong actual_size = 0;
+    do {
+        if (env->GetArrayLength(buffer) < size)
+            break;
+
+        native_buffer = env->GetByteArrayElements(buffer, NULL);
+        if (native_buffer == NULL)
+            break;
+
+        actual_size = JIMAGE_GetResource((JImageFile*) jimageHandle,
+                (JImageLocationRef) jlocationHandle,
+                (char *) native_buffer, size);
+    } while (0);
+    // Release byte array
+    if (native_buffer != NULL)
+        env->ReleaseByteArrayElements(buffer, native_buffer, 0);
+
+    return actual_size;
+}
+
+// Structure passed from iterator to a visitor to accumulate the results
+
+struct VisitorData {
+    JNIEnv *env;
+    int size; // current number of strings
+    int max; // Maximum number of strings
+    jobjectArray array; // String array to store the strings
+};
+
+// Visitor to accumulate fully qualified resource names
+
+static bool resourceVisitor(JImageFile* image,
+        const char* module, const char* version, const char* package,
+        const char* name, const char* extension, void* arg) {
+    struct VisitorData *vdata = (struct VisitorData *) arg;
+    JNIEnv* env = vdata->env;
+    if (vdata->size < vdata->max) {
+        // Store if there is room in the array
+        // Concatenate to get full path
+        char fullpath[IMAGE_MAX_PATH];
+        fullpath[0] = '\0';
+        if (*module != '\0') {
+            strncpy(fullpath, "/", IMAGE_MAX_PATH - 1);
+            strncat(fullpath, module, IMAGE_MAX_PATH - 1);
+            strncat(fullpath, "/", IMAGE_MAX_PATH - 1);
+        }
+        if (*package != '\0') {
+            strncat(fullpath, package, IMAGE_MAX_PATH - 1);
+            strncat(fullpath, "/", IMAGE_MAX_PATH - 1);
+        }
+        strncat(fullpath, name, IMAGE_MAX_PATH - 1);
+        if (*extension != '\0') {
+            strncat(fullpath, ".", IMAGE_MAX_PATH - 1);
+            strncat(fullpath, extension, IMAGE_MAX_PATH - 1);
+        }
+        jobject str = env->NewStringUTF(fullpath);
+        JNU_CHECK_EXCEPTION_RETURN(env, true);
+        env->SetObjectArrayElement(vdata->array, vdata->size, str);
+        JNU_CHECK_EXCEPTION_RETURN(env, true);
+    }
+    vdata->size++; // always count so the total size is returned
+    return true;
+}
+
+/*
+ * Class:     jdk_internal_jimage_ImageNativeSubstrate
+ * Method:    JIMAGE_Resources
+ * Signature: (J)V
+ */
+JNIEXPORT jint JNICALL Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1Resources
+(JNIEnv *env, jclass, jlong jimageHandle,
+        jobjectArray outputNames) {
+    struct VisitorData vdata;
+    vdata.env = env;
+    vdata.max = 0;
+    vdata.size = 0;
+    vdata.array = outputNames;
+
+    vdata.max = (outputNames != NULL) ? env->GetArrayLength(outputNames) : 0;
+    JIMAGE_ResourceIterator((JImageFile*) jimageHandle, &resourceVisitor, &vdata);
+    return vdata.size;
+}
+
+/*
+ * Class:     jdk_internal_jimage_ImageNativeSubstrate
+ * Method:    JIMAGE_PackageToModule
+ * Signature: (JLjava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_jdk_internal_jimage_ImageNativeSubstrate_JIMAGE_1PackageToModule
+(JNIEnv *env, jclass, jlong jimageHandle, jstring package_name) {
+    const char *native_package = NULL;
+    const char *native_module = NULL;
+    jstring module = NULL;
+
+    native_package = env->GetStringUTFChars(package_name, NULL);
+    JNU_CHECK_EXCEPTION_RETURN(env, NULL);
+
+    native_module = JIMAGE_PackageToModule((JImageFile*) jimageHandle, native_package);
+    if (native_module != NULL) {
+        module = env->NewStringUTF(native_module);
+    }
+    env->ReleaseStringUTFChars(package_name, native_package);
+    return module;
+}
+
+JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
+    ImageDecompressor::image_decompressor_close();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libjimage/endian.cpp	Tue Sep 08 16:10:36 2015 +0200
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "endian.hpp"
+#include "inttypes.hpp"
+
+// Most modern compilers optimize the bswap routines to native instructions.
+inline static u2 bswap_16(u2 x) {
+  return ((x & 0xFF) << 8) |
+         ((x >> 8) & 0xFF);
+}
+
+inline static u4 bswap_32(u4 x) {
+  return ((x & 0xFF) << 24) |
+       ((x & 0xFF00) << 8) |
+       ((x >> 8) & 0xFF00) |
+       ((x >> 24) & 0xFF);
+}
+
+inline static u8 bswap_64(u8 x) {
+  return (u8)bswap_32((u4)x) << 32 |
+         (u8)bswap_32((u4)(x >> 32));
+}
+
+u2 NativeEndian::get(u2 x) { return x; }
+u4 NativeEndian::get(u4 x) { return x; }
+u8 NativeEndian::get(u8 x) { return x; }
+s2 NativeEndian::get(s2 x) { return x; }
+s4 NativeEndian::get(s4 x) { return x; }
+s8 NativeEndian::get(s8 x) { return x; }
+
+void NativeEndian::set(u2& x, u2 y) { x = y; }
+void NativeEndian::set(u4& x, u4 y) { x = y; }
+void NativeEndian::set(u8& x, u8 y) { x = y; }
+void NativeEndian::set(s2& x, s2 y) { x = y; }
+void NativeEndian::set(s4& x, s4 y) { x = y; }
+void NativeEndian::set(s8& x, s8 y) { x = y; }
+
+NativeEndian NativeEndian::_native;
+
+u2 SwappingEndian::get(u2 x) { return bswap_16(x); }
+u4 SwappingEndian::get(u4 x) { return bswap_32(x); }
+u8 SwappingEndian::get(u8 x) { return bswap_64(x); }
+s2 SwappingEndian::get(s2 x) { return bswap_16(x); }
+s4 SwappingEndian::get(s4 x) { return bswap_32(x); }
+s8 SwappingEndian::get(s8 x) { return bswap_64(x); }
+
+void SwappingEndian::set(u2& x, u2 y) { x = bswap_16(y); }
+void SwappingEndian::set(u4& x, u4 y) { x = bswap_32(y); }
+void SwappingEndian::set(u8& x, u8 y) { x = bswap_64(y); }
+void SwappingEndian::set(s2& x, s2 y) { x = bswap_16(y); }
+void SwappingEndian::set(s4& x, s4 y) { x = bswap_32(y); }
+void SwappingEndian::set(s8& x, s8 y) { x = bswap_64(y); }
+
+SwappingEndian SwappingEndian::_swapping;
+
+Endian* Endian::get_handler(bool big_endian) {
+  // If requesting little endian on a little endian machine or
+  // big endian on a big endian machine use native handler
+  if (big_endian == is_big_endian()) {
+    return NativeEndian::get_native();
+  } else {
+    // Use swapping handler.
+    return SwappingEndian::get_swapping();
+  }
+}
+
+// Return a platform u2 from an array in which Big Endian is applied.
+u2 Endian::get_java(u1* x) {
+  return (u2) (x[0]<<8 | x[1]);
+}
+
+// Add a platform u2 to the array as a Big Endian u2
+void Endian::set_java(u1* p, u2 x) {
+  p[0] = (x >> 8) & 0xff;
+  p[1] = x & 0xff;
+}
+
+Endian* Endian::get_native_handler() {
+  return NativeEndian::get_native();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libjimage/endian.hpp	Tue Sep 08 16:10:36 2015 +0200
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef LIBJIMAGE_ENDIAN_HPP
+#define LIBJIMAGE_ENDIAN_HPP
+
+#include "inttypes.hpp"
+
+// Selectable endian handling. Endian handlers are used when accessing values
+// that are of unknown (until runtime) endian.  The only requirement of the values
+// accessed are that they are aligned to proper size boundaries (no misalignment.)
+// To select an endian handler, one should call Endian::get_handler(big_endian);
+// Where big_endian is true if big endian is required and false otherwise.  The
+// native endian handler can be fetched with Endian::get_native_handler();
+// To retrieve a value using the approprate endian, use one of the overloaded
+// calls to get. To set a value, then use one of the overloaded set calls.
+// Ex.
+//      s4 value; // Imported value;
+//      ...
+//      Endian* endian = Endian::get_handler(true);  // Use big endian
+//      s4 corrected = endian->get(value);
+//      endian->set(value, 1);
+//
+class Endian {
+public:
+  virtual u2 get(u2 x) = 0;
+  virtual u4 get(u4 x) = 0;
+  virtual u8 get(u8 x) = 0;
+  virtual s2 get(s2 x) = 0;
+  virtual s4 get(s4 x) = 0;
+  virtual s8 get(s8 x) = 0;
+
+  virtual void set(u2& x, u2 y) = 0;
+  virtual void set(u4& x, u4 y) = 0;
+  virtual void set(u8& x, u8 y) = 0;
+  virtual void set(s2& x, s2 y) = 0;
+  virtual void set(s4& x, s4 y) = 0;
+  virtual void set(s8& x, s8 y) = 0;
+
+  // Quick little endian test.
+  static bool is_little_endian() {  u4 x = 1; return *(u1 *)&x != 0; }
+
+  // Quick big endian test.
+  static bool is_big_endian() { return !is_little_endian(); }
+
+  // Select an appropriate endian handler.
+  static Endian* get_handler(bool big_endian);
+
+  // Return the native endian handler.
+  static Endian* get_native_handler();
+
+  // get platform u2 from Java Big endian
+  static u2 get_java(u1* x);
+  // set platform u2 to Java Big endian
+  static void set_java(u1* p, u2 x);
+};
+
+// Normal endian handling.
+class NativeEndian : public Endian {
+private:
+  static NativeEndian _native;
+
+public:
+  u2 get(u2 x);
+  u4 get(u4 x);
+  u8 get(u8 x);
+  s2 get(s2 x);
+  s4 get(s4 x);
+  s8 get(s8 x);
+
+  void set(u2& x, u2 y);
+  void set(u4& x, u4 y);
+  void set(u8& x, u8 y);
+  void set(s2& x, s2 y);
+  void set(s4& x, s4 y);
+  void set(s8& x, s8 y);
+
+  static Endian* get_native() { return &_native; }
+};
+
+// Swapping endian handling.
+class SwappingEndian : public Endian {
+private:
+  static SwappingEndian _swapping;
+
+public:
+  u2 get(u2 x);
+  u4 get(u4 x);
+  u8 get(u8 x);
+  s2 get(s2 x);
+  s4 get(s4 x);
+  s8 get(s8 x);
+
+  void set(u2& x, u2 y);
+  void set(u4& x, u4 y);
+  void set(u8& x, u8 y);
+  void set(s2& x, s2 y);
+  void set(s4& x, s4 y);
+  void set(s8& x, s8 y);
+
+  static Endian* get_swapping() { return &_swapping; }
+};
+#endif // LIBJIMAGE_ENDIAN_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libjimage/imageDecompressor.cpp	Tue Sep 08 16:10:36 2015 +0200
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+
+#include "jni.h"
+#include "imageDecompressor.hpp"
+#include "endian.hpp"
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <dlfcn.h>
+#endif
+
+typedef jboolean (JNICALL *ZipInflateFully_t)(void *inBuf, jlong inLen, void *outBuf, jlong outLen, char **pmsg);
+static ZipInflateFully_t ZipInflateFully    = NULL;
+
+#ifndef WIN32
+  #define JNI_LIB_PREFIX "lib"
+  #ifdef __APPLE__
+    #define JNI_LIB_SUFFIX ".dylib"
+  #else
+    #define JNI_LIB_SUFFIX ".so"
+  #endif
+#endif
+
+/**
+ * Return the address of the entry point named in the zip shared library.
+ * @param name - the name of the entry point
+ * @return the address of the entry point or NULL
+ */
+static void* findEntry(const char* name) {
+  void *addr = NULL;
+#ifdef WIN32
+  HMODULE handle = GetModuleHandle("zip.dll");
+  if (handle == NULL) {
+    return NULL;
+  }
+  addr = (void*) GetProcAddress(handle, name);
+  return addr;
+#else
+  addr = dlopen(JNI_LIB_PREFIX "zip" JNI_LIB_SUFFIX, RTLD_GLOBAL|RTLD_LAZY);
+  if (addr == NULL) {
+    return NULL;
+  }
+  addr = dlsym(addr, name);
+  return addr;
+#endif
+}
+
+/*
+ * Initialize the array of decompressors.
+ */
+int ImageDecompressor::_decompressors_num = 0;
+ImageDecompressor** ImageDecompressor::_decompressors = NULL;
+void ImageDecompressor::image_decompressor_init() {
+  if (_decompressors == NULL) {
+    ZipInflateFully = (ZipInflateFully_t) findEntry("ZIP_InflateFully");
+   assert(ZipInflateFully != NULL && "ZIP decompressor not found.");
+    _decompressors_num = 2;
+    _decompressors = new ImageDecompressor*[_decompressors_num];
+    _decompressors[0] = new ZipDecompressor("zip");
+    _decompressors[1] = new SharedStringDecompressor("compact-cp");
+  }
+}
+
+void ImageDecompressor::image_decompressor_close() {
+  delete _decompressors;
+}
+
+/*
+ * Locate decompressor.
+ */
+ImageDecompressor* ImageDecompressor::get_decompressor(const char * decompressor_name) {
+  image_decompressor_init();
+  for (int i = 0; i < _decompressors_num; i++) {
+    ImageDecompressor* decompressor = _decompressors[i];
+    assert(decompressor != NULL && "Decompressors not initialized.");
+    if (strcmp(decompressor->get_name(), decompressor_name) == 0) {
+      return decompressor;
+    }
+  }
+  assert(false && "No decompressor found.");
+  return NULL;
+}
+
+/*
+ * Decompression entry point. Called from ImageFileReader::get_resource.
+ */
+void ImageDecompressor::decompress_resource(u1* compressed, u1* uncompressed,
+        u4 uncompressed_size, const ImageStrings* strings) {
+  bool has_header = false;
+  u1* decompressed_resource = compressed;
+  u1* compressed_resource = compressed;
+
+  // Resource could have been transformed by a stack of decompressors.
+  // Iterate and decompress resources until there is no more header.
+  do {
+    ResourceHeader _header;
+    memcpy(&_header, compressed_resource, sizeof (ResourceHeader));
+    has_header = _header._magic == ResourceHeader::resource_header_magic;
+    if (has_header) {
+      // decompressed_resource array contains the result of decompression
+      decompressed_resource = new u1[_header._uncompressed_size];
+      // Retrieve the decompressor name
+      const char* decompressor_name = strings->get(_header._decompressor_name_offset);
+      assert(decompressor_name && "image decompressor not found");
+      // Retrieve the decompressor instance
+      ImageDecompressor* decompressor = get_decompressor(decompressor_name);
+      assert(decompressor && "image decompressor not found");
+      u1* compressed_resource_base = compressed_resource;
+      compressed_resource += ResourceHeader::resource_header_length;
+      // Ask the decompressor to decompress the compressed content
+      decompressor->decompress_resource(compressed_resource, decompressed_resource,
+        &_header, strings);
+      if (compressed_resource_base != compressed) {
+        delete compressed_resource_base;
+      }
+      compressed_resource = decompressed_resource;
+    }
+  } while (has_header);
+  memcpy(uncompressed, decompressed_resource, uncompressed_size);
+  delete decompressed_resource;
+}
+
+// Zip decompressor
+
+void ZipDecompressor::decompress_resource(u1* data, u1* uncompressed,
+        ResourceHeader* header, const ImageStrings* strings) {
+  char* msg = NULL;
+  jboolean res = ZipDecompressor::decompress(data, header->_size, uncompressed,
+          header->_uncompressed_size, &msg);
+  assert(res && "decompression failed");
+}
+
+jboolean ZipDecompressor::decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg) {
+  return (*ZipInflateFully)(in, inSize, out, outSize, pmsg);
+}
+
+// END Zip Decompressor
+
+// Shared String decompressor
+
+// array index is the constant pool tag. value is size.
+// eg: array[5]  = 8; means size of long is 8 bytes.
+const u1 SharedStringDecompressor::sizes[] = {0, 0, 0, 4, 4, 8, 8, 2, 2, 4, 4, 4, 4, 0, 0, 3, 2, 0, 4};
+/**
+ * Recreate the class by reconstructing the constant pool.
+ */
+void SharedStringDecompressor::decompress_resource(u1* data,
+        u1* uncompressed_resource,
+        ResourceHeader* header, const ImageStrings* strings) {
+  u1* uncompressed_base = uncompressed_resource;
+  u1* data_base = data;
+  int header_size = 8; // magic + major + minor
+  memcpy(uncompressed_resource, data, header_size + 2); //+ cp count
+  uncompressed_resource += header_size + 2;
+  data += header_size;
+  u2 cp_count = Endian::get_java(data);
+  data += 2;
+  for (int i = 1; i < cp_count; i++) {
+    u1 tag = *data;
+    data += 1;
+    switch (tag) {
+
+      case externalized_string:
+      { // String in Strings table
+        *uncompressed_resource = 1;
+        uncompressed_resource += 1;
+        int i = decompress_int(data);
+        const char * string = strings->get(i);
+        int str_length = (int) strlen(string);
+        Endian::set_java(uncompressed_resource, str_length);
+        uncompressed_resource += 2;
+        memcpy(uncompressed_resource, string, str_length);
+        uncompressed_resource += str_length;
+        break;
+      }
+      // Descriptor String has been split and types added to Strings table
+      case externalized_string_descriptor:
+      {
+        *uncompressed_resource = 1;
+        uncompressed_resource += 1;
+        int descriptor_index = decompress_int(data);
+        int indexes_length = decompress_int(data);
+        u1* length_address = uncompressed_resource;
+        uncompressed_resource += 2;
+        int desc_length = 0;
+        const char * desc_string = strings->get(descriptor_index);
+        if (indexes_length > 0) {
+          u1* indexes_base = data;
+          data += indexes_length;
+          char c = *desc_string;
+          do {
+            *uncompressed_resource = c;
+            uncompressed_resource++;
+            desc_length += 1;
+            /*
+             * Every L character is the marker we are looking at in order
+             * to reconstruct the descriptor. Each time an L is found, then
+             * we retrieve the couple token/token at the current index and
+             * add it to the descriptor.
+             * "(L;I)V" and "java/lang","String" couple of tokens,
+             * this becomes "(Ljava/lang/String;I)V"
+             */
+            if (c == 'L') {
+              int index = decompress_int(indexes_base);
+              const char * pkg = strings->get(index);
+              int str_length = (int) strlen(pkg);
+              // the case where we have a package.
+              // reconstruct the type full name
+              if (str_length > 0) {
+                int len = str_length + 1;
+                char* fullpkg = new char[len];
+                char* pkg_base = fullpkg;
+                memcpy(fullpkg, pkg, str_length);
+                fullpkg += str_length;
+                *fullpkg = '/';
+                memcpy(uncompressed_resource, pkg_base, len);
+                uncompressed_resource += len;
+                delete pkg_base;
+                desc_length += len;
+              } else { // Empty package
+                // Nothing to do.
+              }
+              int classIndex = decompress_int(indexes_base);
+              const char * clazz = strings->get(classIndex);
+              int clazz_length = (int) strlen(clazz);
+              memcpy(uncompressed_resource, clazz, clazz_length);
+              uncompressed_resource += clazz_length;
+              desc_length += clazz_length;
+            }
+            desc_string += 1;
+            c = *desc_string;
+          } while (c != '\0');
+        } else {
+            desc_length = (int) strlen(desc_string);
+            memcpy(uncompressed_resource, desc_string, desc_length);
+            uncompressed_resource += desc_length;
+        }
+        Endian::set_java(length_address, desc_length);
+        break;
+      }
+
+      case constant_utf8:
+      { // UTF-8
+        *uncompressed_resource = tag;
+        uncompressed_resource += 1;
+        u2 str_length = Endian::get_java(data);
+        int len = str_length + 2;
+        memcpy(uncompressed_resource, data, len);
+        uncompressed_resource += len;
+        data += len;
+        break;
+      }
+
+      case constant_long:
+      case constant_double:
+      {
+        i++;
+      }
+      default:
+      {
+        *uncompressed_resource = tag;
+        uncompressed_resource += 1;
+        int size = sizes[tag];
+        memcpy(uncompressed_resource, data, size);
+        uncompressed_resource += size;
+        data += size;
+      }
+    }
+  }
+  u4 remain = header->_size - (int)(data - data_base);
+  u4 computed = (u4)(uncompressed_resource - uncompressed_base) + remain;
+  if (header->_uncompressed_size != computed)
+    printf("Failure, expecting %d but getting %d\n", header->_uncompressed_size,
+        computed);
+  assert(header->_uncompressed_size == computed &&
+        "Constant Pool reconstruction failed");
+  memcpy(uncompressed_resource, data, remain);
+}
+
+/*
+ * Decompress integers. Compressed integers are negative.
+ * If positive, the integer is not decompressed.
+ * If negative, length extracted from the first byte, then reconstruct the integer
+ * from the following bytes.
+ * Example of compression: 1 is compressed on 1 byte: 10100001
+ */
+int SharedStringDecompressor::decompress_int(unsigned char*& value) {
+  int len = 4;
+  int res = 0;
+  char b1 = *value;
+  if (is_compressed((signed char)b1)) { // compressed
+    len = get_compressed_length(b1);
+    char clearedValue = b1 &= 0x1F;
+    if (len == 1) {
+      res = clearedValue;
+    } else {
+      res = (clearedValue & 0xFF) << 8 * (len - 1);
+      for (int i = 1; i < len; i++) {
+        res |= (value[i]&0xFF) << 8 * (len - i - 1);
+      }
+    }
+  } else {
+    res = (value[0] & 0xFF) << 24 | (value[1]&0xFF) << 16 |
+          (value[2]&0xFF) << 8 | (value[3]&0xFF);
+  }
+  value += len;
+  return res;
+}
+// END Shared String decompressor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libjimage/imageDecompressor.hpp	Tue Sep 08 16:10:36 2015 +0200
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef LIBJIMAGE_IMAGEDECOMPRESSOR_HPP
+#define LIBJIMAGE_IMAGEDECOMPRESSOR_HPP
+
+#include <assert.h>
+#include <string.h>
+
+#include "imageFile.hpp"
+#include "inttypes.hpp"
+#include "jni.h"
+
+/*
+ * Compressed resources located in image have an header.
+ * This header contains:
+ * - _magic: A magic u4, required to retrieved the header in the compressed content
+ * - _size: The size of the compressed resource.
+ * - _uncompressed_size: The uncompressed size of the compressed resource.
+ * - _decompressor_name_offset: The ImageDecompressor instance name StringsTable offset.
+ * - _decompressor_config_offset: StringsTable offset of configuration that could be needed by
+ *   the decompressor in order to decompress.
+ * - _is_terminal: 1: the compressed content is terminal. Uncompressing it would
+ *   create the actual resource. 0: the compressed content is not terminal. Uncompressing it
+ *   will result in a compressed content to be decompressed (This occurs when a stack of compressors
+ *   have been used to compress the resource.
+ */
+struct ResourceHeader {
+  /* Length of header, needed to retrieve content offset */
+  static const u1 resource_header_length = 21;
+  /* magic bytes that identifies a compressed resource header*/
+  static const u4 resource_header_magic = 0xCAFEFAFA;
+  u4 _magic; // Resource header
+  u4 _size;  // Resource size
+  u4 _uncompressed_size;  // Expected uncompressed size
+  u4 _decompressor_name_offset;  // Strings table decompressor offset
+  u4 _decompressor_config_offset; // Strings table config offset
+  u1 _is_terminal; // Last decompressor 1, otherwise 0.
+};
+
+/*
+ * Resources located in jimage file can be compressed. Compression occurs at
+ * jimage file creation time. When compressed a resource is added an header that
+ * contains the name of the compressor that compressed it.
+ * Various compression strategies can be applied to compress a resource.
+ * The same resource can even be compressed multiple time by a stack of compressors.
+ * At runtime, a resource is decompressed in a loop until there is no more header
+ * meaning that the resource is equivalent to the not compressed resource.
+ * In each iteration, the name of the compressor located in the current header
+ * is used to retrieve the associated instance of ImageDecompressor.
+ * For example “zip” is the name of the compressor that compresses resources
+ * using the zip algorithm. The ZipDecompressor class name is also “zip”.
+ * ImageDecompressor instances are retrieved from a static array in which
+ * they are registered.
+ */
+class ImageDecompressor {
+
+private:
+  const char* _name;
+
+  /*
+   * Array of concrete decompressors. This array is used to retrieve the decompressor
+   * that can handle resource decompression.
+   */
+  static ImageDecompressor** _decompressors;
+  /**
+   * Num of decompressors
+   */
+  static int _decompressors_num;
+  /*
+   * Identifier of a decompressor. This name is the identification key to retrieve
+   * decompressor from a resource header.
+   */
+  inline const char* get_name() const { return _name; }
+
+
+protected:
+  ImageDecompressor(const char* name) : _name(name) {
+  }
+  virtual void decompress_resource(u1* data, u1* uncompressed,
+    ResourceHeader* header, const ImageStrings* strings) = 0;
+
+public:
+  static void image_decompressor_init();
+  static void image_decompressor_close();
+  static ImageDecompressor* get_decompressor(const char * decompressor_name) ;
+  static void decompress_resource(u1* compressed, u1* uncompressed,
+    u4 uncompressed_size, const ImageStrings* strings);
+};
+
+/**
+ * Zip decompressor.
+ */
+class ZipDecompressor : public ImageDecompressor {
+public:
+  ZipDecompressor(const char* sym) : ImageDecompressor(sym) { }
+  void decompress_resource(u1* data, u1* uncompressed, ResourceHeader* header,
+    const ImageStrings* strings);
+  static jboolean decompress(void *in, u8 inSize, void *out, u8 outSize, char **pmsg);
+};
+
+/*
+ * Shared Strings decompressor. This decompressor reconstruct the class
+ * constant pool UTF_U entries by retrieving strings stored in jimage strings table.
+ * In addition, if the UTF_8 entry is a descriptor, the descriptor has to be rebuilt,
+ * all java type having been removed from the descriptor and added to the sting table.
+ * eg: "(Ljava/lang/String;I)V" ==> "(L;I)V" and "java/lang", "String"
+ * stored in string table. offsets to the 2 strings are compressed and stored in the
+ * constantpool entry.
+ */
+class SharedStringDecompressor : public ImageDecompressor {
+private:
+  // the constant pool tag for UTF8 string located in strings table
+  static const int externalized_string = 23;
+  // the constant pool tag for UTF8 descriptors string located in strings table
+  static const int externalized_string_descriptor = 25;
+  // the constant pool tag for UTF8
+  static const int constant_utf8 = 1;
+  // the constant pool tag for long
+  static const int constant_long = 5;
+  // the constant pool tag for double
+  static const int constant_double = 6;
+  // array index is the constant pool tag. value is size.
+  // eg: array[5]  = 8; means size of long is 8 bytes.
+  static const u1 sizes[];
+  // bit 5 and 6 are used to store the length of the compressed integer.
+  // size can be 1 (01), 2 (10), 3 (11).
+  // 0x60 ==> 0110000
+  static const int compressed_index_size_mask = 0x60;
+  /*
+   * mask the length bits (5 and 6) and move to the right 5 bits.
+   */
+  inline static int get_compressed_length(char c) { return ((char) (c & compressed_index_size_mask) >> 5); }
+  inline static bool is_compressed(signed char b1) { return b1 < 0; }
+  static int decompress_int(unsigned char*& value);
+public:
+  SharedStringDecompressor(const char* sym) : ImageDecompressor(sym){}
+  void decompress_resource(u1* data, u1* uncompressed, ResourceHeader* header,
+  const ImageStrings* strings);
+};
+#endif // LIBJIMAGE_IMAGEDECOMPRESSOR_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libjimage/imageFile.cpp	Tue Sep 08 16:10:36 2015 +0200
@@ -0,0 +1,682 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "endian.hpp"
+#include "imageDecompressor.hpp"
+#include "imageFile.hpp"
+#include "inttypes.hpp"
+#include "jni.h"
+#include "osSupport.hpp"
+
+// Map the full jimage, only with 64 bit addressing.
+bool MemoryMapImage = sizeof(void *) == 8;
+
+#ifdef WIN32
+const char FileSeparator = '\\';
+#else
+const char FileSeparator = '/';
+#endif
+
+// Image files are an alternate file format for storing classes and resources. The
+// goal is to supply file access which is faster and smaller than the jar format.
+//
+// (More detailed nodes in the header.)
+//
+
+// Compute the Perfect Hashing hash code for the supplied UTF-8 string.
+s4 ImageStrings::hash_code(const char* string, s4 seed) {
+  // Access bytes as unsigned.
+  u1* bytes = (u1*)string;
+  // Compute hash code.
+  for (u1 byte = *bytes++; byte; byte = *bytes++) {
+    seed = (seed * HASH_MULTIPLIER) ^ byte;
+  }
+  // Ensure the result is not signed.
+  return seed & 0x7FFFFFFF;
+}
+
+// Match up a string in a perfect hash table.
+// Returns the index where the name should be.
+// Result still needs validation for precise match (false positive.)
+s4 ImageStrings::find(Endian* endian, const char* name, s4* redirect, u4 length) {
+  // If the table is empty, then short cut.
+  if (!redirect || !length) {
+    return NOT_FOUND;
+  }
+  // Compute the basic perfect hash for name.
+  s4 hash_code = ImageStrings::hash_code(name);
+  // Modulo table size.
+  s4 index = hash_code % length;
+  // Get redirect entry.
+  //   value == 0 then not found
+  //   value < 0 then -1 - value is true index
+  //   value > 0 then value is seed for recomputing hash.
+  s4 value = endian->get(redirect[index]);
+  // if recompute is required.
+  if (value > 0 ) {
+    // Entry collision value, need to recompute hash.
+    hash_code = ImageStrings::hash_code(name, value);
+    // Modulo table size.
+    return hash_code % length;
+  } else if (value < 0) {
+    // Compute direct index.
+    return -1 - value;
+  }
+  // No entry found.
+  return NOT_FOUND;
+}
+
+// Test to see if UTF-8 string begins with the start UTF-8 string.  If so,
+// return non-NULL address of remaining portion of string.  Otherwise, return
+// NULL.  Used to test sections of a path without copying from image string
+// table.
+const char* ImageStrings::starts_with(const char* string, const char* start) {
+  char ch1, ch2;
+  // Match up the strings the best we can.
+  while ((ch1 = *string) && (ch2 = *start)) {
+    if (ch1 != ch2) {
+      // Mismatch, return NULL.
+      return NULL;
+    }
+    // Next characters.
+    string++, start++;
+  }
+  // Return remainder of string.
+  return string;
+}
+
+// Inflates the attribute stream into individual values stored in the long
+// array _attributes. This allows an attribute value to be quickly accessed by
+// direct indexing.  Unspecified values default to zero (from constructor.)
+void ImageLocation::set_data(u1* data) {
+  // Deflate the attribute stream into an array of attributes.
+  u1 byte;
+  // Repeat until end header is found.
+  while ((byte = *data)) {
+    // Extract kind from header byte.
+    u1 kind = attribute_kind(byte);
+    assert(kind < ATTRIBUTE_COUNT && "invalid image location attribute");
+    // Extract length of data (in bytes).
+    u1 n = attribute_length(byte);
+    // Read value (most significant first.)
+    _attributes[kind] = attribute_value(data + 1, n);
+    // Position to next attribute by skipping attribute header and data bytes.
+    data += n + 1;
+  }
+}
+
+// Zero all attribute values.
+void ImageLocation::clear_data() {
+  // Set defaults to zero.
+  memset(_attributes, 0, sizeof(_attributes));
+}
+
+// ImageModuleData constructor maps out sub-tables for faster access.
+ImageModuleData::ImageModuleData(const ImageFileReader* image_file,
+        const char* module_data_name) :
+    _image_file(image_file),
+    _endian(image_file->endian()),
+    _strings(image_file->get_strings()) {
+  // Retrieve the resource containing the module data for the image file.
+  ImageLocation location;
+  bool found = image_file->find_location(module_data_name, location);
+  if (found) {
+    u8 data_size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
+    _data = new u1[(size_t)data_size];
+    _image_file->get_resource(location, _data);
+    // Map out the header.
+    _header = (Header*)_data;
+    // Get the package to module entry count.
+    u4 ptm_count = _header->ptm_count(_endian);
+    // Get the module to package entry count.
+    u4 mtp_count = _header->mtp_count(_endian);
+    // Compute the offset of the package to module perfect hash redirect.
+    u4 ptm_redirect_offset = sizeof(Header);
+    // Compute the offset of the package to module data.
+    u4 ptm_data_offset = ptm_redirect_offset + ptm_count * sizeof(s4);
+    // Compute the offset of the module to package perfect hash redirect.
+    u4 mtp_redirect_offset = ptm_data_offset + ptm_count * sizeof(PTMData);
+    // Compute the offset of the module to package data.
+    u4 mtp_data_offset = mtp_redirect_offset + mtp_count * sizeof(s4);
+    // Compute the offset of the module to package tables.
+    u4 mtp_packages_offset = mtp_data_offset + mtp_count * sizeof(MTPData);
+    // Compute the address of the package to module perfect hash redirect.
+    _ptm_redirect = (s4*)(_data + ptm_redirect_offset);
+    // Compute the address of the package to module data.
+    _ptm_data = (PTMData*)(_data + ptm_data_offset);
+    // Compute the address of the module to package perfect hash redirect.
+    _mtp_redirect = (s4*)(_data + mtp_redirect_offset);
+    // Compute the address of the module to package data.
+    _mtp_data = (MTPData*)(_data + mtp_data_offset);
+    // Compute the address of the module to package tables.
+    _mtp_packages = (s4*)(_data + mtp_packages_offset);
+  } else {
+    // No module data present.
+    _data = NULL;
+    _header = NULL;
+    _ptm_redirect = NULL;
+    _ptm_data = NULL;
+    _mtp_redirect = NULL;
+    _mtp_data = NULL;
+    _mtp_packages = NULL;
+  }
+}
+
+// Release module data resource.
+ImageModuleData::~ImageModuleData() {
+  if (_data) {
+    delete _data;
+  }
+}
+
+// Return the name of the module data resource.  Ex. "./lib/modules/file.jimage"
+// yields "file.jdata"
+void ImageModuleData::module_data_name(char* buffer, const char* image_file_name) {
+  // Locate the last slash in the file name path.
+  const char* slash = strrchr(image_file_name, FileSeparator);
+  // Trim the path to name and extension.
+  const char* name = slash ? slash + 1 : (char *)image_file_name;
+  // Locate the extension period.
+  const char* dot = strrchr(name, '.');
+  assert(dot && "missing extension on jimage name");
+  // Trim to only base name.
+  int length = (int)(dot - name);
+  strncpy(buffer, name, length);
+  buffer[length] = '\0';
+  // Append extension.
+  strcat(buffer, ".jdata");
+}
+
+// Return the module in which a package resides.  Returns NULL if not found.
+const char* ImageModuleData::package_to_module(const char* package_name) {
+  // Test files may contain no module data.
+  if (_data != NULL) {
+    // Search the package to module table.
+    s4 index = ImageStrings::find(_endian, package_name, _ptm_redirect,
+                                    _header->ptm_count(_endian));
+    // If entry is found.
+    if (index != ImageStrings::NOT_FOUND) {
+      // Retrieve the package to module entry.
+      PTMData* data = _ptm_data + index;
+      // Verify that it is the correct data.
+      if (strcmp(package_name, get_string(data->name_offset(_endian))) != 0) {
+        return NULL;
+      }
+      // Return the module name.
+      return get_string(data->module_name_offset(_endian));
+    }
+  }
+  return NULL;
+}
+
+// Returns all the package names in a module in a NULL terminated array.
+// Returns NULL if module not found.
+const char** ImageModuleData::module_to_packages(const char* module_name) {
+  // Test files may contain no module data.
+  if (_data != NULL) {
+    // Search the module to package table.
+    s4 index = ImageStrings::find(_endian, module_name, _mtp_redirect,
+                                    _header->mtp_count(_endian));
+    // If entry is found.
+    if (index != ImageStrings::NOT_FOUND) {
+      // Retrieve the module to package entry.
+      MTPData* data = _mtp_data + index;
+      // Verify that it is the correct data.
+      if (strcmp(module_name, get_string(data->name_offset(_endian))) != 0) {
+        return NULL;
+      }
+      // Construct an array of all the package entries.
+      u4 count = data->package_count(_endian);
+      const char** packages = new const char*[count + 1];
+      s4 package_offset = data->package_offset(_endian);
+      for (u4 i = 0; i < count; i++) {
+        u4 package_name_offset = mtp_package(package_offset + i);
+        const char* package_name = get_string(package_name_offset);
+        packages[i] = package_name;
+      }
+      packages[count] = NULL;
+      return packages;
+    }
+  }
+  return NULL;
+}
+
+// Manage a table of open image files.  This table allows multiple access points
+// to share an open image.
+ImageFileReaderTable::ImageFileReaderTable() : _count(0), _max(_growth) {
+  _table = new ImageFileReader*[_max];
+}
+
+ImageFileReaderTable::~ImageFileReaderTable() {
+  delete _table;
+}
+
+// Add a new image entry to the table.
+void ImageFileReaderTable::add(ImageFileReader* image) {
+  if (_count == _max) {
+    _max += _growth;
+    _table = static_cast<ImageFileReader**>(realloc(_table, _max * sizeof(ImageFileReader*)));
+  }
+  _table[_count++] = image;
+}
+
+// Remove an image entry from the table.
+void ImageFileReaderTable::remove(ImageFileReader* image) {
+  s4 last = _count - 1;
+  for (s4 i = 0; _count; i++) {
+    if (_table[i] == image) {
+      if (i != last) {
+        _table[i] = _table[last];
+        _count = last;
+      }
+      break;
+    }
+  }
+
+  if (_count != 0 && _count == _max - _growth) {
+    _max -= _growth;
+    _table = static_cast<ImageFileReader**>(realloc(_table, _max * sizeof(ImageFileReader*)));
+  }
+}
+
+// Determine if image entry is in table.
+bool ImageFileReaderTable::contains(ImageFileReader* image) {
+  for (s4 i = 0; _count; i++) {
+    if (_table[i] == image) {
+      return true;
+    }
+  }
+  return false;
+}
+
+// Table to manage multiple opens of an image file.
+ImageFileReaderTable ImageFileReader::_reader_table;
+
+SimpleCriticalSection _reader_table_lock;
+
+// Open an image file, reuse structure if file already open.
+ImageFileReader* ImageFileReader::open(const char* name, bool big_endian) {
+  {
+    // Lock out _reader_table.
+    SimpleCriticalSectionLock cs(&_reader_table_lock);
+    // Search for an exist image file.
+    for (u4 i = 0; i < _reader_table.count(); i++) {
+      // Retrieve table entry.
+      ImageFileReader* reader = _reader_table.get(i);
+      // If name matches, then reuse (bump up use count.)
+      if (strcmp(reader->name(), name) == 0) {
+        reader->inc_use();
+        return reader;
+      }
+    }
+  } // Unlock the mutex
+
+  // Need a new image reader.
+  ImageFileReader* reader = new ImageFileReader(name, big_endian);
+  bool opened = reader->open();
+  // If failed to open.
+  if (!opened) {
+    delete reader;
+    return NULL;
+  }
+
+  // Lock to update
+  SimpleCriticalSectionLock cs(&_reader_table_lock);
+  // Search for an exist image file.
+  for (u4 i = 0; i < _reader_table.count(); i++) {
+    // Retrieve table entry.
+    ImageFileReader* existing_reader = _reader_table.get(i);
+    // If name matches, then reuse (bump up use count.)
+    if (strcmp(existing_reader->name(), name) == 0) {
+      existing_reader->inc_use();
+      reader->close();
+      delete reader;
+      return existing_reader;
+    }
+  }
+  // Bump use count and add to table.
+  reader->inc_use();
+  _reader_table.add(reader);
+  return reader;
+}
+
+// Close an image file if the file is not in use elsewhere.
+void ImageFileReader::close(ImageFileReader *reader) {
+  // Lock out _reader_table.
+  SimpleCriticalSectionLock cs(&_reader_table_lock);
+  // If last use then remove from table and then close.
+  if (reader->dec_use()) {
+    _reader_table.remove(reader);
+    delete reader;
+  }
+}
+
+// Return an id for the specifed ImageFileReader.
+u8 ImageFileReader::readerToID(ImageFileReader *reader) {
+  // ID is just the cloaked reader address.
+  return (u8)reader;
+}
+
+// Validate the image id.
+bool ImageFileReader::idCheck(u8 id) {
+  // Make sure the ID is a managed (_reader_table) reader.
+  SimpleCriticalSectionLock cs(&_reader_table_lock);
+  return _reader_table.contains((ImageFileReader*)id);
+}
+
+// Return an id for the specifed ImageFileReader.
+ImageFileReader* ImageFileReader::idToReader(u8 id) {
+  assert(idCheck(id) && "invalid image id");
+  return (ImageFileReader*)id;
+}
+
+// Constructor intializes to a closed state.
+ImageFileReader::ImageFileReader(const char* name, bool big_endian) {
+  // Copy the image file name.
+   int len = (int) strlen(name) + 1;
+  _name = new char[len];
+  strncpy(_name, name, len);
+  // Initialize for a closed file.
+  _fd = -1;
+  _endian = Endian::get_handler(big_endian);
+  _index_data = NULL;
+}
+
+// Close image and free up data structures.
+ImageFileReader::~ImageFileReader() {
+  // Ensure file is closed.
+  close();
+  // Free up name.
+  if (_name) {
+    delete _name;
+    _name = NULL;
+  }
+}
+
+// Open image file for read access.
+bool ImageFileReader::open() {
+  char buffer[IMAGE_MAX_PATH];
+
+  // If file exists open for reading.
+  _fd = osSupport::openReadOnly(_name);
+  if (_fd == -1) {
+    return false;
+  }
+  // Retrieve the file size.
+  _file_size = osSupport::size(_name);
+  // Read image file header and verify it has a valid header.
+  size_t header_size = sizeof(ImageHeader);
+  if (_file_size < header_size ||
+    !read_at((u1*)&_header, header_size, 0) ||
+    _header.magic(_endian) != IMAGE_MAGIC ||
+    _header.major_version(_endian) != MAJOR_VERSION ||
+    _header.minor_version(_endian) != MINOR_VERSION) {
+    close();
+    return false;
+  }
+  // Size of image index.
+  _index_size = index_size();
+  // Make sure file is large enough to contain the index.
+  if (_file_size < _index_size) {
+    return false;
+  }
+  // Determine how much of the image is memory mapped.
+  size_t map_size = (size_t)(MemoryMapImage ? _file_size : _index_size);
+  // Memory map image (minimally the index.)
+  _index_data = (u1*)osSupport::map_memory(_fd, _name, 0, map_size);
+  assert(_index_data && "image file not memory mapped");
+  // Retrieve length of index perfect hash table.
+  u4 length = table_length();
+  // Compute offset of the perfect hash table redirect table.
+  u4 redirect_table_offset = (u4)header_size;
+  // Compute offset of index attribute offsets.
+  u4 offsets_table_offset = redirect_table_offset + length * sizeof(s4);
+  // Compute offset of index location attribute data.
+  u4 location_bytes_offset = offsets_table_offset + length * sizeof(u4);
+  // Compute offset of index string table.
+  u4 string_bytes_offset = location_bytes_offset + locations_size();
+  // Compute address of the perfect hash table redirect table.
+  _redirect_table = (s4*)(_index_data + redirect_table_offset);
+  // Compute address of index attribute offsets.
+  _offsets_table = (u4*)(_index_data + offsets_table_offset);
+  // Compute address of index location attribute data.
+  _location_bytes = _index_data + location_bytes_offset;
+  // Compute address of index string table.
+  _string_bytes = _index_data + string_bytes_offset;
+
+  // Initialize the module data
+  ImageModuleData::module_data_name(buffer, _name);
+  module_data = new ImageModuleData(this, buffer);
+  // Successful open.
+  return true;
+}
+
+// Close image file.
+void ImageFileReader::close() {
+  // Deallocate the index.
+  if (_index_data) {
+    osSupport::unmap_memory((char*)_index_data, _index_size);
+    _index_data = NULL;
+  }
+  // Close file.
+  if (_fd != -1) {
+    osSupport::close(_fd);
+    _fd = -1;
+  }
+}
+
+// Read directly from the file.
+bool ImageFileReader::read_at(u1* data, u8 size, u8 offset) const {
+  return (u8)osSupport::read(_fd, (char*)data, size, offset) == size;
+}
+
+// Find the location attributes associated with the path.  Returns true if
+// the location is found, false otherwise.
+bool ImageFileReader::find_location(const char* path, ImageLocation& location) const {
+  // Locate the entry in the index perfect hash table.
+  s4 index = ImageStrings::find(_endian, path, _redirect_table, table_length());
+  // If is found.
+  if (index != ImageStrings::NOT_FOUND) {
+    // Get address of first byte of location attribute stream.
+    u1* data = get_location_data(index);
+    // Expand location attributes.
+    location.set_data(data);
+    // Make sure result is not a false positive.
+    return verify_location(location, path);
+  }
+  return false;
+}
+
+// Find the location index and size associated with the path.
+// Returns the location index and size if the location is found, 0 otherwise.
+u4 ImageFileReader::find_location_index(const char* path, u8 *size) const {
+  // Locate the entry in the index perfect hash table.
+  s4 index = ImageStrings::find(_endian, path, _redirect_table, table_length());
+  // If found.
+  if (index != ImageStrings::NOT_FOUND) {
+    // Get address of first byte of location attribute stream.
+    u4 offset = get_location_offset(index);
+    u1* data = get_location_offset_data(offset);
+    // Expand location attributes.
+    ImageLocation location(data);
+    // Make sure result is not a false positive.
+    if (verify_location(location, path)) {
+        *size = (jlong)location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
+        return offset;
+    }
+  }
+  return 0;      // not found
+}
+
+// Assemble the location path from the string fragments indicated in the location attributes.
+void ImageFileReader::location_path(ImageLocation& location, char* path, size_t max) const {
+  // Manage the image string table.
+  ImageStrings strings(_string_bytes, _header.strings_size(_endian));
+  // Position to first character of the path buffer.
+  char* next = path;
+  // Temp for string length.
+  size_t length;
+  // Get module string.
+  const char* module = location.get_attribute(ImageLocation::ATTRIBUTE_MODULE, strings);
+  // If module string is not empty string.
+  if (*module != '\0') {
+    // Get length of module name.
+    length = strlen(module);
+    // Make sure there is no buffer overflow.
+    assert(next - path + length + 2 < max && "buffer overflow");
+    // Append '/module/'.
+    *next++ = '/';
+    strncpy(next, module, length); next += length;
+    *next++ = '/';
+  }
+  // Get parent (package) string.
+  const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
+  // If parent string is not empty string.
+  if (*parent != '\0') {
+    // Get length of module string.
+    length = strlen(parent);
+    // Make sure there is no buffer overflow.
+    assert(next - path + length + 1 < max && "buffer overflow");
+    // Append 'patent/' .
+    strncpy(next, parent, length); next += length;
+    *next++ = '/';
+  }
+  // Get base name string.
+  const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
+  // Get length of base name.
+  length = strlen(base);
+  // Make sure there is no buffer overflow.
+  assert(next - path + length < max && "buffer overflow");
+  // Append base name.
+  strncpy(next, base, length); next += length;
+  // Get extension string.
+  const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
+  // If extension string is not empty string.
+  if (*extension != '\0') {
+    // Get length of extension string.
+    length = strlen(extension);
+    // Make sure there is no buffer overflow.
+    assert(next - path + length + 1 < max && "buffer overflow");
+    // Append '.extension' .
+    *next++ = '.';
+    strncpy(next, extension, length); next += length;
+  }
+  // Make sure there is no buffer overflow.
+  assert((size_t)(next - path) < max && "buffer overflow");
+  // Terminate string.
+  *next = '\0';
+}
+
+// Verify that a found location matches the supplied path (without copying.)
+bool ImageFileReader::verify_location(ImageLocation& location, const char* path) const {
+  // Manage the image string table.
+  ImageStrings strings(_string_bytes, _header.strings_size(_endian));
+  // Position to first character of the path string.
+  const char* next = path;
+  // Get module name string.
+  const char* module = location.get_attribute(ImageLocation::ATTRIBUTE_MODULE, strings);
+  // If module string is not empty.
+  if (*module != '\0') {
+    // Compare '/module/' .
+    if (*next++ != '/') return false;
+    if (!(next = ImageStrings::starts_with(next, module))) return false;
+    if (*next++ != '/') return false;
+  }
+  // Get parent (package) string
+  const char* parent = location.get_attribute(ImageLocation::ATTRIBUTE_PARENT, strings);
+  // If parent string is not empty string.
+  if (*parent != '\0') {
+    // Compare 'parent/' .
+    if (!(next = ImageStrings::starts_with(next, parent))) return false;
+    if (*next++ != '/') return false;
+  }
+  // Get base name string.
+  const char* base = location.get_attribute(ImageLocation::ATTRIBUTE_BASE, strings);
+  // Compare with basne name.
+  if (!(next = ImageStrings::starts_with(next, base))) return false;
+  // Get extension string.
+  const char* extension = location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION, strings);
+  // If extension is not empty.
+  if (*extension != '\0') {
+    // Compare '.extension' .
+    if (*next++ != '.') return false;
+    if (!(next = ImageStrings::starts_with(next, extension))) return false;
+  }
+  // True only if complete match and no more characters.
+  return *next == '\0';
+}
+
+// Return the resource for the supplied location offset.
+void ImageFileReader::get_resource(u4 offset, u1* uncompressed_data) const {
+    // Get address of first byte of location attribute stream.
+    u1* data = get_location_offset_data(offset);
+    // Expand location attributes.
+    ImageLocation location(data);
+    // Read the data
+    get_resource(location, uncompressed_data);
+}
+
+// Return the resource for the supplied location.
+void ImageFileReader::get_resource(ImageLocation& location, u1* uncompressed_data) const {
+  // Retrieve the byte offset and size of the resource.
+  u8 offset = location.get_attribute(ImageLocation::ATTRIBUTE_OFFSET);
+  u8 uncompressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_UNCOMPRESSED);
+  u8 compressed_size = location.get_attribute(ImageLocation::ATTRIBUTE_COMPRESSED);
+  // If the resource is compressed.
+  if (compressed_size != 0) {
+    u1* compressed_data;
+    // If not memory mapped read in bytes.
+    if (!MemoryMapImage) {
+      // Allocate buffer for compression.
+      compressed_data = new u1[(u4)compressed_size];
+      // Read bytes from offset beyond the image index.
+      bool is_read = read_at(compressed_data, compressed_size, _index_size + offset);
+      assert(is_read && "error reading from image or short read");
+    } else {
+      compressed_data = get_data_address() + offset;
+    }
+    // Get image string table.
+    const ImageStrings strings = get_strings();
+    // Decompress resource.
+    ImageDecompressor::decompress_resource(compressed_data, uncompressed_data, (u4)uncompressed_size,
+            &strings);
+    // If not memory mapped then release temporary buffer.
+    if (!MemoryMapImage) {
+        delete compressed_data;
+    }
+  } else {
+    // Read bytes from offset beyond the image index.
+    bool is_read = read_at(uncompressed_data, uncompressed_size, _index_size + offset);
+    assert(is_read && "error reading from image or short read");
+  }
+}
+
+// Return the ImageModuleData for this image
+ImageModuleData * ImageFileReader::get_image_module_data() {
+    return module_data;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libjimage/imageFile.hpp	Tue Sep 08 16:10:36 2015 +0200
@@ -0,0 +1,648 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef LIBJIMAGE_IMAGEFILE_HPP
+#define LIBJIMAGE_IMAGEFILE_HPP
+
+#include <assert.h>
+
+#include "endian.hpp"
+#include "inttypes.hpp"
+
+// Image files are an alternate file format for storing classes and resources. The
+// goal is to supply file access which is faster and smaller than the jar format.
+// It should be noted that unlike jars, information stored in an image is in native
+// endian format. This allows the image to be mapped into memory without endian
+// translation.  This also means that images are platform dependent.
+//
+// Image files are structured as three sections;
+//
+//         +-----------+
+//         |  Header   |
+//         +-----------+
+//         |           |
+//         |   Index   |
+//         |           |
+//         +-----------+
+//         |           |
+//         |           |
+//         | Resources |
+//         |           |
+//         |           |
+//         +-----------+
+//
+// The header contains information related to identification and description of
+// contents.
+//
+//         +-------------------------+
+//         |   Magic (0xCAFEDADA)    |
+//         +------------+------------+
+//         | Major Vers | Minor Vers |
+//         +------------+------------+
+//         |          Flags          |
+//         +-------------------------+
+//         |      Resource Count     |
+//         +-------------------------+
+//         |       Table Length      |
+//         +-------------------------+
+//         |      Attributes Size    |
+//         +-------------------------+
+//         |       Strings Size      |
+//         +-------------------------+
+//
+// Magic - means of identifying validity of the file.  This avoids requiring a
+//         special file extension.
+// Major vers, minor vers - differences in version numbers indicate structural
+//                          changes in the image.
+// Flags - various image wide flags (future).
+// Resource count - number of resources in the file.
+// Table length - the length of lookup tables used in the index.
+// Attributes size - number of bytes in the region used to store location attribute
+//                   streams.
+// Strings size - the size of the region used to store strings used by the
+//                index and meta data.
+//
+// The index contains information related to resource lookup. The algorithm
+// used for lookup is "A Practical Minimal Perfect Hashing Method"
+// (http://homepages.dcc.ufmg.br/~nivio/papers/wea05.pdf). Given a path string
+// in the form /<module>/<package>/<base>.<extension>  return the resource location
+// information;
+//
+//     redirectIndex = hash(path, DEFAULT_SEED) % table_length;
+//     redirect = redirectTable[redirectIndex];
+//     if (redirect == 0) return not found;
+//     locationIndex = redirect < 0 ? -1 - redirect : hash(path, redirect) % table_length;
+//     location = locationTable[locationIndex];
+//     if (!verify(location, path)) return not found;
+//     return location;
+//
+// Note: The hash function takes an initial seed value.  A different seed value
+// usually returns a different result for strings that would otherwise collide with
+// other seeds. The verify function guarantees the found resource location is
+// indeed the resource we are looking for.
+//
+// The following is the format of the index;
+//
+//         +-------------------+
+//         |   Redirect Table  |
+//         +-------------------+
+//         | Attribute Offsets |
+//         +-------------------+
+//         |   Attribute Data  |
+//         +-------------------+
+//         |      Strings      |
+//         +-------------------+
+//
+// Redirect Table - Array of 32-bit signed values representing actions that
+//                  should take place for hashed strings that map to that
+//                  value.  Negative values indicate no hash collision and can be
+//                  quickly converted to indices into attribute offsets.  Positive
+//                  values represent a new seed for hashing an index into attribute
+//                  offsets.  Zero indicates not found.
+// Attribute Offsets - Array of 32-bit unsigned values representing offsets into
+//                     attribute data.  Attribute offsets can be iterated to do a
+//                     full survey of resources in the image.  Offset of zero
+//                     indicates no attributes.
+// Attribute Data - Bytes representing compact attribute data for locations. (See
+//                  comments in ImageLocation.)
+// Strings - Collection of zero terminated UTF-8 strings used by the index and
+//           image meta data.  Each string is accessed by offset.  Each string is
+//           unique.  Offset zero is reserved for the empty string.
+//
+// Note that the memory mapped index assumes 32 bit alignment of each component
+// in the index.
+//
+// Endianness of an image.
+// An image booted by hotspot is always in native endian.  However, it is possible
+// to read (by the JDK) in alternate endian format.  Primarily, this is during
+// cross platform scenarios.  Ex, where javac needs to read an embedded image
+// to access classes for crossing compilation.
+//
+
+class ImageFileReader; // forward declaration
+
+// Manage image file string table.
+class ImageStrings {
+private:
+  u1* _data; // Data bytes for strings.
+  u4 _size; // Number of bytes in the string table.
+public:
+  enum {
+    // Not found result from find routine.
+    NOT_FOUND = -1,
+    // Prime used to generate hash for Perfect Hashing.
+    HASH_MULTIPLIER = 0x01000193
+  };
+
+  ImageStrings(u1* data, u4 size) : _data(data), _size(size) {}
+
+  // Return the UTF-8 string beginning at offset.
+  inline const char* get(u4 offset) const {
+    assert(offset < _size && "offset exceeds string table size");
+    return (const char*)(_data + offset);
+  }
+
+  // Compute the Perfect Hashing hash code for the supplied UTF-8 string.
+  inline static u4 hash_code(const char* string) {
+    return hash_code(string, HASH_MULTIPLIER);
+  }
+
+  // Compute the Perfect Hashing hash code for the supplied string, starting at seed.
+  static s4 hash_code(const char* string, s4 seed);
+
+  // Match up a string in a perfect hash table.  Result still needs validation
+  // for precise match.
+  static s4 find(Endian* endian, const char* name, s4* redirect, u4 length);
+
+  // Test to see if UTF-8 string begins with the start UTF-8 string.  If so,
+  // return non-NULL address of remaining portion of string.  Otherwise, return
+  // NULL.  Used to test sections of a path without copying from image string
+  // table.
+  static const char* starts_with(const char* string, const char* start);
+
+  // Test to see if UTF-8 string begins with start char.  If so, return non-NULL
+  // address of remaining portion of string.  Otherwise, return NULL.  Used
+  // to test a character of a path without copying.
+  inline static const char* starts_with(const char* string, const char ch) {
+    return *string == ch ? string + 1 : NULL;
+  }
+};
+
+// Manage image file location attribute data.  Within an image, a location's
+// attributes are compressed into a stream of bytes.  An attribute stream is
+// composed of individual attribute sequences.  Each attribute sequence begins with
+// a header byte containing the attribute 'kind' (upper 5 bits of header) and the
+// 'length' less 1 (lower 3 bits of header) of bytes that follow containing the
+// attribute value.  Attribute values present as most significant byte first.
+//
+// Ex. Container offset (ATTRIBUTE_OFFSET) 0x33562 would be represented as 0x22
+// (kind = 4, length = 3), 0x03, 0x35, 0x62.
+//
+// An attribute stream is terminated with a header kind of ATTRIBUTE_END (header
+// byte of zero.)
+//
+// ImageLocation inflates the stream into individual values stored in the long
+// array _attributes. This allows an attribute value can be quickly accessed by
+// direct indexing. Unspecified values default to zero.
+//
+// Notes:
+//  - Even though ATTRIBUTE_END is used to mark the end of the attribute stream,
+//    streams will contain zero byte values to represent lesser significant bits.
+//    Thus, detecting a zero byte is not sufficient to detect the end of an attribute
+//    stream.
+//  - ATTRIBUTE_OFFSET represents the number of bytes from the beginning of the region
+//    storing the resources.  Thus, in an image this represents the number of bytes
+//    after the index.
+//  - Currently, compressed resources are represented by having a non-zero
+//    ATTRIBUTE_COMPRESSED value.  This represents the number of bytes stored in the
+//    image, and the value of ATTRIBUTE_UNCOMPRESSED represents number of bytes of the
+//    inflated resource in memory. If the ATTRIBUTE_COMPRESSED is zero then the value
+//    of ATTRIBUTE_UNCOMPRESSED represents both the number of bytes in the image and
+//    in memory.  In the future, additional compression techniques will be used and
+//    represented differently.
+//  - Package strings include trailing slash and extensions include prefix period.
+//
+class ImageLocation {
+public:
+  enum {
+    ATTRIBUTE_END,          // End of attribute stream marker
+    ATTRIBUTE_MODULE,       // String table offset of module name
+    ATTRIBUTE_PARENT,       // String table offset of resource path parent
+    ATTRIBUTE_BASE,         // String table offset of resource path base
+    ATTRIBUTE_EXTENSION,    // String table offset of resource path extension
+    ATTRIBUTE_OFFSET,       // Container byte offset of resource
+    ATTRIBUTE_COMPRESSED,   // In image byte size of the compressed resource
+    ATTRIBUTE_UNCOMPRESSED, // In memory byte size of the uncompressed resource
+    ATTRIBUTE_COUNT         // Number of attribute kinds
+  };
+
+private:
+  // Values of inflated attributes.
+  u8 _attributes[ATTRIBUTE_COUNT];
+
+  // Return the attribute value number of bytes.
+  inline static u1 attribute_length(u1 data) {
+    return (data & 0x7) + 1;
+  }
+
+  // Return the attribute kind.
+  inline static u1 attribute_kind(u1 data) {
+    u1 kind = data >> 3;
+    assert(kind < ATTRIBUTE_COUNT && "invalid attribute kind");
+    return kind;
+  }
+
+  // Return the attribute length.
+  inline static u8 attribute_value(u1* data, u1 n) {
+    assert(0 < n && n <= 8 && "invalid attribute value length");
+    u8 value = 0;
+    // Most significant bytes first.
+    for (u1 i = 0; i < n; i++) {
+      value <<= 8;
+      value |= data[i];
+    }
+    return value;
+  }
+
+public:
+  ImageLocation() {
+    clear_data();
+  }
+
+  ImageLocation(u1* data) {
+    clear_data();
+    set_data(data);
+  }
+
+  // Inflates the attribute stream into individual values stored in the long
+  // array _attributes. This allows an attribute value to be quickly accessed by
+  // direct indexing. Unspecified values default to zero.
+  void set_data(u1* data);
+
+  // Zero all attribute values.
+  void clear_data();
+
+  // Retrieve an attribute value from the inflated array.
+  inline u8 get_attribute(u1 kind) const {
+    assert(ATTRIBUTE_END < kind && kind < ATTRIBUTE_COUNT && "invalid attribute kind");
+    return _attributes[kind];
+  }
+
+  // Retrieve an attribute string value from the inflated array.
+  inline const char* get_attribute(u4 kind, const ImageStrings& strings) const {
+    return strings.get((u4)get_attribute(kind));
+  }
+};
+
+//
+// NOTE: needs revision.
+// Each loader requires set of module meta data to identify which modules and
+// packages are managed by that loader.  Currently, there is one image file per
+// builtin loader, so only one  module meta data resource per file.
+//
+// Each element in the module meta data is a native endian 4 byte integer.  Note
+// that entries with zero offsets for string table entries should be ignored (
+// padding for hash table lookup.)
+//
+// Format:
+//    Count of package to module entries
+//    Count of module to package entries
+//    Perfect Hash redirect table[Count of package to module entries]
+//    Package to module entries[Count of package to module entries]
+//        Offset to package name in string table
+//        Offset to module name in string table
+//    Perfect Hash redirect table[Count of module to package entries]
+//    Module to package entries[Count of module to package entries]
+//        Offset to module name in string table
+//        Count of packages in module
+//        Offset to first package in packages table
+//    Packages[]
+//        Offset to package name in string table
+//
+// Manage the image module meta data.
+class ImageModuleData {
+  class Header {
+  private:
+    u4 _ptm_count;      // Count of package to module entries
+    u4 _mtp_count;      // Count of module to package entries
+  public:
+    inline u4 ptm_count(Endian* endian) const { return endian->get(_ptm_count); }
+    inline u4 mtp_count(Endian* endian) const { return endian->get(_mtp_count); }
+  };
+
+  // Hashtable entry
+  class HashData {
+  private:
+    u4 _name_offset;    // Name offset in string table
+  public:
+    inline s4 name_offset(Endian* endian) const { return endian->get(_name_offset); }
+  };
+
+  // Package to module hashtable entry
+  class PTMData : public HashData {
+  private:
+    u4 _module_name_offset; // Module name offset in string table
+  public:
+    inline s4 module_name_offset(Endian* endian) const { return endian->get(_module_name_offset); }
+  };
+
+  // Module to package hashtable entry
+  class MTPData : public HashData {
+  private:
+    u4 _package_count;     // Number of packages in module
+    u4 _package_offset;    // Offset in package list
+  public:
+    inline u4 package_count(Endian* endian)  const { return endian->get(_package_count); }
+    inline u4 package_offset(Endian* endian) const { return endian->get(_package_offset); }
+  };
+
+  const ImageFileReader* _image_file; // Source image file
+  Endian* _endian;                    // Endian handler
+  ImageStrings _strings;              // Image file strings
+  u1* _data;                          // Module data resource data
+  u8 _data_size;                      // Size of resource data
+  Header* _header;                    // Module data header
+  s4* _ptm_redirect;                  // Package to module hashtable redirect
+  PTMData* _ptm_data;                 // Package to module data
+  s4* _mtp_redirect;                  // Module to packages hashtable redirect
+  MTPData* _mtp_data;                 // Module to packages data
+  s4* _mtp_packages;                  // Package data (name offsets)
+
+  // Return a string from the string table.
+  inline const char* get_string(u4 offset) {
+    return _strings.get(offset);
+  }
+
+  inline u4 mtp_package(u4 index) {
+    return _endian->get(_mtp_packages[index]);
+  }
+
+public:
+  ImageModuleData(const ImageFileReader* image_file, const char* module_data_name);
+  ~ImageModuleData();
+
+  // Return the name of the module data resource.
+  static void module_data_name(char* buffer, const char* image_file_name);
+
+  // Return the module in which a package resides.  Returns NULL if not found.
+  const char* package_to_module(const char* package_name);
+
+  // Returns all the package names in a module in a NULL terminated array.
+  // Returns NULL if module not found.
+  const char** module_to_packages(const char* module_name);
+};
+
+// Image file header, starting at offset 0.
+class ImageHeader {
+private:
+  u4 _magic;           // Image file marker
+  u4 _version;         // Image file major version number
+  u4 _flags;           // Image file flags
+  u4 _resource_count;  // Number of resources in file
+  u4 _table_length;    // Number of slots in index tables
+  u4 _locations_size;  // Number of bytes in attribute table
+  u4 _strings_size;    // Number of bytes in string table
+
+public:
+  u4 magic() const { return _magic; }
+  u4 magic(Endian* endian) const { return endian->get(_magic); }
+  void set_magic(Endian* endian, u4 magic) { return endian->set(_magic, magic); }
+
+  u4 major_version(Endian* endian) const { return endian->get(_version) >> 16; }
+  u4 minor_version(Endian* endian) const { return endian->get(_version) & 0xFFFF; }
+  void set_version(Endian* endian, u4 major_version, u4 minor_version) {
+    return endian->set(_version, major_version << 16 | minor_version);
+  }
+
+  u4 flags(Endian* endian) const { return endian->get(_flags); }
+  void set_flags(Endian* endian, u4 value) { return endian->set(_flags, value); }
+
+  u4 resource_count(Endian* endian) const { return endian->get(_resource_count); }
+  void set_resource_count(Endian* endian, u4 count) { return endian->set(_resource_count, count); }
+
+  u4 table_length(Endian* endian) const { return endian->get(_table_length); }
+  void set_table_length(Endian* endian, u4 count) { return endian->set(_table_length, count); }
+
+  u4 locations_size(Endian* endian) const { return endian->get(_locations_size); }
+  void set_locations_size(Endian* endian, u4 size) { return endian->set(_locations_size, size); }
+
+  u4 strings_size(Endian* endian) const { return endian->get(_strings_size); }
+  void set_strings_size(Endian* endian, u4 size) { return endian->set(_strings_size, size); }
+};
+
+// Max path length limit independent of platform.  Windows max path is 1024,
+// other platforms use 4096.  The JCK fails several tests when 1024 is used.
+#define IMAGE_MAX_PATH 4096
+
+class ImageFileReader;
+
+// Manage a table of open image files.  This table allows multiple access points
+// to share an open image.
+class ImageFileReaderTable {
+private:
+  const static u4 _growth = 8;   // Growth rate of the table
+  u4 _count;                     // Number of entries in the table
+  u4 _max;                       // Maximum number of entries allocated
+  ImageFileReader** _table;      // Growable array of entries
+
+public:
+  ImageFileReaderTable();
+  ~ImageFileReaderTable();
+
+  // Return the number of entries.
+  inline u4 count() { return _count; }
+
+  // Return the ith entry from the table.
+  inline ImageFileReader* get(u4 i) { return _table[i]; }
+
+  // Add a new image entry to the table.
+  void add(ImageFileReader* image);
+
+  // Remove an image entry from the table.
+  void remove(ImageFileReader* image);
+
+  // Determine if image entry is in table.
+  bool contains(ImageFileReader* image);
+};
+
+// Manage the image file.
+// ImageFileReader manages the content of an image file.
+// Initially, the header of the image file is read for validation.  If valid,
+// values in the header are used calculate the size of the image index.  The
+// index is then memory mapped to allow load on demand and sharing.  The
+// -XX:+MemoryMapImage flag determines if the entire file is loaded (server use.)
+// An image can be used by Hotspot and multiple reference points in the JDK, thus
+// it is desirable to share a reader.  To accomodate sharing, a share table is
+// defined (see ImageFileReaderTable in imageFile.cpp)  To track the number of
+// uses, ImageFileReader keeps a use count (_use).  Use is incremented when
+// 'opened' by reference point and decremented when 'closed'.  Use of zero
+// leads the ImageFileReader to be actually closed and discarded.
+class ImageFileReader {
+private:
+  // Manage a number of image files such that an image can be shared across
+  // multiple uses (ex. loader.)
+  static ImageFileReaderTable _reader_table;
+
+  char* _name;         // Name of image
+  s4 _use;             // Use count
+  int _fd;             // File descriptor
+  Endian* _endian;     // Endian handler
+  u8 _file_size;       // File size in bytes
+  ImageHeader _header; // Image header
+  size_t _index_size;  // Total size of index
+  u1* _index_data;     // Raw index data
+  s4* _redirect_table; // Perfect hash redirect table
+  u4* _offsets_table;  // Location offset table
+  u1* _location_bytes; // Location attributes
+  u1* _string_bytes;   // String table
+  ImageModuleData *module_data;   // The ImageModuleData for this image
+
+  ImageFileReader(const char* name, bool big_endian);
+  ~ImageFileReader();
+
+  // Compute number of bytes in image file index.
+  inline size_t index_size() {
+    return sizeof(ImageHeader) +
+      table_length() * sizeof(u4) * 2 + locations_size() + strings_size();
+  }
+
+public:
+  enum {
+    // Image file marker.
+    IMAGE_MAGIC = 0xCAFEDADA,
+    // Endian inverted Image file marker.
+    IMAGE_MAGIC_INVERT = 0xDADAFECA,
+    // Image file major version number.
+    MAJOR_VERSION = 1,
+    // Image file minor version number.
+    MINOR_VERSION = 0
+  };
+
+  // Open an image file, reuse structure if file already open.
+  static ImageFileReader* open(const char* name, bool big_endian = Endian::is_big_endian());
+
+  // Close an image file if the file is not in use elsewhere.
+  static void close(ImageFileReader *reader);
+
+  // Return an id for the specifed ImageFileReader.
+  static u8 readerToID(ImageFileReader *reader);
+
+  // Validate the image id.
+  static bool idCheck(u8 id);
+
+  // Return an id for the specifed ImageFileReader.
+  static ImageFileReader* idToReader(u8 id);
+
+  // Open image file for read access.
+  bool open();
+
+  // Close image file.
+  void close();
+
+  // Read directly from the file.
+  bool read_at(u1* data, u8 size, u8 offset) const;
+
+  inline Endian* endian() const { return _endian; }
+
+  // Retrieve name of image file.
+  inline const char* name() const {
+    return _name;
+  }
+
+  // Retrieve size of image file.
+  inline u8 file_size() const {
+    return _file_size;
+  }
+
+  // Return first address of index data.
+  inline u1* get_index_address() const {
+    return _index_data;
+  }
+
+  // Return first address of resource data.
+  inline u1* get_data_address() const {
+    return _index_data + _index_size;
+  }
+
+  // Get the size of the index data.
+  size_t get_index_size() const {
+    return _index_size;
+  }
+
+  inline u4 table_length() const {
+    return _header.table_length(_endian);
+  }
+
+  inline u4 locations_size() const {
+    return _header.locations_size(_endian);
+  }
+
+  inline u4 strings_size()const  {
+    return _header.strings_size(_endian);
+  }
+
+  inline u4* offsets_table() const {
+    return _offsets_table;
+  }
+
+  // Increment use count.
+  inline void inc_use() {
+    _use++;
+  }
+
+  // Decrement use count.
+  inline bool dec_use() {
+    return --_use == 0;
+  }
+
+  // Return a string table accessor.
+  inline const ImageStrings get_strings() const {
+    return ImageStrings(_string_bytes, _header.strings_size(_endian));
+  }
+
+  // Return location attribute stream at offset.
+  inline u1* get_location_offset_data(u4 offset) const {
+    assert((u4)offset < _header.locations_size(_endian) &&
+              "offset exceeds location attributes size");
+    return offset != 0 ? _location_bytes + offset : NULL;
+  }
+
+  // Return location attribute stream for location i.
+  inline u1* get_location_data(u4 index) const {
+    return get_location_offset_data(get_location_offset(index));
+  }
+
+  // Return the location offset for index.
+  inline u4 get_location_offset(u4 index) const {
+    assert((u4)index < _header.table_length(_endian) &&
+              "index exceeds location count");
+    return _endian->get(_offsets_table[index]);
+  }
+
+  // Find the location attributes associated with the path.  Returns true if
+  // the location is found, false otherwise.
+  bool find_location(const char* path, ImageLocation& location) const;
+
+  // Find the location index and size associated with the path.
+  // Returns the location index and size if the location is found,
+  // ImageFileReader::NOT_FOUND otherwise.
+  u4 find_location_index(const char* path, u8 *size) const;
+
+  // Assemble the location path.
+  void location_path(ImageLocation& location, char* path, size_t max) const;
+
+  // Verify that a found location matches the supplied path.
+  bool verify_location(ImageLocation& location, const char* path) const;
+
+  // Return the resource for the supplied location index.
+  void get_resource(u4 index, u1* uncompressed_data) const;
+
+  // Return the resource for the supplied path.
+  void get_resource(ImageLocation& location, u1* uncompressed_data) const;
+
+  // Return the ImageModuleData for this image
+  ImageModuleData * get_image_module_data();
+
+};
+#endif // LIBJIMAGE_IMAGEFILE_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libjimage/inttypes.hpp	Tue Sep 08 16:10:36 2015 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef LIBJIMAGE_INTTYPES_HPP
+#define LIBJIMAGE_INTTYPES_HPP
+
+typedef unsigned char      u1;
+typedef          char      s1;
+typedef unsigned short     u2;
+typedef          short     s2;
+typedef unsigned int       u4;
+typedef          int       s4;
+#ifdef LP64
+typedef unsigned long      u8;
+typedef          long      s8;
+#else
+typedef unsigned long long u8;
+typedef          long long s8;
+#endif
+
+#endif // LIBJIMAGE_INTTYPES_HPP
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libjimage/jimage.cpp	Tue Sep 08 16:10:36 2015 +0200
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include <string.h>
+
+#include "jimage.hpp"
+
+#include "imageFile.hpp"
+
+#define BOOT_VERSION "9.0"
+
+/*
+ * JImageOpen - Given the supplied full path file name, open an image file. This
+ * function will also initialize tables and retrieve meta-data necessary to
+ * satisfy other functions in the API. If the image file has been previously
+ * open, a new open request will share memory and resources used by the previous
+ * open. A call to JImageOpen should be balanced by a call to JImageClose, to
+ * release memory and resources used. If the image file is not found or cannot
+ * be open, then NULL is returned and error will contain a reason for the
+ * failure; a positive value for a system error number, negative for a jimage
+ * specific error (see JImage Error Codes.)
+ *
+ *  Ex.
+ *   jint error;
+ *   JImageFile* jimage = (*JImageOpen)(JAVA_HOME "lib/modules/bootmodules.jimage", &error);
+ *   if (image == NULL) {
+ *     tty->print_cr("JImage failed to open: %d", error);
+ *     ...
+ *   }
+ *   ...
+ */
+extern "C" JImageFile* JIMAGE_Open(const char *name, jint* error) {
+    // TODO - return a meaningful error code
+    *error = 0;
+    ImageFileReader* jfile = ImageFileReader::open(name);
+    return (JImageFile*) jfile;
+}
+
+/*
+ * JImageClose - Given the supplied open image file (see JImageOpen), release
+ * memory and resources used by the open file and close the file. If the image
+ * file is shared by other uses, release and close is deferred until the last use
+ * is also closed.
+ *
+ * Ex.
+ *  (*JImageClose)(image);
+ */
+extern "C" void JIMAGE_Close(JImageFile* image) {
+    ImageFileReader::close((ImageFileReader*) image);
+}
+
+/*
+ * JImagePackageToModule - Given an open image file (see JImageOpen) and the name
+ * of a package, return the name of module where the package resides. If the
+ * package does not exist in the image file, the function returns NULL.
+ * The resulting string does/should not have to be released. All strings are
+ * utf-8, zero byte terminated.
+ *
+ * Ex.
+ *  const char* package = (*JImagePackageToModule)(image, "java/lang");
+ *  tty->print_cr(package);
+ *  —> java.base
+ */
+extern "C" const char* JIMAGE_PackageToModule(JImageFile* image, const char* package_name) {
+    return ((ImageFileReader*) image)->get_image_module_data()->package_to_module(package_name);
+}
+
+/*
+ * JImageFindResource - Given an open image file (see JImageOpen), a module
+ * name, a version string and the name of a class/resource, return location
+ * information describing the resource and its size. If no resource is found, the
+ * function returns JIMAGE_NOT_FOUND and the value of size is undefined.
+ * The version number should be "9.0" and is not used in locating the resource.
+ * The resulting location does/should not have to be released.
+ * All strings are utf-8, zero byte terminated.
+ *
+ *  Ex.
+ *   jlong size;
+ *   JImageLocationRef location = (*JImageFindResource)(image, "java.base", "9.0", "java/lang/String.class", &size);
+ */
+extern "C" JImageLocationRef JIMAGE_FindResource(JImageFile* image,
+        const char* module_name, const char* version, const char* name,
+        jlong* size) {
+    if (strcmp(version, BOOT_VERSION) != 0) {
+        return (JImageLocationRef) 0;
+    }
+
+    ImageLocation location;
+    char fullpath[IMAGE_MAX_PATH];
+
+    // Concatenate to get full path
+    strncpy(fullpath, "/", IMAGE_MAX_PATH - 1);
+    strncat(fullpath, module_name, IMAGE_MAX_PATH - 1);
+    strncat(fullpath, "/", IMAGE_MAX_PATH - 1);
+    strncat(fullpath, name, IMAGE_MAX_PATH - 1);
+    JImageLocationRef loc =
+            (JImageLocationRef) ((ImageFileReader*) image)->find_location_index(fullpath, (u8*) size);
+    return loc;
+}
+
+/*
+ * JImageGetResource - Given an open image file (see JImageOpen), a resource’s
+ * location information (see JImageFindResource), a buffer of appropriate
+ * size and the size, retrieve the bytes associated with the
+ * resource. If the size is less than the resource size then the read is truncated.
+ * If the size is greater than the resource size then the remainder of the buffer
+ * is zero filled.  The function will return the actual size of the resource.
+ *
+ * Ex.
+ *  jlong size;
+ *  JImageLocationRef* location = (*JImageFindResource)(image, "java.base", "9.0", "java/lang/String.class", &size);
+ *  char* buffer = new char[size];
+ *  (*JImageGetResource)(image, location, buffer, size);
+ */
+extern "C" jlong JIMAGE_GetResource(JImageFile* image, JImageLocationRef location,
+        char* buffer, jlong size) {
+    ((ImageFileReader*) image)->get_resource((u4) location, (u1*) buffer);
+    return size;
+}
+
+/*
+ * JImageResourceIterator - Given an open image file (see JImageOpen), a visitor
+ * function and a visitor argument, iterator through each of the image's resources.
+ * The visitor function is called with the image file, the module name, the
+ * package name, the base name, the extension and the visitor argument. The return
+ * value of the visitor function should be true, unless an early iteration exit is
+ * required. All strings are utf-8, zero byte terminated.file.
+ *
+ * Ex.
+ *   bool ctw_visitor(JImageFile* jimage, const char* module_name, const char* version, const char* package, const char* name, const char* extension, void* arg) {
+ *     if (strcmp(extension, “class”) == 0) {
+ *       char path[JIMAGE_MAX_PATH];
+ *       Thread* THREAD = Thread::current();
+ *       jio_snprintf(path, JIMAGE_MAX_PATH - 1, "/%s/%s", package, name);
+ *       ClassLoader::compile_the_world_in(path, (Handle)arg, THREAD);
+ *       return !HAS_PENDING_EXCEPTION;
+ *     }
+ *     return true;
+ *   }
+ *   (*JImageResourceIterator)(image, ctw_visitor, loader);
+ */
+extern "C" void JIMAGE_ResourceIterator(JImageFile* image,
+        JImageResourceVisitor_t visitor, void* arg) {
+    ImageFileReader* imageFile = (ImageFileReader*) image;
+    u4 nEntries = imageFile->table_length();
+    const ImageStrings strings = imageFile->get_strings();
+    for (u4 i = 0; i < nEntries; i++) {
+        ImageLocation location(imageFile->get_location_data(i));
+
+        u4 moduleOffset = (u4) location.get_attribute(ImageLocation::ATTRIBUTE_MODULE);
+        if (moduleOffset == 0) {
+            continue; // skip non-modules
+        }
+        const char *module = strings.get(moduleOffset);
+        if (strcmp(module, "modules") == 0
+            || strcmp(module, "packages") == 0) {
+            continue; // always skip
+        }
+
+        u4 parentOffset = (u4) location.get_attribute(ImageLocation::ATTRIBUTE_PARENT);
+        const char *parent = strings.get(parentOffset);
+        u4 baseOffset = (u4) location.get_attribute(ImageLocation::ATTRIBUTE_BASE);
+        const char *base = strings.get(baseOffset);
+        u4 extOffset = (u4) location.get_attribute(ImageLocation::ATTRIBUTE_EXTENSION);
+        const char *extension = strings.get(extOffset);
+
+        if (!(*visitor)(image, module, "9", parent, base, extension, arg)) {
+            break;
+        }
+
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libjimage/jimage.hpp	Tue Sep 08 16:10:36 2015 +0200
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "jni.h"
+
+// Opaque reference to a JImage file.
+class JImageFile;
+// Opaque reference to an image file resource location.
+typedef jlong JImageLocationRef;
+
+// Max path length limit independent of platform.  Windows max path is 1024,
+// other platforms use 4096.  The JCK fails several tests when 1024 is used.
+#define JIMAGE_MAX_PATH 4096
+
+// JImage Error Codes
+
+// The image file is not prefixed with 0xCAFEDADA
+#define JIMAGE_BAD_MAGIC (-1)
+// The image file does not have a compatible (translatable) version
+#define JIMAGE_BAD_VERSION (-2)
+// The image file content is malformed
+#define JIMAGE_CORRUPTED (-3)
+
+/*
+ * JImageOpen - Given the supplied full path file name, open an image file. This
+ * function will also initialize tables and retrieve meta-data necessary to
+ * satisfy other functions in the API. If the image file has been previously
+ * open, a new open request will share memory and resources used by the previous
+ * open. A call to JImageOpen should be balanced by a call to JImageClose, to
+ * release memory and resources used. If the image file is not found or cannot
+ * be open, then NULL is returned and error will contain a reason for the
+ * failure; a positive value for a system error number, negative for a jimage
+ * specific error (see JImage Error Codes.)
+ *
+ *  Ex.
+ *   jint error;
+ *   JImageFile* jimage = (*JImageOpen)(JAVA_HOME "lib/modules/bootmodules.jimage", &error);
+ *   if (image == NULL) {
+ *     tty->print_cr("JImage failed to open: %d", error);
+ *     ...
+ *   }
+ *   ...
+ */
+
+extern "C" JImageFile* JIMAGE_Open(const char *name, jint* error);
+
+typedef JImageFile* (*JImageOpen_t)(const char *name, jint* error);
+
+/*
+ * JImageClose - Given the supplied open image file (see JImageOpen), release
+ * memory and resources used by the open file and close the file. If the image
+ * file is shared by other uses, release and close is deferred until the last use
+ * is also closed.
+ *
+ * Ex.
+ *  (*JImageClose)(image);
+ */
+
+extern "C" void JIMAGE_Close(JImageFile* jimage);
+
+typedef void (*JImageClose_t)(JImageFile* jimage);
+
+
+/*
+ * JImagePackageToModule - Given an open image file (see JImageOpen) and the name
+ * of a package, return the name of module where the package resides. If the
+ * package does not exist in the image file, the function returns NULL.
+ * The resulting string does/should not have to be released. All strings are
+ * utf-8, zero byte terminated.
+ *
+ * Ex.
+ *  const char* package = (*JImagePackageToModule)(image, "java/lang");
+ *  tty->print_cr(package);
+ *  —> java.base
+ */
+
+extern "C" const char * JIMAGE_PackageToModule(JImageFile* jimage, const char* package_name);
+
+typedef const char* (*JImagePackageToModule_t)(JImageFile* jimage, const char* package_name);
+
+
+/*
+ * JImageFindResource - Given an open image file (see JImageOpen), a module
+ * name, a version string and the name of a class/resource, return location
+ * information describing the resource and its size. If no resource is found, the
+ * function returns JIMAGE_NOT_FOUND and the value of size is undefined.
+ * The version number should be "9.0" and is not used in locating the resource.
+ * The resulting location does/should not have to be released.
+ * All strings are utf-8, zero byte terminated.
+ *
+ *  Ex.
+ *   jlong size;
+ *   JImageLocationRef location = (*JImageFindResource)(image, "java.base", "9.0", "java/lang/String.class", &size);
+ */
+extern "C" JImageLocationRef JIMAGE_FindResource(JImageFile* jimage,
+        const char* module_name, const char* version, const char* name,
+        jlong* size);
+
+typedef JImageLocationRef(*JImageFindResource_t)(JImageFile* jimage,
+        const char* module_name, const char* version, const char* name,
+        jlong* size);
+
+
+/*
+ * JImageGetResource - Given an open image file (see JImageOpen), a resource’s
+ * location information (see JImageFindResource), a buffer of appropriate
+ * size and the size, retrieve the bytes associated with the
+ * resource. If the size is less than the resource size then the read is truncated.
+ * If the size is greater than the resource size then the remainder of the buffer
+ * is zero filled.  The function will return the actual size of the resource.
+ *
+ * Ex.
+ *  jlong size;
+ *  JImageLocationRef location = (*JImageFindResource)(image, "java.base", "9.0", "java/lang/String.class", &size);
+ *  char* buffer = new char[size];
+ *  (*JImageGetResource)(image, location, buffer, size);
+ */
+extern "C" jlong JIMAGE_GetResource(JImageFile* jimage, JImageLocationRef location,
+        char* buffer, jlong size);
+
+typedef jlong(*JImageGetResource_t)(JImageFile* jimage, JImageLocationRef location,
+        char* buffer, jlong size);
+
+
+/*
+ * JImageResourceIterator - Given an open image file (see JImageOpen), a visitor
+ * function and a visitor argument, iterator through each of the image's resources.
+ * The visitor function is called with the image file, the module name, the
+ * package name, the base name, the extension and the visitor argument. The return
+ * value of the visitor function should be true, unless an early iteration exit is
+ * required. All strings are utf-8, zero byte terminated.file.
+ *
+ * Ex.
+ *   bool ctw_visitor(JImageFile* jimage, const char* module_name, const char* version, const char* package, const char* name, const char* extension, void* arg) {
+ *     if (strcmp(extension, “class”) == 0) {
+ *       char path[JIMAGE_MAX_PATH];
+ *       Thread* THREAD = Thread::current();
+ *       jio_snprintf(path, JIMAGE_MAX_PATH - 1, "/%s/%s", package, name);
+ *       ClassLoader::compile_the_world_in(path, (Handle)arg, THREAD);
+ *       return !HAS_PENDING_EXCEPTION;
+ *     }
+ *     return true;
+ *   }
+ *   (*JImageResourceIterator)(image, ctw_visitor, loader);
+ */
+
+typedef bool (*JImageResourceVisitor_t)(JImageFile* jimage,
+        const char* module_name, const char* version, const char* package,
+        const char* name, const char* extension, void* arg);
+
+extern "C" void JIMAGE_ResourceIterator(JImageFile* jimage,
+        JImageResourceVisitor_t visitor, void *arg);
+
+typedef void (*JImageResourceIterator_t)(JImageFile* jimage,
+        JImageResourceVisitor_t visitor, void* arg);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/native/libjimage/osSupport.hpp	Tue Sep 08 16:10:36 2015 +0200
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#ifndef LIBJIMAGE_OSSUPPORT_HPP
+#define LIBJIMAGE_OSSUPPORT_HPP
+
+#ifdef WIN32
+#include <Windows.h>
+#else
+#include <pthread.h>
+#endif
+
+class osSupport {
+public:
+    /**
+     * Open a regular file read-only.
+     * Return the file descriptor.
+     */
+    static jint openReadOnly(const char *path);
+
+    /**
+     * Close a file descriptor.
+     */
+    static jint close(jint fd);
+
+    /**
+     * Return the size of a regular file.
+     */
+    static jlong size(const char *path);
+
+    /**
+     * Read nBytes at offset into a buffer.
+     */
+    static jlong read(jint fd, char *buf, jlong nBytes, jlong offset);
+
+    /**
+     * Map nBytes at offset into memory and return the address.
+     * The system chooses the address.
+     */
+    static void* map_memory(jint fd, const char *filename, size_t file_offset, size_t bytes);
+
+    /**
+     * Unmap nBytes of memory at address.
+     */
+    static int unmap_memory(void* addr, size_t bytes);
+};
+
+/**
+ * A CriticalSection to protect a small section of code.
+ */
+class SimpleCriticalSection {
+    friend class SimpleCriticalSectionLock;
+private:
+    void enter();
+    void exit();
+public:
+    SimpleCriticalSection();
+    //~SimpleCriticalSection(); // Cretes a dependency on Solaris on a C++ exit registration
+
+private:
+#ifdef WIN32
+    CRITICAL_SECTION critical_section;
+#else
+    pthread_mutex_t mutex;
+#endif // WIN32
+};
+
+/**
+ * SimpleCriticalSectionLock instance.
+ * The constructor locks a SimpleCriticalSection and the
+ * destructor does the unlock.
+ */
+class SimpleCriticalSectionLock {
+private:
+    SimpleCriticalSection *lock;
+public:
+
+    SimpleCriticalSectionLock(SimpleCriticalSection *cslock) {
+        this->lock = cslock;
+        lock->enter();
+    }
+
+    ~SimpleCriticalSectionLock() {
+        lock->exit();
+    }
+};
+
+#endif  // LIBJIMAGE_OSSUPPORT_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/unix/native/libjimage/osSupport_unix.cpp	Tue Sep 08 16:10:36 2015 +0200
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "jni.h"
+#include "osSupport.hpp"
+
+/**
+ * Open a regular file read-only.
+ * Return the file descriptor.
+ */
+jint osSupport::openReadOnly(const char *path) {
+    return ::open(path, 0);
+}
+
+/**
+ * Close a file descriptor.
+ */
+jint osSupport::close(jint fd) {
+    return ::close(fd);
+}
+
+/**
+ * Return the size of a regular file.
+ */
+jlong osSupport::size(const char *path) {
+    struct stat statbuf;
+    if (stat(path, &statbuf) < 0 ||
+            (statbuf.st_mode & S_IFREG) != S_IFREG) {
+        return -1;
+    }
+    return (jsize) statbuf.st_size;
+}
+
+/**
+ * Read nBytes at offset into a buffer.
+ */
+jlong osSupport::read(jint fd, char *buf, jlong nBytes, jlong offset) {
+    return ::pread(fd, buf, nBytes, offset);
+}
+
+/**
+ * Map nBytes at offset into memory and return the address.
+ * The system chooses the address.
+ */
+void* osSupport::map_memory(int fd, const char *filename, size_t file_offset, size_t bytes) {
+    void* mapped_address = NULL;
+    mapped_address = (void*) mmap(NULL,
+            bytes, PROT_READ, MAP_SHARED,
+            fd, file_offset);
+    if (mapped_address == MAP_FAILED) {
+        return NULL;
+    }
+    return mapped_address;
+}
+
+/**
+ * Unmap nBytes of memory at address.
+ */
+int osSupport::unmap_memory(void *addr, size_t bytes) {
+    return munmap((char *) addr, bytes) == 0;
+}
+
+/**
+ * A CriticalSection to protect a small section of code.
+ */
+void SimpleCriticalSection::enter() {
+    pthread_mutex_lock(&mutex);
+}
+
+void SimpleCriticalSection::exit() {
+    pthread_mutex_unlock(&mutex);
+
+}
+
+SimpleCriticalSection::SimpleCriticalSection() {
+    pthread_mutex_init(&mutex, NULL);
+}
+
+//SimpleCriticalSection::~SimpleCriticalSection() {
+//    pthread_mutex_destroy(&mutex);
+//}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/windows/native/libjimage/osSupport_windows.cpp	Tue Sep 08 16:10:36 2015 +0200
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include <windows.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <io.h>
+#include <malloc.h>
+
+#include "jni.h"
+#include "osSupport.hpp"
+
+/**
+ * Open a regular file read-only.
+ * Return the file descriptor.
+ */
+jint osSupport::openReadOnly(const char *path) {
+    return ::open(path, 0, 0);
+}
+
+/**
+ * Close a file descriptor.
+ */
+jint osSupport::close(jint fd) {
+    return ::close(fd);
+}
+
+/**
+ * Return the size of a regular file.
+ */
+jlong osSupport::size(const char *path) {
+    struct stat statbuf;
+    if (stat(path, &statbuf) < 0 ||
+            (statbuf.st_mode & S_IFREG) != S_IFREG) {
+        return -1;
+    }
+    return (jlong) statbuf.st_size;
+}
+
+/**
+ * Read nBytes at offset into a buffer.
+ */
+jlong osSupport::read(jint fd, char *buf, jlong nBytes, jlong offset) {
+    OVERLAPPED ov;
+    DWORD nread;
+    BOOL result;
+
+    ZeroMemory(&ov, sizeof (ov));
+    ov.Offset = (DWORD) offset;
+    ov.OffsetHigh = (DWORD) (offset >> 32);
+
+    HANDLE h = (HANDLE)::_get_osfhandle(fd);
+
+    result = ReadFile(h, (LPVOID) buf, (DWORD) nBytes, &nread, &ov);
+
+    return result ? nread : 0;
+}
+
+/**
+ * Map nBytes at offset into memory and return the address.
+ * The system chooses the address.
+ */
+void* osSupport::map_memory(jint fd, const char *file_name, size_t file_offset, size_t bytes) {
+    HANDLE hFile;
+    char* base = NULL;
+
+    // Get a handle to the file
+    hFile = CreateFile(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
+            OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (hFile != NULL) {
+        // Create a file mapping handle
+        HANDLE hMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0,
+                NULL /* file_name */);
+        if (hMap != NULL) {
+            // Map the file into the address space at the offset
+            base = (char*) MapViewOfFileEx(hMap, FILE_MAP_READ, 0, (DWORD) file_offset,
+                    (DWORD) bytes, NULL);
+            CloseHandle(hMap); // The mapping is no longer needed
+        }
+        CloseHandle(hFile); // The file handle is no longer needed
+    }
+    return base;
+}
+
+/**
+ * Unmap nBytes of memory at address.
+ */
+int osSupport::unmap_memory(void* addr, size_t bytes) {
+    BOOL result = UnmapViewOfFile(addr);
+    return result;
+}
+
+/**
+ * A CriticalSection to protect a small section of code.
+ */
+void SimpleCriticalSection::enter() {
+    EnterCriticalSection(&critical_section);
+}
+
+void SimpleCriticalSection::exit() {
+    LeaveCriticalSection(&critical_section);
+}
+
+SimpleCriticalSection::SimpleCriticalSection() {
+    InitializeCriticalSection(&critical_section);
+}
+
+//SimpleCriticalSection::~SimpleCriticalSection() {
+//    DeleteCriticalSection(&critical_section);
+//}
+
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/IIOPHelper.java	Thu Sep 03 15:48:24 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,190 +0,0 @@
-/*
- * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.jmx.remote.internal;
-
-import java.util.Properties;
-import java.io.IOException;
-import java.rmi.Remote;
-import java.rmi.NoSuchObjectException;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-/**
- * A helper class for RMI-IIOP and CORBA APIs.
- */
-
-public final class IIOPHelper {
-    private IIOPHelper() { }
-
-    // loads IIOPProxy implementation class if available
-    private static final String IMPL_CLASS =
-        "com.sun.jmx.remote.protocol.iiop.IIOPProxyImpl";
-    private static final IIOPProxy proxy =
-        AccessController.doPrivileged(new PrivilegedAction<IIOPProxy>() {
-            public IIOPProxy run() {
-                try {
-                    Class<?> c = Class.forName(IMPL_CLASS, true,
-                                               IIOPHelper.class.getClassLoader());
-                    return (IIOPProxy)c.newInstance();
-                } catch (ClassNotFoundException cnf) {
-                    return null;
-                } catch (InstantiationException e) {
-                    throw new AssertionError(e);
-                } catch (IllegalAccessException e) {
-                    throw new AssertionError(e);
-                }
-            }});
-
-    /**
-     * Returns true if RMI-IIOP and CORBA is available.
-     */
-    public static boolean isAvailable() {
-        return proxy != null;
-    }
-
-    private static void ensureAvailable() {
-        if (proxy == null)
-            throw new AssertionError("Should not here");
-    }
-
-    /**
-     * Returns true if the given object is a Stub.
-     */
-    public static boolean isStub(Object obj) {
-        return (proxy == null) ? false : proxy.isStub(obj);
-    }
-
-    /**
-     * Returns the Delegate to which the given Stub delegates.
-     */
-    public static Object getDelegate(Object stub) {
-        ensureAvailable();
-        return proxy.getDelegate(stub);
-    }
-
-    /**
-     * Sets the Delegate for a given Stub.
-     */
-    public static void setDelegate(Object stub, Object delegate) {
-        ensureAvailable();
-        proxy.setDelegate(stub, delegate);
-    }
-
-    /**
-     * Returns the ORB associated with the given stub
-     *
-     * @throws  UnsupportedOperationException
-     *          if the object does not support the operation that
-     *          was invoked
-     */
-    public static Object getOrb(Object stub) {
-        ensureAvailable();
-        return proxy.getOrb(stub);
-    }
-
-    /**
-     * Connects the Stub to the given ORB.
-     */
-    public static void connect(Object stub, Object orb)
-        throws IOException
-    {
-        if (proxy == null)
-            throw new IOException("Connection to ORB failed, RMI/IIOP not available");
-        proxy.connect(stub, orb);
-    }
-
-    /**
-     * Returns true if the given object is an ORB.
-     */
-    public static boolean isOrb(Object obj) {
-        return (proxy == null) ? false : proxy.isOrb(obj);
-    }
-
-    /**
-     * Creates, and returns, a new ORB instance.
-     */
-    public static Object createOrb(String[] args, Properties props)
-        throws IOException
-    {
-        if (proxy == null)
-            throw new IOException("ORB initialization failed, RMI/IIOP not available");
-        return proxy.createOrb(args, props);
-    }
-
-    /**
-     * Converts a string, produced by the object_to_string method, back
-     * to a CORBA object reference.
-     */
-    public static Object stringToObject(Object orb, String str) {
-        ensureAvailable();
-        return proxy.stringToObject(orb, str);
-    }
-
-    /**
-     * Converts the given CORBA object reference to a string.
-     */
-    public static String objectToString(Object orb, Object obj) {
-        ensureAvailable();
-        return proxy.objectToString(orb, obj);
-    }
-
-    /**
-     * Checks to ensure that an object of a remote or abstract interface
-     * type can be cast to a desired type.
-     */
-    public static <T> T narrow(Object narrowFrom, Class<T> narrowTo) {
-        ensureAvailable();
-        return proxy.narrow(narrowFrom, narrowTo);
-    }
-
-    /**
-     * Makes a server object ready to receive remote calls
-     */
-    public static void exportObject(Remote obj) throws IOException {
-        if (proxy == null)
-            throw new IOException("RMI object cannot be exported, RMI/IIOP not available");
-        proxy.exportObject(obj);
-    }
-
-    /**
-     * Deregisters a server object from the runtime.
-     */
-    public static void unexportObject(Remote obj) throws IOException {
-        if (proxy == null)
-            throw new NoSuchObjectException("Object not exported");
-        proxy.unexportObject(obj);
-    }
-
-    /**
-     * Returns a stub for the given server object.
-     */
-    public static Remote toStub(Remote obj) throws IOException {
-        if (proxy == null)
-            throw new NoSuchObjectException("Object not exported");
-        return proxy.toStub(obj);
-    }
-}
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/internal/IIOPProxy.java	Thu Sep 03 15:48:24 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,110 +0,0 @@
-/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.jmx.remote.internal;
-
-import java.util.Properties;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.NoSuchObjectException;
-
-/**
- * An interface to a subset of the RMI-IIOP and CORBA APIs to avoid a
- * static dependencies on the types defined by these APIs.
- */
-
-public interface IIOPProxy {
-
-    /**
-     * Returns true if the given object is a Stub.
-     */
-    boolean isStub(Object obj);
-
-    /**
-     * Returns the Delegate to which the given Stub delegates.
-     */
-    Object getDelegate(Object stub);
-
-    /**
-     * Sets the Delegate for a given Stub.
-     */
-    void setDelegate(Object stub, Object delegate);
-
-    /**
-     * Returns the ORB associated with the given stub
-     *
-     * @throws  UnsupportedOperationException
-     *          if the object does not support the operation that
-     *          was invoked
-     */
-    Object getOrb(Object stub);
-
-    /**
-     * Connects the Stub to the given ORB.
-     */
-    void connect(Object stub, Object orb) throws RemoteException;
-
-    /**
-     * Returns true if the given object is an ORB.
-     */
-    boolean isOrb(Object obj);
-
-    /**
-     * Creates, and returns, a new ORB instance.
-     */
-    Object createOrb(String[] args, Properties props);
-
-    /**
-     * Converts a string, produced by the object_to_string method, back
-     * to a CORBA object reference.
-     */
-    Object stringToObject(Object orb, String str);
-
-    /**
-     * Converts the given CORBA object reference to a string.
-     */
-    String objectToString(Object orb, Object obj);
-
-    /**
-     * Checks to ensure that an object of a remote or abstract interface
-     * type can be cast to a desired type.
-     */
-    <T> T narrow(Object narrowFrom, Class<T> narrowTo);
-
-    /**
-     * Makes a server object ready to receive remote calls
-     */
-    void exportObject(Remote obj) throws RemoteException;
-
-    /**
-     * Deregisters a server object from the runtime.
-     */
-    void unexportObject(Remote obj) throws NoSuchObjectException;
-
-    /**
-     * Returns a stub for the given server object.
-     */
-    Remote toStub(Remote obj) throws NoSuchObjectException;
-}
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/protocol/iiop/ClientProvider.java	Thu Sep 03 15:48:24 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.jmx.remote.protocol.iiop;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.util.Map;
-
-import javax.management.remote.JMXConnectorProvider;
-import javax.management.remote.JMXConnector;
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.rmi.RMIConnector;
-
-public class ClientProvider implements JMXConnectorProvider {
-
-    public JMXConnector newJMXConnector(JMXServiceURL serviceURL,
-                                        Map<String,?> environment)
-            throws IOException {
-        if (!serviceURL.getProtocol().equals("iiop")) {
-            throw new MalformedURLException("Protocol not iiop: " +
-                                            serviceURL.getProtocol());
-        }
-        return new RMIConnector(serviceURL, environment);
-    }
-}
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/protocol/iiop/IIOPProxyImpl.java	Thu Sep 03 15:48:24 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-/*
- * Copyright (c) 2009,2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.jmx.remote.protocol.iiop;
-
-import org.omg.CORBA.ORB;
-import org.omg.CORBA.portable.Delegate;
-import javax.rmi.PortableRemoteObject;
-import javax.rmi.CORBA.Stub;
-
-import java.util.Properties;
-import java.rmi.Remote;
-import java.rmi.RemoteException;
-import java.rmi.NoSuchObjectException;
-
-import com.sun.jmx.remote.internal.IIOPProxy;
-import java.io.SerializablePermission;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.Permissions;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.security.ProtectionDomain;
-
-/**
- * An implementation of IIOPProxy that simply delegates to the appropriate
- * RMI-IIOP and CORBA APIs.
- */
-
-public class IIOPProxyImpl implements IIOPProxy {
-    // special ACC used to initialize the IIOP stub
-    // the only allowed privilege is SerializablePermission("enableSubclassImplementation")
-    private static final AccessControlContext STUB_ACC;
-
-    static {
-        Permissions p = new Permissions();
-        p.add(new SerializablePermission("enableSubclassImplementation"));
-        STUB_ACC = new AccessControlContext(
-            new ProtectionDomain[]{
-                new ProtectionDomain(null, p)
-            }
-        );
-    }
-
-    public IIOPProxyImpl() { }
-
-    @Override
-    public boolean isStub(Object obj) {
-        return (obj instanceof Stub);
-    }
-
-    @Override
-    public Object getDelegate(Object stub) {
-        return ((Stub)stub)._get_delegate();
-    }
-
-    @Override
-    public void setDelegate(Object stub, Object delegate) {
-        ((Stub)stub)._set_delegate((Delegate)delegate);
-    }
-
-    @Override
-    public Object getOrb(Object stub) {
-        try {
-            return ((Stub)stub)._orb();
-        } catch (org.omg.CORBA.BAD_OPERATION x) {
-            throw new UnsupportedOperationException(x);
-        }
-    }
-
-    @Override
-    public void connect(Object stub, Object orb)
-        throws RemoteException
-    {
-        ((Stub)stub).connect((ORB)orb);
-    }
-
-    @Override
-    public boolean isOrb(Object obj) {
-        return (obj instanceof ORB);
-    }
-
-    @Override
-    public Object createOrb(String[] args, Properties props) {
-        return ORB.init(args, props);
-    }
-
-    @Override
-    public Object stringToObject(Object orb, String str) {
-        return ((ORB)orb).string_to_object(str);
-    }
-
-    @Override
-    public String objectToString(Object orb, Object obj) {
-        return ((ORB)orb).object_to_string((org.omg.CORBA.Object)obj);
-    }
-
-    @Override
-    @SuppressWarnings("unchecked")
-    public <T> T narrow(Object narrowFrom, Class<T> narrowTo) {
-        return (T)PortableRemoteObject.narrow(narrowFrom, narrowTo);
-    }
-
-    @Override
-    public void exportObject(Remote obj) throws RemoteException {
-        PortableRemoteObject.exportObject(obj);
-    }
-
-    @Override
-    public void unexportObject(Remote obj) throws NoSuchObjectException {
-        PortableRemoteObject.unexportObject(obj);
-    }
-
-    @Override
-    public Remote toStub(final Remote obj) throws NoSuchObjectException {
-        if (System.getSecurityManager() == null) {
-            return PortableRemoteObject.toStub(obj);
-        } else {
-            try {
-                return AccessController.doPrivileged(new PrivilegedExceptionAction<Remote>() {
-
-                    @Override
-                    public Remote run() throws Exception {
-                        return PortableRemoteObject.toStub(obj);
-                    }
-                }, STUB_ACC);
-            } catch (PrivilegedActionException e) {
-                if (e.getException() instanceof NoSuchObjectException) {
-                    throw (NoSuchObjectException)e.getException();
-                }
-                throw new RuntimeException("Unexpected exception type", e.getException());
-            }
-        }
-    }
-}
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/protocol/iiop/ProxyInputStream.java	Thu Sep 03 15:48:24 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +0,0 @@
-/*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.jmx.remote.protocol.iiop;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.math.BigDecimal;
-
-import org.omg.CORBA.Any;
-import org.omg.CORBA.Context;
-import org.omg.CORBA.NO_IMPLEMENT;
-import org.omg.CORBA.ORB;
-import org.omg.CORBA.TypeCode;
-import org.omg.CORBA.portable.BoxedValueHelper;
-
-@SuppressWarnings({"deprecation", "rawtypes"})
-public class ProxyInputStream extends org.omg.CORBA_2_3.portable.InputStream {
-    public ProxyInputStream(org.omg.CORBA.portable.InputStream in) {
-        this.in = in;
-    }
-
-    public boolean read_boolean() {
-        return in.read_boolean();
-    }
-
-    public char read_char() {
-        return in.read_char();
-    }
-
-    public char read_wchar() {
-        return in.read_wchar();
-    }
-
-    public byte read_octet() {
-        return in.read_octet();
-    }
-
-    public short read_short() {
-        return in.read_short();
-    }
-
-    public short read_ushort() {
-        return in.read_ushort();
-    }
-
-    public int read_long() {
-        return in.read_long();
-    }
-
-    public int read_ulong() {
-        return in.read_ulong();
-    }
-
-    public long read_longlong() {
-        return in.read_longlong();
-    }
-
-    public long read_ulonglong() {
-        return in.read_ulonglong();
-    }
-
-    public float read_float() {
-        return in.read_float();
-    }
-
-    public double read_double() {
-        return in.read_double();
-    }
-
-    public String read_string() {
-        return in.read_string();
-    }
-
-    public String read_wstring() {
-        return in.read_wstring();
-    }
-
-    public void read_boolean_array(boolean[] value, int offset, int length) {
-        in.read_boolean_array(value, offset, length);
-    }
-
-    public void read_char_array(char[] value, int offset, int length) {
-        in.read_char_array(value, offset, length);
-    }
-
-    public void read_wchar_array(char[] value, int offset, int length) {
-        in.read_wchar_array(value, offset, length);
-    }
-
-    public void read_octet_array(byte[] value, int offset, int length) {
-        in.read_octet_array(value, offset, length);
-    }
-
-    public void read_short_array(short[] value, int offset, int length) {
-        in.read_short_array(value, offset, length);
-    }
-
-    public void read_ushort_array(short[] value, int offset, int length) {
-        in.read_ushort_array(value, offset, length);
-    }
-
-    public void read_long_array(int[] value, int offset, int length) {
-        in.read_long_array(value, offset, length);
-    }
-
-    public void read_ulong_array(int[] value, int offset, int length) {
-        in.read_ulong_array(value, offset, length);
-    }
-
-    public void read_longlong_array(long[] value, int offset, int length) {
-        in.read_longlong_array(value, offset, length);
-    }
-
-    public void read_ulonglong_array(long[] value, int offset, int length) {
-        in.read_ulonglong_array(value, offset, length);
-    }
-
-    public void read_float_array(float[] value, int offset, int length) {
-        in.read_float_array(value, offset, length);
-    }
-
-    public void read_double_array(double[] value, int offset, int length) {
-        in.read_double_array(value, offset, length);
-    }
-
-    public org.omg.CORBA.Object read_Object() {
-        return in.read_Object();
-    }
-
-    public TypeCode read_TypeCode() {
-        return in.read_TypeCode();
-    }
-
-    public Any read_any() {
-        return in.read_any();
-    }
-
-    /**
-     * @deprecated
-     */
-    @Override
-    @Deprecated
-    public org.omg.CORBA.Principal read_Principal() {
-        return in.read_Principal();
-    }
-
-    @Override
-    public int read() throws IOException {
-        return in.read();
-    }
-
-    @Override
-    public BigDecimal read_fixed() {
-        return in.read_fixed();
-    }
-
-    @Override
-    public Context read_Context() {
-        return in.read_Context();
-    }
-
-    @Override
-    public org.omg.CORBA.Object read_Object(java.lang.Class clz) {
-        return in.read_Object(clz);
-    }
-
-    @Override
-    public ORB orb() {
-        return in.orb();
-    }
-
-    @Override
-    public Serializable read_value() {
-        return narrow().read_value();
-    }
-
-    @Override
-    public Serializable read_value(Class clz) {
-        return narrow().read_value(clz);
-    }
-
-    @Override
-    public Serializable read_value(BoxedValueHelper factory) {
-        return narrow().read_value(factory);
-    }
-
-    @Override
-    public Serializable read_value(String rep_id) {
-        return narrow().read_value(rep_id);
-    }
-
-    @Override
-    public Serializable read_value(Serializable value) {
-        return narrow().read_value(value);
-    }
-
-    @Override
-    public Object read_abstract_interface() {
-        return narrow().read_abstract_interface();
-    }
-
-    @Override
-    public Object read_abstract_interface(Class clz) {
-        return narrow().read_abstract_interface(clz);
-    }
-
-    protected org.omg.CORBA_2_3.portable.InputStream narrow() {
-        if (in instanceof org.omg.CORBA_2_3.portable.InputStream)
-            return (org.omg.CORBA_2_3.portable.InputStream) in;
-        throw new NO_IMPLEMENT();
-    }
-
-    public org.omg.CORBA.portable.InputStream getProxiedInputStream() {
-        return in;
-    }
-
-    protected final org.omg.CORBA.portable.InputStream in;
-}
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/protocol/iiop/ServerProvider.java	Thu Sep 03 15:48:24 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.jmx.remote.protocol.iiop;
-
-import java.io.IOException;
-import java.net.MalformedURLException;
-import java.util.Map;
-
-import javax.management.MBeanServer;
-import javax.management.remote.JMXConnectorServer;
-import javax.management.remote.JMXConnectorServerProvider;
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.rmi.RMIConnectorServer;
-
-public class ServerProvider implements JMXConnectorServerProvider {
-
-    public JMXConnectorServer newJMXConnectorServer(JMXServiceURL serviceURL,
-                                                    Map<String,?> environment,
-                                                    MBeanServer mbeanServer)
-            throws IOException {
-        if (!serviceURL.getProtocol().equals("iiop")) {
-            throw new MalformedURLException("Protocol not iiop: " +
-                                            serviceURL.getProtocol());
-        }
-        return new RMIConnectorServer(serviceURL, environment, mbeanServer);
-    }
-
-}
--- a/jdk/src/java.management/share/classes/javax/management/remote/JMXConnectorFactory.java	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/src/java.management/share/classes/javax/management/remote/JMXConnectorFactory.java	Tue Sep 08 16:10:36 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -140,9 +140,7 @@
  *
  * <p>Every implementation must support the RMI connector protocol with
  * the default RMI transport, specified with string <code>rmi</code>.
- * An implementation may optionally support the RMI connector protocol
- * with the RMI/IIOP transport, specified with the string
- * <code>iiop</code>.</p>
+ * </p>
  *
  * <p>Once a provider is found, the result of the
  * <code>newJMXConnector</code> method is the result of calling {@link
--- a/jdk/src/java.management/share/classes/javax/management/remote/JMXConnectorServerFactory.java	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/src/java.management/share/classes/javax/management/remote/JMXConnectorServerFactory.java	Tue Sep 08 16:10:36 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -131,9 +131,7 @@
  *
  * <p>Every implementation must support the RMI connector protocol with
  * the default RMI transport, specified with string <code>rmi</code>.
- * An implementation may optionally support the RMI connector protocol
- * with the RMI/IIOP transport, specified with the string
- * <code>iiop</code>.</p>
+ * </p>
  *
  * <p>Once a provider is found, the result of the
  * <code>newJMXConnectorServer</code> method is the result of calling
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/NoCallStackClassLoader.java	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/src/java.management/share/classes/javax/management/remote/rmi/NoCallStackClassLoader.java	Tue Sep 08 16:10:36 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,12 +31,11 @@
     <p>A class loader that only knows how to define a limited number
     of classes, and load a limited number of other classes through
     delegation to another loader.  It is used to get around a problem
-    with Serialization, in particular as used by RMI (including
-    RMI/IIOP).  The JMX Remote API defines exactly what class loader
-    must be used to deserialize arguments on the server, and return
-    values on the client.  We communicate this class loader to RMI by
-    setting it as the context class loader.  RMI uses the context
-    class loader to load classes as it deserializes, which is what we
+    with Serialization, in particular as used by RMI. The JMX Remote API
+    defines exactly what class loader must be used to deserialize arguments on
+    the server, and return values on the client.  We communicate this class
+    loader to RMI by setting it as the context class loader.  RMI uses the
+    context class loader to load classes as it deserializes, which is what we
     want.  However, before consulting the context class loader, it
     looks up the call stack for a class with a non-null class loader,
     and uses that if it finds one.  So, in the standalone version of
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java	Tue Sep 08 16:10:36 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -76,11 +76,10 @@
 
     /**
      * Constructs a new {@link RMIConnection}. This connection can be
-     * used with either the JRMP or IIOP transport. This object does
+     * used with the JRMP transport. This object does
      * not export itself: it is the responsibility of the caller to
      * export it appropriately (see {@link
-     * RMIJRMPServerImpl#makeClient(String,Subject)} and {@link
-     * RMIIIOPServerImpl#makeClient(String,Subject)}.
+     * RMIJRMPServerImpl#makeClient(String,Subject)}).
      *
      * @param rmiServer The RMIServerImpl object for which this
      * connection is created.  The behavior is unspecified if this
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnector.java	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnector.java	Tue Sep 08 16:10:36 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,25 +30,21 @@
 import com.sun.jmx.remote.internal.ClientListenerInfo;
 import com.sun.jmx.remote.internal.ClientNotifForwarder;
 import com.sun.jmx.remote.internal.ProxyRef;
-import com.sun.jmx.remote.internal.IIOPHelper;
 import com.sun.jmx.remote.util.ClassLogger;
 import com.sun.jmx.remote.util.EnvHelp;
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InvalidObjectException;
-import java.io.NotSerializableException;
 import java.io.ObjectInputStream;
 import java.io.ObjectStreamClass;
 import java.io.Serializable;
-import java.io.WriteAbortedException;
 import java.lang.ref.WeakReference;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Proxy;
 import java.net.MalformedURLException;
-import java.rmi.MarshalException;
 import java.rmi.MarshalledObject;
 import java.rmi.NoSuchObjectException;
 import java.rmi.Remote;
@@ -61,13 +57,12 @@
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.security.PrivilegedExceptionAction;
-import java.security.PrivilegedActionException;
 import java.security.ProtectionDomain;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.Hashtable;
 import java.util.Map;
-import java.util.Properties;
 import java.util.Set;
 import java.util.WeakHashMap;
 import javax.management.Attribute;
@@ -146,22 +141,20 @@
      * the RMI connector server with the given address.</p>
      *
      * <p>The address can refer directly to the connector server,
-     * using one of the following syntaxes:</p>
+     * using the following syntax:</p>
      *
      * <pre>
      * service:jmx:rmi://<em>[host[:port]]</em>/stub/<em>encoded-stub</em>
-     * service:jmx:iiop://<em>[host[:port]]</em>/ior/<em>encoded-IOR</em>
      * </pre>
      *
      * <p>(Here, the square brackets {@code []} are not part of the
      * address but indicate that the host and port are optional.)</p>
      *
      * <p>The address can instead indicate where to find an RMI stub
-     * through JNDI, using one of the following syntaxes:</p>
+     * through JNDI, using the following syntax:</p>
      *
      * <pre>
      * service:jmx:rmi://<em>[host[:port]]</em>/jndi/<em>jndi-name</em>
-     * service:jmx:iiop://<em>[host[:port]]</em>/jndi/<em>jndi-name</em>
      * </pre>
      *
      * <p>An implementation may also recognize additional address
@@ -242,8 +235,7 @@
 
     /**
      * @throws IOException if the connection could not be made because of a
-     *   communication problem, or in the case of the {@code iiop} protocol,
-     *   that RMI/IIOP is not supported
+     *   communication problem
      */
     public void connect() throws IOException {
         connect(null);
@@ -251,8 +243,7 @@
 
     /**
      * @throws IOException if the connection could not be made because of a
-     *   communication problem, or in the case of the {@code iiop} protocol,
-     *   that RMI/IIOP is not supported
+     *   communication problem
      */
     public synchronized void connect(Map<String,?> environment)
     throws IOException {
@@ -294,9 +285,7 @@
 
             if (checkStub) checkStub(stub, rmiServerImplStubClass);
 
-            // Connect IIOP Stub if needed.
             if (tracing) logger.trace("connect",idstr + " connecting stub...");
-            stub = connectStub(stub,usemap);
             idstr = (tracing?"["+this.toString()+"]":null);
 
             // Calling newClient on the RMIServer stub.
@@ -307,18 +296,6 @@
             try {
                 connection = getConnection(stub, credentials, checkStub);
             } catch (java.rmi.RemoteException re) {
-                if (jmxServiceURL != null) {
-                    final String pro = jmxServiceURL.getProtocol();
-                    final String path = jmxServiceURL.getURLPath();
-
-                    if ("rmi".equals(pro) &&
-                        path.startsWith("/jndi/iiop:")) {
-                        MalformedURLException mfe = new MalformedURLException(
-                              "Protocol is rmi but JNDI scheme is iiop: " + jmxServiceURL);
-                        mfe.initCause(re);
-                        throw mfe;
-                    }
-                }
                 throw re;
             }
 
@@ -1413,13 +1390,6 @@
             if (ioe instanceof UnmarshalException) {
                 throw ioe; // the fix of 6937053 made ClientNotifForwarder.fetchNotifs
                            // fetch one by one with UnmarshalException
-            } else if (ioe instanceof MarshalException) {
-                // IIOP will throw MarshalException wrapping a NotSerializableException
-                // when a server fails to serialize a response.
-                MarshalException me = (MarshalException)ioe;
-                if (me.detail instanceof NotSerializableException) {
-                    throw (NotSerializableException)me.detail;
-                }
             }
 
             // Not serialization problem, return.
@@ -1654,9 +1624,6 @@
                 throw new IOException("Failed to get a RMI stub: "+ne);
             }
 
-            // Connect IIOP Stub if needed.
-            stub = connectStub(stub,env);
-
             // Calling newClient on the RMIServer stub.
             Object credentials = env.get(CREDENTIALS);
             connection = stub.newClient(credentials);
@@ -1694,103 +1661,6 @@
     // Private stuff - Serialization
     //--------------------------------------------------------------------
     /**
-     * <p>In order to be usable, an IIOP stub must be connected to an ORB.
-     * The stub is automatically connected to the ORB if:
-     * <ul>
-     *     <li> It was returned by the COS naming</li>
-     *     <li> Its server counterpart has been registered in COS naming
-     *          through JNDI.</li>
-     * </ul>
-     * Otherwise, it is not connected. A stub which is deserialized
-     * from Jini is not connected. A stub which is obtained from a
-     * non registered RMIIIOPServerImpl is not a connected.<br>
-     * A stub which is not connected can't be serialized, and thus
-     * can't be registered in Jini. A stub which is not connected can't
-     * be used to invoke methods on the server.
-     * <p>
-     * In order to palliate this, this method will connect the
-     * given stub if it is not yet connected. If the given
-     * <var>RMIServer</var> is not an instance of
-     * {@link javax.rmi.CORBA.Stub javax.rmi.CORBA.Stub}, then the
-     * method do nothing and simply returns that stub. Otherwise,
-     * this method will attempt to connect the stub to an ORB as
-     * follows:
-     * <ul>
-     * <li>This method looks in the provided <var>environment</var> for
-     * the "java.naming.corba.orb" property. If it is found, the
-     * referenced object (an {@link org.omg.CORBA.ORB ORB}) is used to
-     * connect the stub. Otherwise, a new org.omg.CORBA.ORB is created
-     * by calling {@link
-     * org.omg.CORBA.ORB#init(String[], Properties)
-     * org.omg.CORBA.ORB.init((String[])null,(Properties)null)}</li>
-     * <li>The new created ORB is kept in a static
-     * {@link WeakReference} and can be reused for connecting other
-     * stubs. However, no reference is ever kept on the ORB provided
-     * in the <var>environment</var> map, if any.</li>
-     * </ul>
-     * @param rmiServer A RMI Server Stub.
-     * @param environment An environment map, possibly containing an ORB.
-     * @return the given stub.
-     * @exception IllegalArgumentException if the
-     *      {@code java.naming.corba.orb} property is specified and
-     *      does not point to an {@link org.omg.CORBA.ORB ORB}.
-     * @exception IOException if the connection to the ORB failed.
-     **/
-    static RMIServer connectStub(RMIServer rmiServer,
-                                 Map<String, ?> environment)
-        throws IOException {
-        if (IIOPHelper.isStub(rmiServer)) {
-            try {
-                IIOPHelper.getOrb(rmiServer);
-            } catch (UnsupportedOperationException x) {
-                // BAD_OPERATION
-                IIOPHelper.connect(rmiServer, resolveOrb(environment));
-            }
-        }
-        return rmiServer;
-    }
-
-    /**
-     * Get the ORB specified by <var>environment</var>, or create a
-     * new one.
-     * <p>This method looks in the provided <var>environment</var> for
-     * the "java.naming.corba.orb" property. If it is found, the
-     * referenced object (an {@link org.omg.CORBA.ORB ORB}) is
-     * returned. Otherwise, a new org.omg.CORBA.ORB is created
-     * by calling {@link
-     * org.omg.CORBA.ORB#init(String[], java.util.Properties)
-     * org.omg.CORBA.ORB.init((String[])null,(Properties)null)}
-     * <p>The new created ORB is kept in a static
-     * {@link WeakReference} and can be reused for connecting other
-     * stubs. However, no reference is ever kept on the ORB provided
-     * in the <var>environment</var> map, if any.
-     * @param environment An environment map, possibly containing an ORB.
-     * @return An ORB.
-     * @exception IllegalArgumentException if the
-     *      {@code java.naming.corba.orb} property is specified and
-     *      does not point to an {@link org.omg.CORBA.ORB ORB}.
-     * @exception IOException if the ORB initialization failed.
-     **/
-    static Object resolveOrb(Map<String, ?> environment)
-        throws IOException {
-        if (environment != null) {
-            final Object orb = environment.get(EnvHelp.DEFAULT_ORB);
-            if (orb != null && !(IIOPHelper.isOrb(orb)))
-                throw new IllegalArgumentException(EnvHelp.DEFAULT_ORB +
-                        " must be an instance of org.omg.CORBA.ORB.");
-            if (orb != null) return orb;
-        }
-        final Object orb =
-                (RMIConnector.orb==null)?null:RMIConnector.orb.get();
-        if (orb != null) return orb;
-
-        final Object newOrb =
-                IIOPHelper.createOrb((String[])null, (Properties)null);
-        RMIConnector.orb = new WeakReference<Object>(newOrb);
-        return newOrb;
-    }
-
-    /**
      * Read RMIConnector fields from an {@link java.io.ObjectInputStream
      * ObjectInputStream}.
      * Calls {@code s.defaultReadObject()} and then initializes
@@ -1846,7 +1716,6 @@
     throws IOException {
         if (rmiServer == null && jmxServiceURL == null) throw new
                 InvalidObjectException("rmiServer and jmxServiceURL both null.");
-        connectStub(this.rmiServer,env);
         s.defaultWriteObject();
     }
 
@@ -1911,24 +1780,15 @@
     private RMIServer findRMIServer(JMXServiceURL directoryURL,
             Map<String, Object> environment)
             throws NamingException, IOException {
-        final boolean isIiop = RMIConnectorServer.isIiopURL(directoryURL,true);
-        if (isIiop) {
-            // Make sure java.naming.corba.orb is in the Map.
-            environment.put(EnvHelp.DEFAULT_ORB,resolveOrb(environment));
-        }
 
         String path = directoryURL.getURLPath();
         int end = path.indexOf(';');
         if (end < 0) end = path.length();
         if (path.startsWith("/jndi/"))
-            return findRMIServerJNDI(path.substring(6,end), environment, isIiop);
+            return findRMIServerJNDI(path.substring(6,end), environment);
         else if (path.startsWith("/stub/"))
-            return findRMIServerJRMP(path.substring(6,end), environment, isIiop);
-        else if (path.startsWith("/ior/")) {
-            if (!IIOPHelper.isAvailable())
-                throw new IOException("iiop protocol not available");
-            return findRMIServerIIOP(path.substring(5,end), environment, isIiop);
-        } else {
+            return findRMIServerJRMP(path.substring(6,end), environment);
+        else {
             final String msg = "URL path must begin with /jndi/ or /stub/ " +
                     "or /ior/: " + path;
             throw new MalformedURLException(msg);
@@ -1940,16 +1800,13 @@
      * @param jndiURL A JNDI URL indicating the location of the Stub
      *                (see {@link javax.management.remote.rmi}), e.g.:
      *   <ul><li>{@code rmi://registry-host:port/rmi-stub-name}</li>
-     *       <li>or {@code iiop://cosnaming-host:port/iiop-stub-name}</li>
      *       <li>or {@code ldap://ldap-host:port/java-container-dn}</li>
      *   </ul>
      * @param env the environment Map passed to the connector.
-     * @param isIiop true if the stub is expected to be an IIOP stub.
      * @return The retrieved RMIServer stub.
      * @exception NamingException if the stub couldn't be found.
      **/
-    private RMIServer findRMIServerJNDI(String jndiURL, Map<String, ?> env,
-            boolean isIiop)
+    private RMIServer findRMIServerJNDI(String jndiURL, Map<String, ?> env)
             throws NamingException {
 
         InitialContext ctx = new InitialContext(EnvHelp.mapToHashtable(env));
@@ -1957,10 +1814,7 @@
         Object objref = ctx.lookup(jndiURL);
         ctx.close();
 
-        if (isIiop)
-            return narrowIIOPServer(objref);
-        else
-            return narrowJRMPServer(objref);
+        return narrowJRMPServer(objref);
     }
 
     private static RMIServer narrowJRMPServer(Object objref) {
@@ -1968,28 +1822,8 @@
         return (RMIServer) objref;
     }
 
-    private static RMIServer narrowIIOPServer(Object objref) {
-        try {
-            return IIOPHelper.narrow(objref, RMIServer.class);
-        } catch (ClassCastException e) {
-            if (logger.traceOn())
-                logger.trace("narrowIIOPServer","Failed to narrow objref=" +
-                        objref + ": " + e);
-            if (logger.debugOn()) logger.debug("narrowIIOPServer",e);
-            return null;
-        }
-    }
-
-    private RMIServer findRMIServerIIOP(String ior, Map<String, ?> env, boolean isIiop) {
-        // could forbid "rmi:" URL here -- but do we need to?
-        final Object orb = env.get(EnvHelp.DEFAULT_ORB);
-        final Object stub = IIOPHelper.stringToObject(orb, ior);
-        return IIOPHelper.narrow(stub, RMIServer.class);
-    }
-
-    private RMIServer findRMIServerJRMP(String base64, Map<String, ?> env, boolean isIiop)
+    private RMIServer findRMIServerJRMP(String base64, Map<String, ?> env)
         throws IOException {
-        // could forbid "iiop:" URL here -- but do we need to?
         final byte[] serialized;
         try {
             serialized = base64ToByteArray(base64);
@@ -2203,228 +2037,6 @@
         return proxyStub;
     }
 
-    /*
-       The following code performs a similar trick for RMI/IIOP to the
-       one described above for RMI/JRMP.  Unlike JRMP, though, we
-       can't easily insert an object between the RMIConnection stub
-       and the RMI/IIOP deserialization code, as explained below.
-
-       A method in an RMI/IIOP stub does the following.  It makes an
-       org.omg.CORBA_2_3.portable.OutputStream for each request, and
-       writes the parameters to it.  Then it calls
-       _invoke(OutputStream) which it inherits from CORBA's
-       ObjectImpl.  That returns an
-       org.omg.CORBA_2_3.portable.InputStream.  The return value is
-       read from this InputStream.  So the stack during
-       deserialization looks like this:
-
-       MBeanServerConnection.getAttribute (or whatever)
-       -> _RMIConnection_Stub.getAttribute
-          -> Util.readAny (a CORBA method)
-             -> InputStream.read_any
-                -> internal CORBA stuff
-
-       What we would have *liked* to have done would be the same thing
-       as for RMI/JRMP.  We create a "ProxyDelegate" that is an
-       org.omg.CORBA.portable.Delegate that simply forwards every
-       operation to the real original Delegate from the RMIConnection
-       stub, except that the InputStream returned by _invoke is
-       wrapped by a "ProxyInputStream" that is loaded by our
-       NoCallStackClassLoader.
-
-       Unfortunately, this doesn't work, at least with Sun's J2SE
-       1.4.2, because the CORBA code is not designed to allow you to
-       change Delegates arbitrarily.  You get a ClassCastException
-       from code that expects the Delegate to implement an internal
-       interface.
-
-       So instead we do the following.  We create a subclass of the
-       stub that overrides the _invoke method so as to wrap the
-       returned InputStream in a ProxyInputStream.  We create a
-       subclass of ProxyInputStream using the NoCallStackClassLoader
-       and override its read_any and read_value(Class) methods.
-       (These are the only methods called during deserialization of
-       MBeanServerConnection return values.)  We extract the Delegate
-       from the original stub and insert it into our subclass stub,
-       and away we go.  The state of a stub consists solely of its
-       Delegate.
-
-       We also need to catch ApplicationException, which will encode
-       any exceptions declared in the throws clause of the called
-       method.  Its InputStream needs to be wrapped in a
-       ProxyInputSteam too.
-
-       We override _releaseReply in the stub subclass so that it
-       replaces a ProxyInputStream argument with the original
-       InputStream.  This avoids problems if the implementation of
-       _releaseReply ends up casting this InputStream to an
-       implementation-specific interface (which in Sun's J2SE 5 it
-       does).
-
-       It is not strictly necessary for the stub subclass to be loaded
-       by a NoCallStackClassLoader, since the call-stack search stops
-       at the ProxyInputStream subclass.  However, it is convenient
-       for two reasons.  One is that it means that the
-       ProxyInputStream subclass can be accessed directly, without
-       using reflection.  The other is that it avoids build problems,
-       since usually stubs are created after other classes are
-       compiled, so we can't access them from this class without,
-       again, using reflection.
-
-       The strings below encode the following two Java classes,
-       compiled using javac -g:none.
-
-        package com.sun.jmx.remote.protocol.iiop;
-
-        import org.omg.stub.javax.management.remote.rmi._RMIConnection_Stub;
-
-        import org.omg.CORBA.portable.ApplicationException;
-        import org.omg.CORBA.portable.InputStream;
-        import org.omg.CORBA.portable.OutputStream;
-        import org.omg.CORBA.portable.RemarshalException;
-
-        public class ProxyStub extends _RMIConnection_Stub {
-            public InputStream _invoke(OutputStream out)
-                    throws ApplicationException, RemarshalException {
-                try {
-                    return new PInputStream(super._invoke(out));
-                } catch (ApplicationException e) {
-                    InputStream pis = new PInputStream(e.getInputStream());
-                    throw new ApplicationException(e.getId(), pis);
-                }
-            }
-
-            public void _releaseReply(InputStream in) {
-                if (in != null)
-                    in = ((PInputStream)in).getProxiedInputStream();
-                super._releaseReply(in);
-            }
-        }
-
-        package com.sun.jmx.remote.protocol.iiop;
-
-        public class PInputStream extends ProxyInputStream {
-            public PInputStream(org.omg.CORBA.portable.InputStream in) {
-                super(in);
-            }
-
-            public org.omg.CORBA.Any read_any() {
-                return in.read_any();
-            }
-
-            public java.io.Serializable read_value(Class clz) {
-                return narrow().read_value(clz);
-            }
-        }
-
-
-     */
-    private static final String iiopConnectionStubClassName =
-        "org.omg.stub.javax.management.remote.rmi._RMIConnection_Stub";
-    private static final String proxyStubClassName =
-        "com.sun.jmx.remote.protocol.iiop.ProxyStub";
-    private static final String ProxyInputStreamClassName =
-        "com.sun.jmx.remote.protocol.iiop.ProxyInputStream";
-    private static final String pInputStreamClassName =
-        "com.sun.jmx.remote.protocol.iiop.PInputStream";
-    private static final Class<?> proxyStubClass;
-    static {
-        final String proxyStubByteCodeString =
-                "\312\376\272\276\0\0\0\63\0+\12\0\14\0\30\7\0\31\12\0\14\0\32\12"+
-                "\0\2\0\33\7\0\34\12\0\5\0\35\12\0\5\0\36\12\0\5\0\37\12\0\2\0 "+
-                "\12\0\14\0!\7\0\"\7\0#\1\0\6<init>\1\0\3()V\1\0\4Code\1\0\7_in"+
-                "voke\1\0K(Lorg/omg/CORBA/portable/OutputStream;)Lorg/omg/CORBA"+
-                "/portable/InputStream;\1\0\15StackMapTable\7\0\34\1\0\12Except"+
-                "ions\7\0$\1\0\15_releaseReply\1\0'(Lorg/omg/CORBA/portable/Inp"+
-                "utStream;)V\14\0\15\0\16\1\0-com/sun/jmx/remote/protocol/iiop/"+
-                "PInputStream\14\0\20\0\21\14\0\15\0\27\1\0+org/omg/CORBA/porta"+
-                "ble/ApplicationException\14\0%\0&\14\0'\0(\14\0\15\0)\14\0*\0&"+
-                "\14\0\26\0\27\1\0*com/sun/jmx/remote/protocol/iiop/ProxyStub\1"+
-                "\0<org/omg/stub/javax/management/remote/rmi/_RMIConnection_Stu"+
-                "b\1\0)org/omg/CORBA/portable/RemarshalException\1\0\16getInput"+
-                "Stream\1\0&()Lorg/omg/CORBA/portable/InputStream;\1\0\5getId\1"+
-                "\0\24()Ljava/lang/String;\1\09(Ljava/lang/String;Lorg/omg/CORB"+
-                "A/portable/InputStream;)V\1\0\25getProxiedInputStream\0!\0\13\0"+
-                "\14\0\0\0\0\0\3\0\1\0\15\0\16\0\1\0\17\0\0\0\21\0\1\0\1\0\0\0\5"+
-                "*\267\0\1\261\0\0\0\0\0\1\0\20\0\21\0\2\0\17\0\0\0G\0\4\0\4\0\0"+
-                "\0'\273\0\2Y*+\267\0\3\267\0\4\260M\273\0\2Y,\266\0\6\267\0\4N"+
-                "\273\0\5Y,\266\0\7-\267\0\10\277\0\1\0\0\0\14\0\15\0\5\0\1\0\22"+
-                "\0\0\0\6\0\1M\7\0\23\0\24\0\0\0\6\0\2\0\5\0\25\0\1\0\26\0\27\0"+
-                "\1\0\17\0\0\0'\0\2\0\2\0\0\0\22+\306\0\13+\300\0\2\266\0\11L*+"+
-                "\267\0\12\261\0\0\0\1\0\22\0\0\0\3\0\1\14\0\0";
-        final String pInputStreamByteCodeString =
-                "\312\376\272\276\0\0\0\63\0\36\12\0\7\0\17\11\0\6\0\20\12\0\21"+
-                "\0\22\12\0\6\0\23\12\0\24\0\25\7\0\26\7\0\27\1\0\6<init>\1\0'("+
-                "Lorg/omg/CORBA/portable/InputStream;)V\1\0\4Code\1\0\10read_an"+
-                "y\1\0\25()Lorg/omg/CORBA/Any;\1\0\12read_value\1\0)(Ljava/lang"+
-                "/Class;)Ljava/io/Serializable;\14\0\10\0\11\14\0\30\0\31\7\0\32"+
-                "\14\0\13\0\14\14\0\33\0\34\7\0\35\14\0\15\0\16\1\0-com/sun/jmx"+
-                "/remote/protocol/iiop/PInputStream\1\0\61com/sun/jmx/remote/pr"+
-                "otocol/iiop/ProxyInputStream\1\0\2in\1\0$Lorg/omg/CORBA/portab"+
-                "le/InputStream;\1\0\"org/omg/CORBA/portable/InputStream\1\0\6n"+
-                "arrow\1\0*()Lorg/omg/CORBA_2_3/portable/InputStream;\1\0&org/o"+
-                "mg/CORBA_2_3/portable/InputStream\0!\0\6\0\7\0\0\0\0\0\3\0\1\0"+
-                "\10\0\11\0\1\0\12\0\0\0\22\0\2\0\2\0\0\0\6*+\267\0\1\261\0\0\0"+
-                "\0\0\1\0\13\0\14\0\1\0\12\0\0\0\24\0\1\0\1\0\0\0\10*\264\0\2\266"+
-                "\0\3\260\0\0\0\0\0\1\0\15\0\16\0\1\0\12\0\0\0\25\0\2\0\2\0\0\0"+
-                "\11*\266\0\4+\266\0\5\260\0\0\0\0\0\0";
-        final byte[] proxyStubByteCode =
-                NoCallStackClassLoader.stringToBytes(proxyStubByteCodeString);
-        final byte[] pInputStreamByteCode =
-                NoCallStackClassLoader.stringToBytes(pInputStreamByteCodeString);
-        final String[] classNames={proxyStubClassName, pInputStreamClassName};
-        final byte[][] byteCodes = {proxyStubByteCode, pInputStreamByteCode};
-        final String[] otherClassNames = {
-            iiopConnectionStubClassName,
-            ProxyInputStreamClassName,
-        };
-        if (IIOPHelper.isAvailable()) {
-            PrivilegedExceptionAction<Class<?>> action =
-                new PrivilegedExceptionAction<Class<?>>() {
-              public Class<?> run() throws Exception {
-                Class<RMIConnector> thisClass = RMIConnector.class;
-                ClassLoader thisLoader = thisClass.getClassLoader();
-                ProtectionDomain thisProtectionDomain =
-                        thisClass.getProtectionDomain();
-                ClassLoader cl =
-                        new NoCallStackClassLoader(classNames,
-                        byteCodes,
-                        otherClassNames,
-                        thisLoader,
-                        thisProtectionDomain);
-                return cl.loadClass(proxyStubClassName);
-              }
-            };
-            Class<?> stubClass;
-            try {
-                stubClass = AccessController.doPrivileged(action);
-            } catch (Exception e) {
-                logger.error("<clinit>",
-                        "Unexpected exception making shadow IIOP stub class: "+e);
-                logger.debug("<clinit>",e);
-                stubClass = null;
-            }
-            proxyStubClass = stubClass;
-        } else {
-            proxyStubClass = null;
-        }
-    }
-
-  private static RMIConnection shadowIiopStub(Object stub)
-    throws InstantiationException, IllegalAccessException {
-        Object proxyStub = null;
-        try {
-            proxyStub = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
-                public Object run() throws Exception {
-                    return proxyStubClass.newInstance();
-                }
-            });
-        } catch (PrivilegedActionException e) {
-            throw new InternalError();
-        }
-        IIOPHelper.setDelegate(proxyStub, IIOPHelper.getDelegate(stub));
-        return (RMIConnection) proxyStub;
-    }
     private static RMIConnection getConnection(RMIServer server,
             Object credentials,
             boolean checkStub)
@@ -2434,8 +2046,6 @@
         try {
             if (c.getClass() == rmiConnectionImplStubClass)
                 return shadowJrmpStub((RemoteObject) c);
-            if (c.getClass().getName().equals(iiopConnectionStubClassName))
-                return shadowIiopStub(c);
             logger.trace("getConnection",
                     "Did not wrap " + c.getClass() + " to foil " +
                     "stack search for classes: class loading semantics " +
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectorServer.java	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIConnectorServer.java	Tue Sep 08 16:10:36 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,6 @@
 
 
 import com.sun.jmx.remote.security.MBeanServerFileAccessController;
-import com.sun.jmx.remote.internal.IIOPHelper;
 import com.sun.jmx.remote.util.ClassLogger;
 import com.sun.jmx.remote.util.EnvHelp;
 
@@ -117,8 +116,8 @@
      *
      * @exception MalformedURLException if <code>url</code> does not
      * conform to the syntax for an RMI connector, or if its protocol
-     * is not recognized by this implementation. Only "rmi" and "iiop"
-     * are valid when this constructor is used.
+     * is not recognized by this implementation. Only "rmi" is valid when
+     * this constructor is used.
      *
      * @exception IOException if the connector server cannot be created
      * for some reason or if it is inevitable that its {@link #start()
@@ -151,8 +150,8 @@
      *
      * @exception MalformedURLException if <code>url</code> does not
      * conform to the syntax for an RMI connector, or if its protocol
-     * is not recognized by this implementation. Only "rmi" and "iiop"
-     * are valid when this constructor is used.
+     * is not recognized by this implementation. Only "rmi" is valid
+     * when this constructor is used.
      *
      * @exception IOException if the connector server cannot be created
      * for some reason or if it is inevitable that its {@link #start()
@@ -179,7 +178,7 @@
      *  consistent with the protocol type specified in <var>url</var>.
      *  If this parameter is non null, the protocol type specified by
      *  <var>url</var> is not constrained, and is assumed to be valid.
-     *  Otherwise, only "rmi" and "iiop" will be recognized.
+     *  Otherwise, only "rmi" will be recognized.
      *
      * @param mbeanServer the MBean server to which the new connector
      * server is attached, or null if it will be attached by being
@@ -189,8 +188,8 @@
      *
      * @exception MalformedURLException if <code>url</code> does not
      * conform to the syntax for an RMI connector, or if its protocol
-     * is not recognized by this implementation. Only "rmi" and "iiop"
-     * are recognized when <var>rmiServerImpl</var> is null.
+     * is not recognized by this implementation. Only "rmi" is recognized
+     * when <var>rmiServerImpl</var> is null.
      *
      * @exception IOException if the connector server cannot be created
      * for some reason or if it is inevitable that its {@link #start()
@@ -208,7 +207,7 @@
             IllegalArgumentException("Null JMXServiceURL");
         if (rmiServerImpl == null) {
             final String prt = url.getProtocol();
-            if (prt == null || !(prt.equals("rmi") || prt.equals("iiop"))) {
+            if (prt == null || !(prt.equals("rmi"))) {
                 final String msg = "Invalid protocol type: " + prt;
                 throw new MalformedURLException(msg);
             }
@@ -298,11 +297,6 @@
      * <li>If an <code>RMIServerImpl</code> was supplied to the
      * constructor, it is used.
      *
-     * <li>Otherwise, if the protocol part of the
-     * <code>JMXServiceURL</code> supplied to the constructor was
-     * <code>iiop</code>, an object of type {@link RMIIIOPServerImpl}
-     * is created.
-     *
      * <li>Otherwise, if the <code>JMXServiceURL</code>
      * was null, or its protocol part was <code>rmi</code>, an object
      * of type {@link RMIJRMPServerImpl} is created.
@@ -324,21 +318,19 @@
      * will not be bound to a directory.  Instead, a reference to it
      * will be encoded in the URL path of the RMIConnectorServer
      * address (returned by {@link #getAddress()}).  The encodings for
-     * <code>rmi</code> and <code>iiop</code> are described in the
-     * package documentation for {@link
-     * javax.management.remote.rmi}.</p>
+     * <code>rmi</code> are described in the package documentation for
+     * {@link javax.management.remote.rmi}.</p>
      *
      * <p>The behavior when the URL path is neither empty nor a JNDI
-     * directory URL, or when the protocol is neither <code>rmi</code>
-     * nor <code>iiop</code>, is implementation defined, and may
-     * include throwing {@link MalformedURLException} when the
-     * connector server is created or when it is started.</p>
+     * directory URL, or when the protocol is not <code>rmi</code>,
+     * is implementation defined, and may include throwing
+     * {@link MalformedURLException} when the connector server is created
+     * or when it is started.</p>
      *
      * @exception IllegalStateException if the connector server has
      * not been attached to an MBean server.
      * @exception IOException if the connector server cannot be
-     * started, or in the case of the {@code iiop} protocol, that
-     * RMI/IIOP is not supported.
+     * started.
      */
     public synchronized void start() throws IOException {
         final boolean tracing = logger.traceOn();
@@ -649,16 +641,13 @@
      * Creates a new RMIServerImpl.
      **/
     RMIServerImpl newServer() throws IOException {
-        final boolean iiop = isIiopURL(address,true);
         final int port;
         if (address == null)
             port = 0;
         else
             port = address.getPort();
-        if (iiop)
-            return newIIOPServer(attributes);
-        else
-            return newJRMPServer(attributes, port);
+
+        return newJRMPServer(attributes, port);
     }
 
     /**
@@ -675,10 +664,7 @@
         final int port;
 
         if (address == null) {
-            if (IIOPHelper.isStub(rmiServer))
-                protocol = "iiop";
-            else
-                protocol = "rmi";
+            protocol = "rmi";
             host = null; // will default to local host name
             port = 0;
         } else {
@@ -692,31 +678,12 @@
         address = new JMXServiceURL(protocol, host, port, urlPath);
     }
 
-    static boolean isIiopURL(JMXServiceURL directoryURL, boolean strict)
-        throws MalformedURLException {
-        String protocol = directoryURL.getProtocol();
-        if (protocol.equals("rmi"))
-            return false;
-        else if (protocol.equals("iiop"))
-            return true;
-        else if (strict) {
-
-            throw new MalformedURLException("URL must have protocol " +
-                                            "\"rmi\" or \"iiop\": \"" +
-                                            protocol + "\"");
-        }
-        return false;
-    }
-
     /**
      * Returns the IOR of the given rmiServer.
      **/
     static String encodeStub(
             RMIServer rmiServer, Map<String, ?> env) throws IOException {
-        if (IIOPHelper.isStub(rmiServer))
-            return "/ior/" + encodeIIOPStub(rmiServer, env);
-        else
-            return "/stub/" + encodeJRMPStub(rmiServer, env);
+        return "/stub/" + encodeJRMPStub(rmiServer, env);
     }
 
     static String encodeJRMPStub(
@@ -730,17 +697,6 @@
         return byteArrayToBase64(bytes);
     }
 
-    static String encodeIIOPStub(
-            RMIServer rmiServer, Map<String, ?> env)
-            throws IOException {
-        try {
-            Object orb = IIOPHelper.getOrb(rmiServer);
-            return IIOPHelper.objectToString(orb, rmiServer);
-        } catch (RuntimeException x) {
-            throw newIOException(x.getMessage(), x);
-        }
-    }
-
     /**
      * Object that we will bind to the registry.
      * This object is a stub connected to our RMIServerImpl.
@@ -748,8 +704,7 @@
     private static RMIServer objectToBind(
             RMIServerImpl rmiServer, Map<String, ?> env)
         throws IOException {
-        return RMIConnector.
-            connectStub((RMIServer)rmiServer.toStub(),env);
+        return (RMIServer)rmiServer.toStub();
     }
 
     private static RMIServerImpl newJRMPServer(Map<String, ?> env, int port)
@@ -761,11 +716,6 @@
         return new RMIJRMPServerImpl(port, csf, ssf, env);
     }
 
-    private static RMIServerImpl newIIOPServer(Map<String, ?> env)
-            throws IOException {
-        return new RMIIIOPServerImpl(env);
-    }
-
     private static String byteArrayToBase64(byte[] a) {
         int aLen = a.length;
         int numFullGroups = aLen/3;
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIIIOPServerImpl.java	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIIIOPServerImpl.java	Tue Sep 08 16:10:36 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,16 +27,9 @@
 
 import java.io.IOException;
 import java.rmi.Remote;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
 import java.util.Map;
-import java.util.Collections;
 import javax.security.auth.Subject;
 
-import com.sun.jmx.remote.internal.IIOPHelper;
-
 /**
  * <p>An {@link RMIServerImpl} that is exported through IIOP and that
  * creates client connections as RMI objects exported through IIOP.
@@ -45,120 +38,59 @@
  * @see RMIServerImpl
  *
  * @since 1.5
+ * @deprecated This transport is no longer supported.
  */
+@Deprecated
 public class RMIIIOPServerImpl extends RMIServerImpl {
     /**
-     * <p>Creates a new {@link RMIServerImpl}.</p>
+     * Throws {@linkplain UnsupportedOperationException}
      *
      * @param env the environment containing attributes for the new
      * <code>RMIServerImpl</code>.  Can be null, which is equivalent
      * to an empty Map.
      *
-     * @exception IOException if the RMI object cannot be created.
+     * @throws IOException if the RMI object cannot be created.
      */
     public RMIIIOPServerImpl(Map<String,?> env)
             throws IOException {
         super(env);
 
-        this.env = (env == null) ? Collections.<String, Object>emptyMap() : env;
-
-        callerACC = AccessController.getContext();
+        throw new UnsupportedOperationException();
     }
 
+    @Override
     protected void export() throws IOException {
-        IIOPHelper.exportObject(this);
+        throw new UnsupportedOperationException("Method not supported. JMX RMI-IIOP is deprecated");
     }
 
+    @Override
     protected String getProtocol() {
         return "iiop";
     }
 
-    /**
-     * <p>Returns an IIOP stub.</p>
-     * The stub might not yet be connected to the ORB. The stub will
-     * be serializable only if it is connected to the ORB.
-     * @return an IIOP stub.
-     * @exception IOException if the stub cannot be created - e.g the
-     *            RMIIIOPServerImpl has not been exported yet.
-     **/
+    @Override
     public Remote toStub() throws IOException {
-        // javax.rmi.CORBA.Stub stub =
-        //    (javax.rmi.CORBA.Stub) PortableRemoteObject.toStub(this);
-        final Remote stub = IIOPHelper.toStub(this);
-        // java.lang.System.out.println("NON CONNECTED STUB " + stub);
-        // org.omg.CORBA.ORB orb =
-        //    org.omg.CORBA.ORB.init((String[])null, (Properties)null);
-        // stub.connect(orb);
-        // java.lang.System.out.println("CONNECTED STUB " + stub);
-        return stub;
+        throw new UnsupportedOperationException();
     }
 
-    /**
-     * <p>Creates a new client connection as an RMI object exported
-     * through IIOP.
-     *
-     * @param connectionId the ID of the new connection.  Every
-     * connection opened by this connector server will have a
-     * different ID.  The behavior is unspecified if this parameter is
-     * null.
-     *
-     * @param subject the authenticated subject.  Can be null.
-     *
-     * @return the newly-created <code>RMIConnection</code>.
-     *
-     * @exception IOException if the new client object cannot be
-     * created or exported.
-     */
+    @Override
     protected RMIConnection makeClient(String connectionId, Subject subject)
             throws IOException {
-
-        if (connectionId == null)
-            throw new NullPointerException("Null connectionId");
-
-        RMIConnection client =
-            new RMIConnectionImpl(this, connectionId, getDefaultClassLoader(),
-                                  subject, env);
-        IIOPHelper.exportObject(client);
-        return client;
+        throw new UnsupportedOperationException();
     }
 
+    @Override
     protected void closeClient(RMIConnection client) throws IOException {
-        IIOPHelper.unexportObject(client);
+        throw new UnsupportedOperationException();
     }
 
-    /**
-     * <p>Called by {@link #close()} to close the connector server by
-     * unexporting this object.  After returning from this method, the
-     * connector server must not accept any new connections.</p>
-     *
-     * @exception IOException if the attempt to close the connector
-     * server failed.
-     */
+    @Override
     protected void closeServer() throws IOException {
-        IIOPHelper.unexportObject(this);
+        throw new UnsupportedOperationException();
     }
 
     @Override
     RMIConnection doNewClient(final Object credentials) throws IOException {
-        if (callerACC == null) {
-            throw new SecurityException("AccessControlContext cannot be null");
-        }
-        try {
-            return AccessController.doPrivileged(
-                new PrivilegedExceptionAction<RMIConnection>() {
-                    public RMIConnection run() throws IOException {
-                        return superDoNewClient(credentials);
-                    }
-            }, callerACC);
-        } catch (PrivilegedActionException pae) {
-            throw (IOException) pae.getCause();
-        }
+        throw new UnsupportedOperationException();
     }
-
-    RMIConnection superDoNewClient(Object credentials) throws IOException {
-        return super.doNewClient(credentials);
-    }
-
-    private final Map<String, ?> env;
-    private final AccessControlContext callerACC;
 }
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIServerImpl.java	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/src/java.management/share/classes/javax/management/remote/rmi/RMIServerImpl.java	Tue Sep 08 16:10:36 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -61,8 +61,7 @@
  * or by instantiating {@link RMIConnector}.</p>
  *
  * <p>This is an abstract class.  Concrete subclasses define the
- * details of the client connection objects, such as whether they use
- * JRMP or IIOP.</p>
+ * details of the client connection objects.</p>
  *
  * @since 1.5
  */
@@ -307,7 +306,7 @@
 
     /**
      * <p>Returns the protocol string for this object.  The string is
-     * <code>rmi</code> for RMI/JRMP and <code>iiop</code> for RMI/IIOP.
+     * <code>rmi</code> for RMI/JRMP.
      *
      * @return the protocol string for this object.
      */
--- a/jdk/src/java.management/share/classes/javax/management/remote/rmi/package.html	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/src/java.management/share/classes/javax/management/remote/rmi/package.html	Tue Sep 08 16:10:36 2015 +0200
@@ -2,7 +2,7 @@
 <head>
     <title>RMI connector</title>
 <!--
-Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
+Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 
 This code is free software; you can redistribute it and/or modify it
@@ -36,16 +36,14 @@
       that different implementations of the RMI connector can
       interoperate.</p>
 
-    <p>The RMI connector supports the JRMP transport for RMI, and
-      optionally the IIOP transport.</p>
+    <p>The RMI connector supports the JRMP transport for RMI.</p>
 
     <p>Like most connectors in the JMX Remote API, an RMI connector
       usually has an address, which
       is a {@link javax.management.remote.JMXServiceURL
       JMXServiceURL}.  The protocol part of this address is
       <code>rmi</code> for a connector that uses the default RMI
-      transport (JRMP), or <code>iiop</code> for a connector that
-      uses RMI/IIOP.</p>
+      transport (JRMP).</p>
 
     <p>There are two forms for RMI connector addresses:</p>
 
@@ -65,10 +63,9 @@
 	information needed to connect to the connector server.  When
 	using RMI/JRMP, the encoded form is the serialized RMI stub
 	for the server object, encoded using BASE64 without embedded
-	newlines.  When using RMI/IIOP, the encoded form is the CORBA
-	IOR for the server object.
+	newlines.
     </ul>
-    
+
     <p>Addresses are covered in more detail below.</p>
 
 
@@ -91,9 +88,8 @@
 
     <h4>Choosing the RMI transport</h4>
 
-    <p>You can choose the RMI transport (JRMP or IIOP) by specifying
-      <code>rmi</code> or <code>iiop</code> in the
-      <code><em>protocol</em></code> part of the
+    <p>You can choose the RMI transport by specifying
+      <code>rmi</code> in the <code><em>protocol</em></code> part of the
       <code>serviceURL</code> when creating the connector server.  You
       can also create specialized connector servers by instantiating
       an appropriate subclass of {@link
@@ -132,33 +128,9 @@
 	stub for the generated object, encoded in BASE64 without
 	newlines.</p>
 
-      <li><p>If the <code>serviceURL</code> looks like:</p>
-
-	<pre>
-	<code>service:jmx:iiop://<em>host</em>:<em>port</em></code>
-	</pre>
-	
-	<p>then the connector server will generate an {@link
-	javax.management.remote.rmi.RMIIIOPServerImpl
-	RMIIIOPServerImpl} and the returned
-	<code>JMXServiceURL</code> looks like:</p>
-
-	<pre>
-	<code>service:jmx:iiop://<em>host</em>:<em>port</em>/ior/IOR:<em>XXXX</em></code>
-	</pre>
-
-	<p>where <code>IOR:<em>XXXX</em></code> is the standard CORBA
-	encoding of the Interoperable Object Reference for the
-	generated object.</p>
-
       <li><p>If there is no <code>serviceURL</code>, there must be a
-	user-provided <code>RMIServerImpl</code>.  If the {@link
-	javax.management.remote.rmi.RMIServerImpl#toStub toStub}
-	method on this object returns an instance of {@link
-	javax.rmi.CORBA.Stub}, then the connector server will generate
-	a <code>JMXServiceURL</code> using the <code>iiop</code>
-	form above.  Otherwise, it will generate a
-	<code>JMXServiceURL</code> using the <code>rmi</code>
+	user-provided <code>RMIServerImpl</code>.  The connector server
+        will generate a <code>JMXServiceURL</code> using the <code>rmi</code>
 	form.</p>
 
     </ul>
@@ -195,12 +167,10 @@
       stub.  This directory address is then used by both client and
       server.</p>
 
-    <p>In this case, the <code>serviceURL</code> has one of these two
-      forms:</p>
+    <p>In this case, the <code>serviceURL</code> has the following form:</p>
 
     <pre>
     <code>service:jmx:rmi://<em>host</em>:<em>port</em>/jndi/<em>jndi-name</em></code>
-    <code>service:jmx:iiop://<em>host</em>:<em>port</em>/jndi/<em>jndi-name</em></code>
     </pre>
 
     <p>Here, <code><em>jndi-name</em></code> is a string that can be
@@ -212,8 +182,7 @@
 
     <p>The connector server will generate an
       <code>RMIServerImpl</code> based on the protocol
-      (<code>rmi</code> or <code>iiop</code>) and, for
-      <code>rmi</code>, the <code><em>port</em></code> if any.  When
+      (<code>rmi</code>) and the <code><em>port</em></code> if any.  When
       the connector server is started, it will derive a stub from this
       object using its {@link
       javax.management.remote.rmi.RMIServerImpl#toStub toStub} method
@@ -250,11 +219,11 @@
     <p>As another example, if the <code>JMXServiceURL</code> is:
 
       <pre>
-      <code>service:jmx:iiop://ignoredhost/jndi/ldap://dirhost:9999/cn=this,ou=that</code>
+      <code>service:jmx:rmi://ignoredhost/jndi/ldap://dirhost:9999/cn=this,ou=that</code>
       </pre>
 
       then the connector server will generate an
-      <code>RMIIIOPServerImpl</code> and store its stub using the JNDI
+      <code>RMIJRMPServerImpl</code> and store its stub using the JNDI
       name
 
       <pre>
@@ -267,11 +236,11 @@
     <p>If the <code>JMXServiceURL</code> is:
 
       <pre>
-      <code>service:jmx:iiop://ignoredhost/jndi/cn=this,ou=that</code>
+      <code>service:jmx:rmi://ignoredhost/jndi/cn=this,ou=that</code>
       </pre>
 
       then the connector server will generate an
-      <code>RMIIIOPServerImpl</code> and store its stub using the JNDI
+      <code>RMIJRMPServerImpl</code> and store its stub using the JNDI
       name
 
       <pre>
@@ -287,7 +256,7 @@
       omitted, for example:</p>
 
       <pre>
-      <code>service:jmx:iiop:///jndi/cn=this,ou=that</code>
+      <code>service:jmx:rmi:///jndi/cn=this,ou=that</code>
       </pre>
 
     <p>However, it is good practice to use the name of the host
@@ -313,8 +282,7 @@
 
     <p>An RMI connector client is usually constructed using {@link
       javax.management.remote.JMXConnectorFactory}, with a
-      <code>JMXServiceURL</code> that has <code>rmi</code> or
-      <code>iiop</code> as its protocol.</p>
+      <code>JMXServiceURL</code> that has <code>rmi</code> as its protocol.</p>
 
     <p>If the <code>JMXServiceURL</code> was generated by the server,
       as described above under <a href="#servergen">"connector
@@ -343,37 +311,6 @@
       constructor of {@link javax.management.remote.rmi.RMIConnector
       RMIConnector}.</p>
 
-
-    <h3>Specifying an ORB for the RMI/IIOP connector</h3>
-
-    <p>When using the IIOP transport, the client and server can
-      specify what ORB to use
-      with the attribute <code>java.naming.corba.orb</code>.
-      Connection to the ORB happens at {@link 
-      javax.management.remote.rmi.RMIConnectorServer#start() start} time 
-      for the connector server, and at {@link 
-      javax.management.remote.rmi.RMIConnector#connect(java.util.Map) 
-      connect} time for the connector client.
-      If the <code>java.naming.corba.orb</code> attribute is contained
-      in the environment Map, then its value (an {@link 
-      org.omg.CORBA.ORB ORB}), is used to connect the IIOP Stubs. 
-      Otherwise, a new org.omg.CORBA.ORB is created by calling {@link 
-      org.omg.CORBA.ORB
-      org.omg.CORBA.ORB.init((String[])null,(Properties)null)}.  A
-      later RMI connector client or server in the same JVM can reuse
-      this ORB, or it can create another one in the same way.</p>
-
-     <p>If the <code>java.naming.corba.orb</code> attribute is 
-      specified and does not point to an {@link org.omg.CORBA.ORB ORB},
-      then an <code>{@link java.lang.IllegalArgumentException}</code> 
-      will be thrown.</p>
-
-     <p>The mechanism described here does not apply when the IIOP
-      Remote objects (Stubs or Servers) are created and connected to
-      an ORB manually before being passed to the RMIConnector and
-      RMIConnectorServer.</p>
-
-
     <h3>Dynamic code downloading</h3>
 
     <p>If an RMI connector client or server receives from its peer an
@@ -385,7 +322,7 @@
     code downloading using Java RMI</em></a> explains this in more
     detail.</p>
 
- 
+
     @see <a href="{@docRoot}/../technotes/guides/rmi/index.html">
 	Java&trade; Remote Method
 	Invocation (RMI)</a>
--- a/jdk/test/TEST.groups	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/test/TEST.groups	Tue Sep 08 16:10:36 2015 +0200
@@ -67,6 +67,7 @@
     sun/misc \
     sun/reflect \
     jdk/lambda \
+    jdk/internal/jimage \
     vm
 
 # All of the java.util package
@@ -210,13 +211,13 @@
 
 # java launcher specific tests, Note: do not include this group into any groups
 # that potentially could be included into a jprt test rule, as the complementary
-# closed  group includes awt SplashScreen and these tests may not run 
-# satisfacotorily on all platforms and  profiles thus this group must always 
+# closed  group includes awt SplashScreen and these tests may not run
+# satisfactorily on all platforms and  profiles thus this group must always
 # be a stand-alone group
 jdk_launcher = \
     tools/launcher \
     sun/tools
-    
+
 #
 # Tool (and tool API) tests are split into core and svc groups
 #
@@ -473,7 +474,7 @@
   sun/reflect/CallerSensitive/MissingCallerSensitive.java \
   sun/security/util/Resources/NewNamesFormat.java \
   vm/verifier/defaultMethods/DefaultMethodRegressionTestsRun.java \
-  javax/xml/ws/clientjar/TestWsImport.java 
+  javax/xml/ws/clientjar/TestWsImport.java
 
 # JRE adds further tests to compact3
 #
--- a/jdk/test/javax/management/remote/mandatory/connection/CloseableTest.java	Thu Sep 03 15:48:24 2015 -0700
+++ b/jdk/test/javax/management/remote/mandatory/connection/CloseableTest.java	Tue Sep 08 16:10:36 2015 +0200
@@ -40,7 +40,6 @@
 import javax.management.remote.rmi.RMIConnectionImpl;
 import javax.management.remote.rmi.RMIConnectionImpl_Stub;
 import javax.management.remote.rmi.RMIConnector;
-import javax.management.remote.rmi.RMIIIOPServerImpl;
 import javax.management.remote.rmi.RMIJRMPServerImpl;
 import javax.management.remote.rmi.RMIServerImpl;
 
@@ -52,7 +51,6 @@
         RMIConnectionImpl.class,
         RMIConnectionImpl_Stub.class,
         RMIServerImpl.class,
-        RMIIIOPServerImpl.class,
         RMIJRMPServerImpl.class
     };
 
--- a/jdk/test/javax/management/remote/mandatory/connection/NoIIOP.java	Thu Sep 03 15:48:24 2015 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +0,0 @@
-/*
- * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/* @test
- * @bug 8004502
- * @summary Sanity check that attempts to use the IIOP transport or
- *   RMIIIOPServerImpl when RMI/IIOP not present throws the expected exceptions
- * @modules java.management
- */
-
-import javax.management.MBeanServer;
-import javax.management.MBeanServerFactory;
-import javax.management.remote.*;
-import javax.management.remote.rmi.*;
-import java.net.MalformedURLException;
-import java.io.IOException;
-import javax.security.auth.Subject;
-import java.rmi.NoSuchObjectException;
-import javax.management.remote.JMXConnectorFactory;
-import javax.management.remote.JMXConnectorServerFactory;
-
-public class NoIIOP {
-
-    /**
-     * RMIIIOPServerImpl implementation for testing purposes (methods are
-     * overridden to be public to allow for testing)
-     */
-    static class MyRMIIIOPServerImpl extends RMIIIOPServerImpl {
-        MyRMIIIOPServerImpl() throws IOException {
-            super(null);
-        }
-        @Override
-        public void export() throws IOException {
-            super.export();
-        }
-        @Override
-        public String getProtocol() {
-            return super.getProtocol();
-        }
-        @Override
-        public RMIConnection makeClient(String connectionId, Subject subject)
-            throws IOException
-        {
-            return super.makeClient(connectionId, subject);
-        }
-        @Override
-        public void closeClient(RMIConnection client) throws IOException {
-            super.closeClient(client);
-        }
-        @Override
-        public void closeServer() throws IOException {
-            super.closeServer();
-        }
-    }
-
-
-    public static void main(String[] args) throws Exception {
-        try {
-            Class.forName("javax.management.remote.rmi._RMIConnectionImpl_Tie");
-            System.out.println("RMI/IIOP appears to be supported, test skipped");
-            return;
-        } catch (ClassNotFoundException okay) { }
-
-        JMXServiceURL url = new JMXServiceURL("service:jmx:iiop://");
-        MBeanServer mbs = MBeanServerFactory.createMBeanServer();
-
-
-        // test JMXConnectorFactory/JMXConnectorServerFactory
-
-        try {
-            JMXConnectorFactory.connect(url);
-            throw new RuntimeException("connect did not throw MalformedURLException");
-        } catch (MalformedURLException expected) { }
-
-        try {
-            JMXConnectorServerFactory.newJMXConnectorServer(url, null, null);
-            throw new RuntimeException("newJMXConnectorServer did not throw MalformedURLException");
-        } catch (MalformedURLException expected) { }
-
-
-        // test RMIConnector/RMIConnectorServer
-
-        RMIConnector connector = new RMIConnector(url, null);
-        try {
-            connector.connect();
-            throw new RuntimeException("connect did not throw IOException");
-        } catch (IOException expected) { }
-
-        RMIConnectorServer server = new RMIConnectorServer(url, null, mbs);
-        try {
-            server.start();
-            throw new RuntimeException("start did not throw IOException");
-        } catch (IOException expected) { }
-
-
-        // test RMIIIOPServerImpl
-
-        MyRMIIIOPServerImpl impl = new MyRMIIIOPServerImpl();
-        impl.setMBeanServer(mbs);
-        System.out.println(impl.getProtocol());
-
-        try {
-            impl.export();
-            throw new RuntimeException("export did not throw IOException");
-        } catch (IOException expected) { }
-
-        try {
-            impl.newClient(null);
-            throw new RuntimeException("newClient did not throw IOException");
-        } catch (IOException expected) { }
-
-        try {
-            impl.toStub();
-            throw new RuntimeException("toStub did not throw NoSuchObjectException");
-        } catch (NoSuchObjectException expected) { }
-
-        try {
-            impl.closeServer();
-            throw new RuntimeException("closeServer did not throw NoSuchObjectException");
-        } catch (NoSuchObjectException expected) { }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/internal/jimage/JImageReadTest.java	Tue Sep 08 16:10:36 2015 +0200
@@ -0,0 +1,377 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @modules java.base/jdk.internal.jimage
+ * @summary Unit test for libjimage JIMAGE_Open/Read/Close
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+import jdk.internal.jimage.BasicImageReader;
+import jdk.internal.jimage.ImageNativeSubstrate;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Optional;
+import org.testng.annotations.Parameters;
+import org.testng.annotations.Test;
+import org.testng.Assert;
+import org.testng.TestNG;
+
+@Test
+public class JImageReadTest {
+
+    static String javaHome = System.getProperty("java.home");
+    static String imageFile = javaHome + File.separator + "lib"
+            + File.separator + "modules" + File.separator
+            + "bootmodules.jimage";
+
+    @DataProvider(name="classes")
+    static Object[][] loadClasses() {
+        return new Object[][] {
+                {"java.base", "java/lang/String.class"},
+                {"java.base", "java/lang/Object.class"},
+                {"java.base", "sun/reflect/generics/tree/TypeArgument.class"},
+                {"jdk.jdeps", "com/sun/tools/javap/StackMapWriter$StackMapBuilder.class"},
+                {"jdk.hotspot.agent", "sa.properties"},
+                {"java.logging", "java/util/logging/Logger.class"},
+                {"java.base", "java/NOSUCHCLASS/yyy.class"},    // non-existent
+                {"NOSUCHMODULE", "java/lang/Class.class"},    // non-existent
+        };
+    }
+
+
+    @DataProvider(name="packages")
+    static Object[][] loadPackages() {
+        return new Object[][] {
+                {"java.base", "java/lang"},
+                {"java.base", "java/io"},
+                {"java.logging", "java/util/logging"},
+        };
+    }
+
+    /**
+     * Test a class is correctly accessible from the image in a module.
+     *
+     * @param moduleName the module name
+     * @param className the classname
+     * @throws Exception is thrown if there is a test error
+     */
+    @Test(dataProvider="classes")
+    public static void test1_ReadClasses(String moduleName, String className) throws Exception {
+        final int classMagic = 0xCAFEBABE;
+        final long NOT_FOUND = 0L;
+
+        if (!(new File(imageFile)).exists()) {
+            System.out.printf("Test skipped; no jimage file");
+            return;
+        }
+
+        long jimageHandle = ImageNativeSubstrate.JIMAGE_Open(imageFile);
+        Assert.assertTrue(jimageHandle != 0, "JIMAGE_Open failed: id: " + jimageHandle);
+
+        long[] sizeArray = new long[1];
+        long locationHandle =
+                ImageNativeSubstrate.JIMAGE_FindResource(jimageHandle,
+                moduleName, "9.0", className, sizeArray);
+        long size = sizeArray[0];
+        System.out.printf("reading: module: %s, path: %s, handle: %16x, " +
+                        "location: %d, size: %d%n",
+                moduleName, className, jimageHandle, locationHandle, size);
+        if (moduleName.contains("NOSUCH") || className.contains("NOSUCH")) {
+            Assert.assertEquals(locationHandle, NOT_FOUND,
+                    "location found for non-existing module: "
+                    + moduleName
+                    + ", or class: " + className);
+            return;         // no more to test for non-existing class
+        } else {
+            Assert.assertTrue(locationHandle != NOT_FOUND, "location not found: " + className);
+            Assert.assertTrue(size > 0, "size of should be > 0: " + className);
+        }
+
+        // positive: read whole class
+        ByteBuffer buffer = ByteBuffer.allocate((int)size);
+        long actual = ImageNativeSubstrate.JIMAGE_GetResource(jimageHandle,
+                locationHandle, buffer.array(), size);
+        Assert.assertEquals(actual, size, "bytes read not equal bytes requested");
+
+        if (className.endsWith(".class")) {
+            int m = buffer.getInt();
+            Assert.assertEquals(m, classMagic, "Classfile has bad magic number");
+        }
+
+        // Read less than the size of the artifact
+        buffer.rewind();
+        Arrays.fill(buffer.array(), (byte)0xc0);
+        long sizeExpected = size - 10;
+        actual = ImageNativeSubstrate.JIMAGE_GetResource(jimageHandle,
+                locationHandle, buffer.array(), sizeExpected);
+        Assert.assertEquals(actual, sizeExpected, "bytes read not equal bytes requested");
+
+        if (className.endsWith(".class")) {
+            int m1 = buffer.getInt();
+            Assert.assertEquals(m1, classMagic, "Read operation succeeded but has bad magic number");
+        }
+
+        ImageNativeSubstrate.JIMAGE_Close(jimageHandle);
+    }
+
+    /**
+     * For all the resource names, check the name and approximate count.
+     *
+     * @throws IOException thrown if an error occurs
+     */
+    @Test
+    static void test2_ImageResources() throws IOException {
+        if (!(new File(imageFile)).exists()) {
+            System.out.printf("Test skipped; no jimage file");
+            return;
+        }
+
+        long jimageHandle = ImageNativeSubstrate.JIMAGE_Open(imageFile);
+        Assert.assertTrue(jimageHandle != 0, "JIMAGE_Open failed: id: " + jimageHandle);
+
+        String[] names = new String[4096];
+        int max = ImageNativeSubstrate.JIMAGE_Resources(jimageHandle,
+                names);
+
+        // Repeat with count available
+        names = new String[max + 1];
+        int count = ImageNativeSubstrate.JIMAGE_Resources(jimageHandle,
+                names);
+        System.out.printf(" count: %d, a class: %s\n", count, names[0]);
+        Assert.assertTrue(max > 31000,
+                "missing entries, should be more than 31000, reported: " + count);
+        Assert.assertTrue(count == max,
+                "unexpected count of entries, count: " + count
+                        + ", max: " + max);
+        for (int i = 0; i < count; i++) {
+            checkFullName(names[i]);
+        }
+
+        ImageNativeSubstrate.JIMAGE_Close(jimageHandle);
+    }
+
+    /**
+     * Tests that a package exists and correctly mapped to the module.
+     *
+     * @param moduleName the module name
+     * @param packageName the package name
+     * @throws IOException thrown if an error occurs
+     */
+    @Test(dataProvider="packages")
+    static void test3_PackageToModule(String moduleName, String packageName) throws IOException {
+        if (!(new File(imageFile)).exists()) {
+            System.out.printf("Test skipped; no jimage file");
+            return;
+        }
+
+        long jimageHandle = ImageNativeSubstrate.JIMAGE_Open(imageFile);
+        Assert.assertTrue(jimageHandle != 0, "JIMAGE_Open failed: id: " + jimageHandle);
+
+        String result = ImageNativeSubstrate.JIMAGE_PackageToModule(jimageHandle, packageName);
+        System.out.printf(" package: %s, module: %s%n", packageName, result);
+        Assert.assertEquals(result, moduleName, "wrong module for package: " + packageName);
+
+        ImageNativeSubstrate.JIMAGE_Close(jimageHandle);
+    }
+
+
+    static void checkFullName(String path) {
+        int next = 0;
+        String m = null;
+        String p = null;
+        String b = null;
+        String e = null;
+        if (path.startsWith("/")) {
+            next = path.indexOf('/', 1);
+            m = path.substring(1, next);
+            next = next + 1;
+        }
+        int lastSlash = path.lastIndexOf('/');
+        if (lastSlash > next) {
+            // has a parent
+            p = path.substring(next, lastSlash);
+            next = lastSlash + 1;
+        }
+        int period = path.indexOf('.', next);
+        if (period > next) {
+            b = path.substring(next, period);
+            e = path.substring(period + 1);
+        } else {
+            b = path.substring(next);
+        }
+        Assert.assertNotNull(m, "module must be non-empty");
+        Assert.assertNotNull(b, "base name must be non-empty");
+    }
+
+    /**
+     * Verify that all of the resource names from BasicImageReader
+     * match those returned from the native JIMAGE_Resources iterator.
+     * Names that start with /modules, /packages, and bootmodules.jdata
+     * must appear in the names from JIMAGE_Resource iterator;
+     * from the BasicImageReader they are ignored.
+     */
+    @Test
+    static void test4_verifyNames() {
+        if (!(new File(imageFile)).exists()) {
+            System.out.printf("Test skipped; no jimage file");
+            return;
+        }
+
+        try {
+            String[] names = BasicImageReader_Names();
+            //writeNames("/tmp/basic-names.txt", names);              // debug
+
+            // Read all the names from the native JIMAGE API
+            String[] nativeNames = JIMAGE_Names();
+            //writeNames("/tmp/native-names.txt", nativeNames);       // debug
+
+
+            int modCount = 0;
+            int pkgCount = 0;
+            int otherCount = 0;
+            for (String n : nativeNames) {
+                if (n.startsWith("/modules/")) {
+                    modCount++;
+                } else if (n.startsWith("/packages/")) {
+                    pkgCount++;
+                } else {
+                    otherCount++;
+                }
+            }
+            System.out.printf("native name count: %d, modCount: %d, pkgCount: %d, otherCount: %d%n",
+                    names.length, modCount, pkgCount, otherCount);
+
+            Assert.assertEquals(modCount, 0, "JIMAGE_ResourceIterator should not return any '/modules' paths");
+            Assert.assertEquals(pkgCount, 0, "JIMAGE_ResourceIterator should not return any '/packages' paths");
+
+            // Sort and merge the two arrays.  Every name should appear exactly twice.
+            Arrays.sort(names);
+            Arrays.sort(nativeNames);
+            String[] combined = Arrays.copyOf(names, nativeNames.length + names.length);
+            System.arraycopy(nativeNames,0, combined, names.length, nativeNames.length);
+            Arrays.sort(combined);
+            int missing = 0;
+            for (int i = 0; i < combined.length; i++) {
+                String s = combined[i];
+                if (isMetaName(s)) {
+                    // Ignore /modules and /packages in BasicImageReader names
+                    continue;
+                }
+
+                if (i < combined.length - 1 && s.equals(combined[i + 1])) {
+                    i++;        // string appears in both java and native
+                    continue;
+                }
+
+                missing++;
+                int ndx = Arrays.binarySearch(names, s);
+                String which = (ndx >= 0) ? "java BasicImageReader" : "native JIMAGE_Resources";
+                System.out.printf("Missing Resource: %s found only via %s%n", s, which);
+            }
+            Assert.assertEquals(missing, 0, "Resources missing");
+
+        } catch (IOException ioe) {
+            Assert.fail("I/O exception", ioe);
+        }
+    }
+
+    /**
+     * Return true if the name is one of the meta-data names
+     * @param name a name
+     * @return return true if starts with either /packages or /modules
+     */
+    static boolean isMetaName(String name) {
+        return name.startsWith("/modules")
+                || name.startsWith("/packages")
+                || name.equals("bootmodules.jdata");
+    }
+
+    /**
+     * Return all of the names from BasicImageReader.
+     * @return the names returned from BasicImageReader
+     */
+    static String[] BasicImageReader_Names() throws IOException {
+        String[] names = null;
+        try (BasicImageReader reader = BasicImageReader.open(imageFile)) {
+            names = reader.getEntryNames();
+        } catch (IOException ioe) {
+            Assert.fail("I/O exception", ioe);
+        }
+        return names;
+    }
+
+    /**
+     * Returns an array of all of the names returned from JIMAGE_Resources
+     */
+    static String[] JIMAGE_Names() throws IOException {
+
+        long jimageHandle = ImageNativeSubstrate.JIMAGE_Open(imageFile);
+        Assert.assertTrue(jimageHandle != 0, "JIMAGE_Open failed: id: " + jimageHandle);
+
+        String[] names = new String[50000];
+        int max = ImageNativeSubstrate.JIMAGE_Resources(jimageHandle, names);
+
+        if (max > names.length) {
+            // Not all names fit, repeat with correct size
+            names = new String[max];
+            max = ImageNativeSubstrate.JIMAGE_Resources(jimageHandle, names);
+        } else {
+            names = Arrays.copyOf(names, max);
+        }
+
+        ImageNativeSubstrate.JIMAGE_Close(jimageHandle);
+        return names;
+    }
+
+    // Write an array of names to a file for debugging
+    static void writeNames(String fname, String[] names) throws IOException {
+        try (FileWriter wr = new FileWriter(new File(fname))) {
+            for (String s : names) {
+                wr.write(s);
+                wr.write("\n");
+            }
+
+        }
+        System.out.printf(" %s: %d names%n", fname, names.length);
+    }
+
+    // main method to run standalone from jtreg
+
+    @Test(enabled=false)
+    @Parameters({"x"})
+    @SuppressWarnings("raw_types")
+    public static void main(@Optional String[] args) {
+        Class<?>[] testclass = { JImageReadTest.class};
+        TestNG testng = new TestNG();
+        testng.setTestClasses(testclass);
+        testng.run();
+    }
+
+}