Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-multiarch-jdk8u
Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/sun/misc/ClassLoaderUtil.java
38829 views
1
/*
2
* Copyright (c) 2006, 2011, 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
}
173
174