提交 ca754cfe 编写于 作者: M mchung

6612680: Remove classloader dependency on jkernel

Summary: Add a new sun.misc.BootClassLoaderHook that DownloadManager will implement
Reviewed-by: alanb, forax, igor
上级 c73ffeb6
...@@ -35,10 +35,6 @@ include $(BUILDDIR)/common/Defs.gmk ...@@ -35,10 +35,6 @@ include $(BUILDDIR)/common/Defs.gmk
# #
_OPT = $(CC_HIGHEST_OPT) _OPT = $(CC_HIGHEST_OPT)
# This re-directs all the class files to a separate location
CLASSDESTDIR = $(TEMPDIR)/classes
# #
# Java source files # Java source files
# #
......
...@@ -58,6 +58,8 @@ import java.util.StringTokenizer; ...@@ -58,6 +58,8 @@ import java.util.StringTokenizer;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import sun.misc.BootClassLoaderHook;
/** /**
* A representation of color profile data for device independent and * A representation of color profile data for device independent and
* device dependent color spaces based on the International Color * device dependent color spaces based on the International Color
...@@ -1850,11 +1852,10 @@ public class ICC_Profile implements Serializable { ...@@ -1850,11 +1852,10 @@ public class ICC_Profile implements Serializable {
f = new File(fullPath); f = new File(fullPath);
if (!f.isFile()) { if (!f.isFile()) {
//make sure file was installed in the kernel mode //make sure file was installed in the kernel mode
try { BootClassLoaderHook hook = BootClassLoaderHook.getHook();
//kernel uses platform independent paths => if (hook.getHook() != null) {
// should not use platform separator char hook.prefetchFile("lib/cmm/"+fileName);
sun.jkernel.DownloadManager.downloadFile("lib/cmm/"+fileName); }
} catch (IOException ioe) {}
} }
} }
......
...@@ -51,6 +51,7 @@ import java.util.Vector; ...@@ -51,6 +51,7 @@ import java.util.Vector;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import sun.misc.BootClassLoaderHook;
import sun.misc.ClassFileTransformer; import sun.misc.ClassFileTransformer;
import sun.misc.CompoundEnumeration; import sun.misc.CompoundEnumeration;
import sun.misc.Resource; import sun.misc.Resource;
...@@ -58,7 +59,6 @@ import sun.misc.URLClassPath; ...@@ -58,7 +59,6 @@ import sun.misc.URLClassPath;
import sun.misc.VM; import sun.misc.VM;
import sun.reflect.Reflection; import sun.reflect.Reflection;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
import sun.jkernel.DownloadManager;
/** /**
* A class loader is an object that is responsible for loading classes. The * A class loader is an object that is responsible for loading classes. The
...@@ -1300,21 +1300,7 @@ public abstract class ClassLoader { ...@@ -1300,21 +1300,7 @@ public abstract class ClassLoader {
* Find resources from the VM's built-in classloader. * Find resources from the VM's built-in classloader.
*/ */
private static URL getBootstrapResource(String name) { private static URL getBootstrapResource(String name) {
try { BootClassLoaderHook.preLoadResource(name);
// If this is a known JRE resource, ensure that its bundle is
// downloaded. If it isn't known, we just ignore the download
// failure and check to see if we can find the resource anyway
// (which is possible if the boot class path has been modified).
if (sun.misc.VM.isBootedKernelVM()) {
sun.jkernel.DownloadManager.getBootClassPathEntryForResource(
name);
}
} catch (NoClassDefFoundError e) {
// This happens while Java itself is being compiled; DownloadManager
// isn't accessible when this code is first invoked. It isn't an
// issue, as if we can't find DownloadManager, we can safely assume
// that additional code is not available for download.
}
URLClassPath ucp = getBootstrapClassPath(); URLClassPath ucp = getBootstrapClassPath();
Resource res = ucp.getResource(name); Resource res = ucp.getResource(name);
return res != null ? res.getURL() : null; return res != null ? res.getURL() : null;
...@@ -1831,24 +1817,7 @@ public abstract class ClassLoader { ...@@ -1831,24 +1817,7 @@ public abstract class ClassLoader {
// Invoked in the java.lang.Runtime class to implement load and loadLibrary. // Invoked in the java.lang.Runtime class to implement load and loadLibrary.
static void loadLibrary(Class fromClass, String name, static void loadLibrary(Class fromClass, String name,
boolean isAbsolute) { boolean isAbsolute) {
try { BootClassLoaderHook.preLoadLibrary(name);
if (VM.isBootedKernelVM() && !DownloadManager.isJREComplete() &&
!DownloadManager.isCurrentThreadDownloading()) {
DownloadManager.downloadFile("bin/" +
System.mapLibraryName(name));
// it doesn't matter if the downloadFile call returns false --
// it probably just means that this is a user library, as
// opposed to a JRE library
}
} catch (IOException e) {
throw new UnsatisfiedLinkError("Error downloading library " +
name + ": " + e);
} catch (NoClassDefFoundError e) {
// This happens while Java itself is being compiled; DownloadManager
// isn't accessible when this code is first invoked. It isn't an
// issue, as if we can't find DownloadManager, we can safely assume
// that additional code is not available for download.
}
ClassLoader loader = ClassLoader loader =
(fromClass == null) ? null : fromClass.getClassLoader(); (fromClass == null) ? null : fromClass.getClassLoader();
if (sys_paths == null) { if (sys_paths == null) {
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
package java.util.zip; package java.util.zip;
import java.util.Date; import java.util.Date;
import sun.misc.BootClassLoaderHook;
/** /**
* This class is used to represent a ZIP file entry. * This class is used to represent a ZIP file entry.
...@@ -109,12 +110,16 @@ class ZipEntry implements ZipConstants, Cloneable { ...@@ -109,12 +110,16 @@ class ZipEntry implements ZipConstants, Cloneable {
* @see #getTime() * @see #getTime()
*/ */
public void setTime(long time) { public void setTime(long time) {
// fix for bug 6625963: we bypass time calculations while Kernel is // Same value as defined in sun.jkernel.DownloadManager.KERNEL_STATIC_MODTIME
// downloading bundles, since they aren't necessary and would cause // to avoid direct reference to DownoadManager class. Need to revisit
// the Kernel core to depend upon the (very large) time zone data // if this is needed any more (see comment in the DownloadManager class)
if (sun.misc.VM.isBootedKernelVM() && final int KERNEL_STATIC_MODTIME = 10000000;
sun.jkernel.DownloadManager.isCurrentThreadDownloading()) { BootClassLoaderHook hook = BootClassLoaderHook.getHook();
this.time = sun.jkernel.DownloadManager.KERNEL_STATIC_MODTIME; if (hook != null && hook.isCurrentThreadPrefetching()) {
// fix for bug 6625963: we bypass time calculations while Kernel is
// downloading bundles, since they aren't necessary and would cause
// the Kernel core to depend upon the (very large) time zone data
this.time = KERNEL_STATIC_MODTIME;
} else { } else {
this.time = javaToDosTime(time); this.time = javaToDosTime(time);
} }
......
...@@ -31,6 +31,7 @@ import java.util.concurrent.*; ...@@ -31,6 +31,7 @@ import java.util.concurrent.*;
import java.util.jar.*; import java.util.jar.*;
import java.util.zip.*; import java.util.zip.*;
import sun.misc.Launcher; import sun.misc.Launcher;
import sun.misc.BootClassLoaderHook;
/** /**
* Handles the downloading of additional JRE components. The bootstrap class * Handles the downloading of additional JRE components. The bootstrap class
...@@ -39,7 +40,7 @@ import sun.misc.Launcher; ...@@ -39,7 +40,7 @@ import sun.misc.Launcher;
* *
*@author Ethan Nicholas *@author Ethan Nicholas
*/ */
public class DownloadManager { public class DownloadManager extends BootClassLoaderHook {
public static final String KERNEL_DOWNLOAD_URL_PROPERTY = public static final String KERNEL_DOWNLOAD_URL_PROPERTY =
"kernel.download.url"; "kernel.download.url";
public static final String KERNEL_DOWNLOAD_ENABLED_PROPERTY = public static final String KERNEL_DOWNLOAD_ENABLED_PROPERTY =
...@@ -1023,7 +1024,8 @@ public class DownloadManager { ...@@ -1023,7 +1024,8 @@ public class DownloadManager {
/** /**
* Returns <code>true</code> if the current thread is in the process of * Returns <code>true</code> if the current thread is in the process of
* downloading a bundle. This is called by ClassLoader.loadLibrary(), so * downloading a bundle. This is called by DownloadManager.loadLibrary()
* that is called by System.loadLibrary(), so
* that when we run into a library required by the download process itself, * that when we run into a library required by the download process itself,
* we don't call back into DownloadManager in an attempt to download it * we don't call back into DownloadManager in an attempt to download it
* (which would lead to infinite recursion). * (which would lead to infinite recursion).
...@@ -1614,6 +1616,77 @@ public class DownloadManager { ...@@ -1614,6 +1616,77 @@ public class DownloadManager {
static native int getCurrentProcessId(); static native int getCurrentProcessId();
private DownloadManager() {
}
// Invoked by jkernel VM after the VM is initialized
static void setBootClassLoaderHook() {
if (!isJREComplete()) {
sun.misc.BootClassLoaderHook.setHook(new DownloadManager());
}
}
// Implementation of the BootClassLoaderHook interface
public String loadBootstrapClass(String name) {
// Check for download before we look for it. If
// DownloadManager ends up downloading it, it will add it to
// our search path before we proceed to the findClass().
return DownloadManager.getBootClassPathEntryForClass(name);
}
public boolean loadLibrary(String name) {
try {
if (!DownloadManager.isJREComplete() &&
!DownloadManager.isCurrentThreadDownloading()) {
return DownloadManager.downloadFile("bin/" +
System.mapLibraryName(name));
// it doesn't matter if the downloadFile call returns false --
// it probably just means that this is a user library, as
// opposed to a JRE library
}
} catch (IOException e) {
throw new UnsatisfiedLinkError("Error downloading library " +
name + ": " + e);
} catch (NoClassDefFoundError e) {
// This happens while Java itself is being compiled; DownloadManager
// isn't accessible when this code is first invoked. It isn't an
// issue, as if we can't find DownloadManager, we can safely assume
// that additional code is not available for download.
}
return false;
}
public boolean prefetchFile(String name) {
try {
return sun.jkernel.DownloadManager.downloadFile(name);
} catch (IOException ioe) {
return false;
}
}
public String getBootstrapResource(String name) {
try {
// If this is a known JRE resource, ensure that its bundle is
// downloaded. If it isn't known, we just ignore the download
// failure and check to see if we can find the resource anyway
// (which is possible if the boot class path has been modified).
return DownloadManager.getBootClassPathEntryForResource(name);
} catch (NoClassDefFoundError e) {
// This happens while Java itself is being compiled; DownloadManager
// isn't accessible when this code is first invoked. It isn't an
// issue, as if we can't find DownloadManager, we can safely assume
// that additional code is not available for download.
return null;
}
}
public File[] getAdditionalBootstrapPaths() {
return DownloadManager.getAdditionalBootStrapPaths();
}
public boolean isCurrentThreadPrefetching() {
return DownloadManager.isCurrentThreadDownloading();
}
public static void main(String[] arg) throws Exception { public static void main(String[] arg) throws Exception {
AccessController.checkPermission(new AllPermission()); AccessController.checkPermission(new AllPermission());
......
/*
* Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Sun designates this
* particular file as subject to the "Classpath" exception as provided
* by Sun in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
* CA 95054 USA or visit www.sun.com if you need additional information or
* have any questions.
*/
package sun.misc;
import java.io.File;
import java.io.IOException;
/**
* BootClassLoaderHook defines an interface for a hook to inject
* into the bootstrap class loader.
*
* In jkernel build, the sun.jkernel.DownloadManager is set as
* a BootClassLoaderHook by the jkernel VM after the VM is initialized.
*
* In other JDK builds, no hook is set.
*/
public abstract class BootClassLoaderHook {
private static BootClassLoaderHook bootLoaderHook = null;
public static synchronized BootClassLoaderHook getHook() {
return bootLoaderHook;
}
public static synchronized void setHook(BootClassLoaderHook hook) {
if (!VM.isBooted()) {
throw new InternalError("hook can only be set after VM is booted");
}
if (bootLoaderHook != null) {
throw new InternalError("hook should not be reinitialized");
}
bootLoaderHook = hook;
}
protected BootClassLoaderHook() {
}
/**
* A method to be invoked before a class loader loads
* a bootstrap class.
*
* @param classname the binary name of the class
*/
public static void preLoadClass(String classname) {
BootClassLoaderHook hook = getHook();
if (hook != null) {
hook.loadBootstrapClass(classname);
}
}
/**
* A method to be invoked before a class loader loads
* a resource.
*
* @param resourcename the resource name
*/
public static void preLoadResource(String resourcename) {
BootClassLoaderHook hook = getHook();
if (hook != null) {
hook.getBootstrapResource(resourcename);
}
}
/**
* A method to be invoked before a library is loaded.
*
* @param libname the name of the library
*/
public static void preLoadLibrary(String libname) {
BootClassLoaderHook hook = getHook();
if (hook != null) {
hook.loadLibrary(libname);
}
}
private static final File[] EMPTY_FILE_ARRAY = new File[0];
/**
* Returns bootstrap class paths added by the hook.
*/
public static File[] getBootstrapPaths() {
BootClassLoaderHook hook = getHook();
if (hook != null) {
return hook.getBootstrapPaths();
} else {
return EMPTY_FILE_ARRAY;
}
}
/**
* Returns a pathname of a JAR or class that the hook loads
* per this loadClass request; or null.
*
* @param classname the binary name of the class
*/
public abstract String loadBootstrapClass(String className);
/**
* Returns a pathname of a resource file that the hook loads
* per this getResource request; or null.
*
* @param resourceName the resource name
*/
public abstract String getBootstrapResource(String resourceName);
/**
* Returns true if the hook successfully performs an operation per
* this loadLibrary request; or false if it fails.
*
* @param libname the name of the library
*/
public abstract boolean loadLibrary(String libname);
/**
* Returns additional boot class paths added by the hook that
* should be searched by the boot class loader.
*/
public abstract File[] getAdditionalBootstrapPaths();
/**
* Returns true if the current thread is in the process of doing
* a prefetching operation.
*/
public abstract boolean isCurrentThreadPrefetching();
/**
* Returns true if the hook successfully prefetches the specified file.
*
* @param name a platform independent pathname
*/
public abstract boolean prefetchFile(String name);
}
...@@ -50,8 +50,6 @@ import java.security.CodeSource; ...@@ -50,8 +50,6 @@ import java.security.CodeSource;
import sun.security.action.GetPropertyAction; import sun.security.action.GetPropertyAction;
import sun.security.util.SecurityConstants; import sun.security.util.SecurityConstants;
import sun.net.www.ParseUtil; import sun.net.www.ParseUtil;
import sun.jkernel.Bundle;
import sun.jkernel.DownloadManager;
/** /**
* This class is used by the system to launch the main application. * This class is used by the system to launch the main application.
...@@ -248,12 +246,7 @@ public class Launcher { ...@@ -248,12 +246,7 @@ public class Launcher {
} }
protected Class findClass(String name) throws ClassNotFoundException { protected Class findClass(String name) throws ClassNotFoundException {
if (VM.isBootedKernelVM()) { BootClassLoaderHook.preLoadClass(name);
// Check for download before we look for it. If
// DownloadManager ends up downloading it, it will add it to
// our search path before we proceed to the findClass().
DownloadManager.getBootClassPathEntryForClass(name);
}
return super.findClass(name); return super.findClass(name);
} }
...@@ -321,9 +314,7 @@ public class Launcher { ...@@ -321,9 +314,7 @@ public class Launcher {
public Class loadClass(String name, boolean resolve) public Class loadClass(String name, boolean resolve)
throws ClassNotFoundException throws ClassNotFoundException
{ {
if (VM.isBootedKernelVM()) { BootClassLoaderHook.preLoadClass(name);
DownloadManager.getBootClassPathEntryForClass(name);
}
int i = name.lastIndexOf('.'); int i = name.lastIndexOf('.');
if (i != -1) { if (i != -1) {
SecurityManager sm = System.getSecurityManager(); SecurityManager sm = System.getSecurityManager();
...@@ -421,19 +412,17 @@ public class Launcher { ...@@ -421,19 +412,17 @@ public class Launcher {
} }
bootstrapClassPath = new URLClassPath(urls, factory); bootstrapClassPath = new URLClassPath(urls, factory);
if (VM.isBootedKernelVM()) { final File[] additionalBootStrapPaths =
final File[] additionalBootStrapPaths = BootClassLoaderHook.getBootstrapPaths();
DownloadManager.getAdditionalBootStrapPaths(); AccessController.doPrivileged(new PrivilegedAction() {
AccessController.doPrivileged(new PrivilegedAction() { public Object run() {
public Object run() { for (int i=0; i<additionalBootStrapPaths.length; i++) {
for (int i=0; i<additionalBootStrapPaths.length; i++) { bootstrapClassPath.addURL(
bootstrapClassPath.addURL( getFileURL(additionalBootStrapPaths[i]));
getFileURL(additionalBootStrapPaths[i]));
}
return null;
} }
}); return null;
} }
});
} }
return bootstrapClassPath; return bootstrapClassPath;
} }
......
...@@ -346,11 +346,6 @@ public class VM { ...@@ -346,11 +346,6 @@ public class VM {
private native static void getThreadStateValues(int[][] vmThreadStateValues, private native static void getThreadStateValues(int[][] vmThreadStateValues,
String[][] vmThreadStateNames); String[][] vmThreadStateNames);
private static boolean kernelVM;
public static boolean isBootedKernelVM() {
return booted && kernelVM;
}
static { static {
initialize(); initialize();
} }
......
...@@ -131,17 +131,6 @@ Java_sun_misc_VM_initialize(JNIEnv *env, jclass cls) { ...@@ -131,17 +131,6 @@ Java_sun_misc_VM_initialize(JNIEnv *env, jclass cls) {
/* obtain the JVM version info */ /* obtain the JVM version info */
(*func_p)(env, &info, sizeof(info)); (*func_p)(env, &info, sizeof(info));
if (info.is_kernel_jvm == 1) {
/* set the static field VM.kernelVM to true for kernel VM */
fid = (*env)->GetStaticFieldID(env, cls, "kernelVM", "Z");
if (fid != 0) {
(*env)->SetStaticBooleanField(env, cls, fid, info.is_kernel_jvm);
} else {
sprintf(errmsg, "Static kernelVM boolean field not found");
JNU_ThrowInternalError(env, errmsg);
}
}
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册