History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/misc/ClassLoaderUtil.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/misc/ClassLoaderUtil.java+172−0
@@ -0,0 +1,172 @@
1+/*
2+ * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package sun.misc;
27+
28+/**
29+ * Provides utility functions related to URLClassLoaders or subclasses of it.
30+ *
31+ * W A R N I N G
32+ *
33+ * This class uses undocumented, unpublished, private data structures inside
34+ * java.net.URLClassLoader and sun.misc.URLClassPath. Use with extreme caution.
35+ *
36+ * @author tjquinn
37+ */
38+
39+
40+import java.io.IOException;
41+import java.net.URLClassLoader;
42+import java.util.*;
43+import java.util.jar.JarFile;
44+
45+public class ClassLoaderUtil {
46+
47+ /**
48+ * Releases resources held by a URLClassLoader. A new classloader must
49+ * be created before the underlying resources can be accessed again.
50+ * @param classLoader the instance of URLClassLoader (or a subclass)
51+ */
52+ public static void releaseLoader(URLClassLoader classLoader) {
53+ releaseLoader(classLoader, null);
54+ }
55+
56+ /**
57+ * Releases resources held by a URLClassLoader. Notably, close the jars
58+ * opened by the loader. Initializes and updates the List of
59+ * jars that have been successfully closed.
60+ * <p>
61+ * @param classLoader the instance of URLClassLoader (or a subclass)
62+ * @param jarsClosed a List of Strings that will contain the names of jars
63+ * successfully closed; can be null if the caller does not need the information returned
64+ * @return a List of IOExceptions reporting jars that failed to close; null
65+ * indicates that an error other than an IOException occurred attempting to
66+ * release the loader; empty indicates a successful release; non-empty
67+ * indicates at least one error attempting to close an open jar.
68+ */
69+ public static List<IOException> releaseLoader(URLClassLoader classLoader, List<String> jarsClosed) {
70+
71+ List<IOException> ioExceptions = new LinkedList<IOException>();
72+
73+ try {
74+ /* Records all IOExceptions thrown while closing jar files. */
75+
76+ if (jarsClosed != null) {
77+ jarsClosed.clear();
78+ }
79+
80+ URLClassPath ucp = SharedSecrets.getJavaNetAccess()
81+ .getURLClassPath(classLoader);
82+ ArrayList loaders = ucp.loaders;
83+ Stack urls = ucp.urls;
84+ HashMap lmap = ucp.lmap;
85+
86+ /*
87+ *The urls variable in the URLClassPath object holds URLs that have not yet
88+ *been used to resolve a resource or load a class and, therefore, do
89+ *not yet have a loader associated with them. Clear the stack so any
90+ *future requests that might incorrectly reach the loader cannot be
91+ *resolved and cannot open a jar file after we think we've closed
92+ *them all.
93+ */
94+ synchronized(urls) {
95+ urls.clear();
96+ }
97+
98+ /*
99+ *Also clear the map of URLs to loaders so the class loader cannot use
100+ *previously-opened jar files - they are about to be closed.
101+ */
102+ synchronized(lmap) {
103+ lmap.clear();
104+ }
105+
106+ /*
107+ *The URLClassPath object's path variable records the list of all URLs that are on
108+ *the URLClassPath's class path. Leave that unchanged. This might
109+ *help someone trying to debug why a released class loader is still used.
110+ *Because the stack and lmap are now clear, code that incorrectly uses a
111+ *the released class loader will trigger an exception if the
112+ *class or resource would have been resolved by the class
113+ *loader (and no other) if it had not been released.
114+ *
115+ *The list of URLs might provide some hints to the person as to where
116+ *in the code the class loader was set up, which might in turn suggest
117+ *where in the code the class loader needs to stop being used.
118+ *The URLClassPath does not use the path variable to open new jar
119+ *files - it uses the urls Stack for that - so leaving the path variable
120+ *will not by itself allow the class loader to continue handling requests.
121+ */
122+
123+ /*
124+ *For each loader, close the jar file associated with that loader.
125+ *
126+ *The URLClassPath's use of loaders is sync-ed on the entire URLClassPath
127+ *object.
128+ */
129+ synchronized (ucp) {
130+ for (Object o : loaders) {
131+ if (o != null) {
132+ /*
133+ *If the loader is a JarLoader inner class and its jarFile
134+ *field is non-null then try to close that jar file. Add
135+ *it to the list of closed files if successful.
136+ */
137+ if (o instanceof URLClassPath.JarLoader) {
138+ URLClassPath.JarLoader jl = (URLClassPath.JarLoader)o;
139+ JarFile jarFile = jl.getJarFile();
140+ try {
141+ if (jarFile != null) {
142+ jarFile.close();
143+ if (jarsClosed != null) {
144+ jarsClosed.add(jarFile.getName());
145+ }
146+ }
147+ } catch (IOException ioe) {
148+ /*
149+ *Wrap the IOException to identify which jar
150+ *could not be closed and add it to the list
151+ *of IOExceptions to be returned to the caller.
152+ */
153+ String jarFileName = (jarFile == null) ? "filename not available":jarFile.getName();
154+ String msg = "Error closing JAR file: " + jarFileName;
155+ IOException newIOE = new IOException(msg);
156+ newIOE.initCause(ioe);
157+ ioExceptions.add(newIOE);
158+ }
159+ }
160+ }
161+ }
162+ /*
163+ *Now clear the loaders ArrayList.
164+ */
165+ loaders.clear();
166+ }
167+ } catch (Throwable t) {
168+ throw new RuntimeException (t);
169+ }
170+ return ioExceptions;
171+ }
172+}