mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-12 19:35:24 +00:00
8034853: remove sun.misc.ClassLoaderUtil
Reviewed-by: alanb, mchung, chegar
This commit is contained in:
parent
0fbc4f8875
commit
afaa69f874
@ -1,172 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006, 2011, 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 sun.misc;
|
||||
|
||||
/**
|
||||
* Provides utility functions related to URLClassLoaders or subclasses of it.
|
||||
*
|
||||
* W A R N I N G
|
||||
*
|
||||
* This class uses undocumented, unpublished, private data structures inside
|
||||
* java.net.URLClassLoader and sun.misc.URLClassPath. Use with extreme caution.
|
||||
*
|
||||
* @author tjquinn
|
||||
*/
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.*;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
public class ClassLoaderUtil {
|
||||
|
||||
/**
|
||||
* Releases resources held by a URLClassLoader. A new classloader must
|
||||
* be created before the underlying resources can be accessed again.
|
||||
* @param classLoader the instance of URLClassLoader (or a subclass)
|
||||
*/
|
||||
public static void releaseLoader(URLClassLoader classLoader) {
|
||||
releaseLoader(classLoader, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases resources held by a URLClassLoader. Notably, close the jars
|
||||
* opened by the loader. Initializes and updates the List of
|
||||
* jars that have been successfully closed.
|
||||
* <p>
|
||||
* @param classLoader the instance of URLClassLoader (or a subclass)
|
||||
* @param jarsClosed a List of Strings that will contain the names of jars
|
||||
* successfully closed; can be null if the caller does not need the information returned
|
||||
* @return a List of IOExceptions reporting jars that failed to close; null
|
||||
* indicates that an error other than an IOException occurred attempting to
|
||||
* release the loader; empty indicates a successful release; non-empty
|
||||
* indicates at least one error attempting to close an open jar.
|
||||
*/
|
||||
public static List<IOException> releaseLoader(URLClassLoader classLoader, List<String> jarsClosed) {
|
||||
|
||||
List<IOException> ioExceptions = new LinkedList<IOException>();
|
||||
|
||||
try {
|
||||
/* Records all IOExceptions thrown while closing jar files. */
|
||||
|
||||
if (jarsClosed != null) {
|
||||
jarsClosed.clear();
|
||||
}
|
||||
|
||||
URLClassPath ucp = SharedSecrets.getJavaNetAccess()
|
||||
.getURLClassPath(classLoader);
|
||||
ArrayList<?> loaders = ucp.loaders;
|
||||
Stack<?> urls = ucp.urls;
|
||||
HashMap<?,?> lmap = ucp.lmap;
|
||||
|
||||
/*
|
||||
*The urls variable in the URLClassPath object holds URLs that have not yet
|
||||
*been used to resolve a resource or load a class and, therefore, do
|
||||
*not yet have a loader associated with them. Clear the stack so any
|
||||
*future requests that might incorrectly reach the loader cannot be
|
||||
*resolved and cannot open a jar file after we think we've closed
|
||||
*them all.
|
||||
*/
|
||||
synchronized(urls) {
|
||||
urls.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
*Also clear the map of URLs to loaders so the class loader cannot use
|
||||
*previously-opened jar files - they are about to be closed.
|
||||
*/
|
||||
synchronized(lmap) {
|
||||
lmap.clear();
|
||||
}
|
||||
|
||||
/*
|
||||
*The URLClassPath object's path variable records the list of all URLs that are on
|
||||
*the URLClassPath's class path. Leave that unchanged. This might
|
||||
*help someone trying to debug why a released class loader is still used.
|
||||
*Because the stack and lmap are now clear, code that incorrectly uses a
|
||||
*the released class loader will trigger an exception if the
|
||||
*class or resource would have been resolved by the class
|
||||
*loader (and no other) if it had not been released.
|
||||
*
|
||||
*The list of URLs might provide some hints to the person as to where
|
||||
*in the code the class loader was set up, which might in turn suggest
|
||||
*where in the code the class loader needs to stop being used.
|
||||
*The URLClassPath does not use the path variable to open new jar
|
||||
*files - it uses the urls Stack for that - so leaving the path variable
|
||||
*will not by itself allow the class loader to continue handling requests.
|
||||
*/
|
||||
|
||||
/*
|
||||
*For each loader, close the jar file associated with that loader.
|
||||
*
|
||||
*The URLClassPath's use of loaders is sync-ed on the entire URLClassPath
|
||||
*object.
|
||||
*/
|
||||
synchronized (ucp) {
|
||||
for (Object o : loaders) {
|
||||
if (o != null) {
|
||||
/*
|
||||
*If the loader is a JarLoader inner class and its jarFile
|
||||
*field is non-null then try to close that jar file. Add
|
||||
*it to the list of closed files if successful.
|
||||
*/
|
||||
if (o instanceof URLClassPath.JarLoader) {
|
||||
URLClassPath.JarLoader jl = (URLClassPath.JarLoader)o;
|
||||
JarFile jarFile = jl.getJarFile();
|
||||
try {
|
||||
if (jarFile != null) {
|
||||
jarFile.close();
|
||||
if (jarsClosed != null) {
|
||||
jarsClosed.add(jarFile.getName());
|
||||
}
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
/*
|
||||
*Wrap the IOException to identify which jar
|
||||
*could not be closed and add it to the list
|
||||
*of IOExceptions to be returned to the caller.
|
||||
*/
|
||||
String jarFileName = (jarFile == null) ? "filename not available":jarFile.getName();
|
||||
String msg = "Error closing JAR file: " + jarFileName;
|
||||
IOException newIOE = new IOException(msg);
|
||||
newIOE.initCause(ioe);
|
||||
ioExceptions.add(newIOE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
*Now clear the loaders ArrayList.
|
||||
*/
|
||||
loaders.clear();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
throw new RuntimeException (t);
|
||||
}
|
||||
return ioExceptions;
|
||||
}
|
||||
}
|
||||
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 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 6349735
|
||||
* @summary Internal API for closing jar files belonging to URLClassLoader instances
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
|
||||
public class Test {
|
||||
|
||||
static File copy (File src, String destDir) throws Exception {
|
||||
FileInputStream fis = new FileInputStream (src);
|
||||
File dest = new File (destDir, src.getName());
|
||||
FileOutputStream fos = new FileOutputStream (dest);
|
||||
byte buf[] = new byte [1024];
|
||||
int c;
|
||||
while ((c=fis.read(buf)) != -1) {
|
||||
fos.write (buf, 0, c);
|
||||
}
|
||||
fis.close();
|
||||
fos.close();
|
||||
return dest;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String srcPath = System.getProperty("test.src");
|
||||
String destPath = System.getProperty("test.classes");
|
||||
if (destPath == null || "".equals(destPath)) {
|
||||
throw new RuntimeException ("Not running test");
|
||||
}
|
||||
File file = new File (srcPath, "test.jar");
|
||||
file = copy (file, destPath);
|
||||
URL url = file.toURL();
|
||||
URLClassLoader loader = new URLClassLoader (new URL [] {url});
|
||||
Class clazz = Class.forName ("Foo", true, loader);
|
||||
Object obj = clazz.newInstance();
|
||||
List<String> jarsclosed = new LinkedList<String>();
|
||||
sun.misc.ClassLoaderUtil.releaseLoader (loader, jarsclosed);
|
||||
for (String jar: jarsclosed) {
|
||||
System.out.println ("Successfully closed " + jar);
|
||||
}
|
||||
if (!file.delete()) {
|
||||
throw new RuntimeException ("failed to delete jar file");
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user