6612680: Remove classloader dependency on jkernel
Add a new sun.misc.BootClassLoaderHook that DownloadManager will implement Reviewed-by: alanb, forax, igor
This commit is contained in:
parent
04890be7bb
commit
9f6fbc5544
@ -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) {
|
||||
// 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
|
||||
if (sun.misc.VM.isBootedKernelVM() &&
|
||||
sun.jkernel.DownloadManager.isCurrentThreadDownloading()) {
|
||||
this.time = sun.jkernel.DownloadManager.KERNEL_STATIC_MODTIME;
|
||||
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());
|
||||
|
153
jdk/src/share/classes/sun/misc/BootClassLoaderHook.java
Normal file
153
jdk/src/share/classes/sun/misc/BootClassLoaderHook.java
Normal file
@ -0,0 +1,153 @@
|
||||
/*
|
||||
* 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,9 +412,8 @@ public class Launcher {
|
||||
}
|
||||
|
||||
bootstrapClassPath = new URLClassPath(urls, factory);
|
||||
if (VM.isBootedKernelVM()) {
|
||||
final File[] additionalBootStrapPaths =
|
||||
DownloadManager.getAdditionalBootStrapPaths();
|
||||
BootClassLoaderHook.getBootstrapPaths();
|
||||
AccessController.doPrivileged(new PrivilegedAction() {
|
||||
public Object run() {
|
||||
for (int i=0; i<additionalBootStrapPaths.length; i++) {
|
||||
@ -434,7 +424,6 @@ public class Launcher {
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user