提交 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
#
_OPT = $(CC_HIGHEST_OPT)
# This re-directs all the class files to a separate location
CLASSDESTDIR = $(TEMPDIR)/classes
#
# Java source files
#
......
......@@ -58,6 +58,8 @@ import java.util.StringTokenizer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.misc.BootClassLoaderHook;
/**
* A representation of color profile data for device independent and
* device dependent color spaces based on the International Color
......@@ -1850,11 +1852,10 @@ public class ICC_Profile implements Serializable {
f = new File(fullPath);
if (!f.isFile()) {
//make sure file was installed in the kernel mode
try {
//kernel uses platform independent paths =>
// should not use platform separator char
sun.jkernel.DownloadManager.downloadFile("lib/cmm/"+fileName);
} catch (IOException ioe) {}
BootClassLoaderHook hook = BootClassLoaderHook.getHook();
if (hook.getHook() != null) {
hook.prefetchFile("lib/cmm/"+fileName);
}
}
}
......
......@@ -51,6 +51,7 @@ import java.util.Vector;
import java.util.Hashtable;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import sun.misc.BootClassLoaderHook;
import sun.misc.ClassFileTransformer;
import sun.misc.CompoundEnumeration;
import sun.misc.Resource;
......@@ -58,7 +59,6 @@ import sun.misc.URLClassPath;
import sun.misc.VM;
import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;
import sun.jkernel.DownloadManager;
/**
* A class loader is an object that is responsible for loading classes. The
......@@ -1300,21 +1300,7 @@ public abstract class ClassLoader {
* Find resources from the VM's built-in classloader.
*/
private static URL 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).
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.
}
BootClassLoaderHook.preLoadResource(name);
URLClassPath ucp = getBootstrapClassPath();
Resource res = ucp.getResource(name);
return res != null ? res.getURL() : null;
......@@ -1831,24 +1817,7 @@ public abstract class ClassLoader {
// Invoked in the java.lang.Runtime class to implement load and loadLibrary.
static void loadLibrary(Class fromClass, String name,
boolean isAbsolute) {
try {
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.
}
BootClassLoaderHook.preLoadLibrary(name);
ClassLoader loader =
(fromClass == null) ? null : fromClass.getClassLoader();
if (sys_paths == null) {
......
......@@ -26,6 +26,7 @@
package java.util.zip;
import java.util.Date;
import sun.misc.BootClassLoaderHook;
/**
* This class is used to represent a ZIP file entry.
......@@ -109,12 +110,16 @@ class ZipEntry implements ZipConstants, Cloneable {
* @see #getTime()
*/
public void setTime(long time) {
// 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
if (sun.misc.VM.isBootedKernelVM() &&
sun.jkernel.DownloadManager.isCurrentThreadDownloading()) {
this.time = sun.jkernel.DownloadManager.KERNEL_STATIC_MODTIME;
// Same value as defined in sun.jkernel.DownloadManager.KERNEL_STATIC_MODTIME
// to avoid direct reference to DownoadManager class. Need to revisit
// if this is needed any more (see comment in the DownloadManager class)
final int KERNEL_STATIC_MODTIME = 10000000;
BootClassLoaderHook hook = BootClassLoaderHook.getHook();
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 {
this.time = javaToDosTime(time);
}
......
......@@ -31,6 +31,7 @@ import java.util.concurrent.*;
import java.util.jar.*;
import java.util.zip.*;
import sun.misc.Launcher;
import sun.misc.BootClassLoaderHook;
/**
* Handles the downloading of additional JRE components. The bootstrap class
......@@ -39,7 +40,7 @@ import sun.misc.Launcher;
*
*@author Ethan Nicholas
*/
public class DownloadManager {
public class DownloadManager extends BootClassLoaderHook {
public static final String KERNEL_DOWNLOAD_URL_PROPERTY =
"kernel.download.url";
public static final String KERNEL_DOWNLOAD_ENABLED_PROPERTY =
......@@ -1023,7 +1024,8 @@ public class DownloadManager {
/**
* 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,
* we don't call back into DownloadManager in an attempt to download it
* (which would lead to infinite recursion).
......@@ -1614,6 +1616,77 @@ public class DownloadManager {
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 {
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;
import sun.security.action.GetPropertyAction;
import sun.security.util.SecurityConstants;
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.
......@@ -248,12 +246,7 @@ public class Launcher {
}
protected Class findClass(String name) throws ClassNotFoundException {
if (VM.isBootedKernelVM()) {
// 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);
}
BootClassLoaderHook.preLoadClass(name);
return super.findClass(name);
}
......@@ -321,9 +314,7 @@ public class Launcher {
public Class loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
if (VM.isBootedKernelVM()) {
DownloadManager.getBootClassPathEntryForClass(name);
}
BootClassLoaderHook.preLoadClass(name);
int i = name.lastIndexOf('.');
if (i != -1) {
SecurityManager sm = System.getSecurityManager();
......@@ -421,19 +412,17 @@ public class Launcher {
}
bootstrapClassPath = new URLClassPath(urls, factory);
if (VM.isBootedKernelVM()) {
final File[] additionalBootStrapPaths =
DownloadManager.getAdditionalBootStrapPaths();
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
for (int i=0; i<additionalBootStrapPaths.length; i++) {
bootstrapClassPath.addURL(
getFileURL(additionalBootStrapPaths[i]));
}
return null;
final File[] additionalBootStrapPaths =
BootClassLoaderHook.getBootstrapPaths();
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
for (int i=0; i<additionalBootStrapPaths.length; i++) {
bootstrapClassPath.addURL(
getFileURL(additionalBootStrapPaths[i]));
}
});
}
return null;
}
});
}
return bootstrapClassPath;
}
......
......@@ -346,11 +346,6 @@ public class VM {
private native static void getThreadStateValues(int[][] vmThreadStateValues,
String[][] vmThreadStateNames);
private static boolean kernelVM;
public static boolean isBootedKernelVM() {
return booted && kernelVM;
}
static {
initialize();
}
......
......@@ -131,17 +131,6 @@ Java_sun_misc_VM_initialize(JNIEnv *env, jclass cls) {
/* obtain the JVM version 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.
先完成此消息的编辑!
想要评论请 注册