Lines 24-31
Link Here
|
24 |
import java.security.*; |
24 |
import java.security.*; |
25 |
import java.security.cert.Certificate; |
25 |
import java.security.cert.Certificate; |
26 |
import java.util.*; |
26 |
import java.util.*; |
27 |
import java.lang.reflect.Field; |
|
|
28 |
import java.lang.reflect.Modifier; |
29 |
|
27 |
|
30 |
/** |
28 |
/** |
31 |
* A ProxyClassLoader capable of loading classes from a set of jar files |
29 |
* A ProxyClassLoader capable of loading classes from a set of jar files |
Lines 213-219
Link Here
|
213 |
// Can cause real problems under 1.4; see Module.java. |
211 |
// Can cause real problems under 1.4; see Module.java. |
214 |
JarFile tempJar = new JarFile(temp); |
212 |
JarFile tempJar = new JarFile(temp); |
215 |
origJar.close(); |
213 |
origJar.close(); |
216 |
forceRelease(orig); |
|
|
217 |
deadJars.add(tempJar); |
214 |
deadJars.add(tempJar); |
218 |
sources[i] = new JarSource(tempJar); |
215 |
sources[i] = new JarSource(tempJar); |
219 |
log("#21114: replacing " + orig + " with " + temp); |
216 |
log("#21114: replacing " + orig + " with " + temp); |
Lines 224-243
Link Here
|
224 |
} |
221 |
} |
225 |
} |
222 |
} |
226 |
|
223 |
|
227 |
/** Release jar: locks when the classloader is shut down. |
|
|
228 |
* Should help reloading modules with changed resources. |
229 |
*/ |
230 |
public void destroy() { |
231 |
super.destroy(); |
232 |
for (int i = 0; i < sources.length; i++) { |
233 |
if (sources[i] instanceof JarSource) { |
234 |
JarFile j = ((JarSource)sources[i]).getJarFile(); |
235 |
File f = new File(j.getName()); |
236 |
forceRelease(f); |
237 |
} |
238 |
} |
239 |
} |
240 |
|
241 |
/** Delete any temporary JARs we were holding on to. |
224 |
/** Delete any temporary JARs we were holding on to. |
242 |
* Also close any other JARs in our list. |
225 |
* Also close any other JARs in our list. |
243 |
*/ |
226 |
*/ |
Lines 248-254
Link Here
|
248 |
JarFile j = ((JarSource)sources[i]).getJarFile(); |
231 |
JarFile j = ((JarSource)sources[i]).getJarFile(); |
249 |
File f = new File(j.getName()); |
232 |
File f = new File(j.getName()); |
250 |
j.close(); |
233 |
j.close(); |
251 |
forceRelease(f); |
|
|
252 |
if (deadJars != null && deadJars.contains(j)) { |
234 |
if (deadJars != null && deadJars.contains(j)) { |
253 |
log("#21114: closing and deleting temporary JAR " + f); |
235 |
log("#21114: closing and deleting temporary JAR " + f); |
254 |
if (f.isFile() && !f.delete()) { |
236 |
if (f.isFile() && !f.delete()) { |
Lines 256-304
Link Here
|
256 |
} |
238 |
} |
257 |
} |
239 |
} |
258 |
} |
240 |
} |
259 |
} |
|
|
260 |
} |
261 |
|
262 |
/** Make sure the Java runtime's jar: URL cache is not holding |
263 |
* onto the specified file. |
264 |
* Workaround for JDK bug #4646668. |
265 |
*/ |
266 |
private static void forceRelease(File f) { |
267 |
if (fileCache == null || factory == null) return; |
268 |
try { |
269 |
synchronized (factory) { |
270 |
Iterator it = fileCache.values().iterator(); |
271 |
while (it.hasNext()) { |
272 |
JarFile j = (JarFile)it.next(); |
273 |
if (f.equals(new File(j.getName()))) { |
274 |
j.close(); |
275 |
it.remove(); |
276 |
log("Removing jar: cache for " + f + " as workaround for JDK #4646668"); |
277 |
} |
278 |
} |
279 |
} |
280 |
} catch (Exception e) { |
281 |
JarClassLoader.annotate(e, 0, "Could not remove jar: cache for " + f, null, null, null); |
282 |
JarClassLoader.notify(0, e); |
283 |
} |
284 |
} |
285 |
private static Object factory = null; |
286 |
private static HashMap fileCache = null; |
287 |
static { |
288 |
try { |
289 |
Class juc = Class.forName("sun.net.www.protocol.jar.JarURLConnection"); // NOI18N |
290 |
Field factoryF = juc.getDeclaredField("factory"); // NOI18N |
291 |
factoryF.setAccessible(true); |
292 |
factory = factoryF.get(null); |
293 |
Class jff = Class.forName("sun.net.www.protocol.jar.JarFileFactory"); // NOI18N |
294 |
if (!jff.isInstance(factory)) throw new ClassCastException(factory.getClass().getName()); |
295 |
Field fileCacheF = jff.getDeclaredField("fileCache"); // NOI18N |
296 |
fileCacheF.setAccessible(true); |
297 |
fileCache = (HashMap)fileCacheF.get(null); |
298 |
log("Workaround for JDK #4646668 active as part of IZ #21114"); |
299 |
} catch (Exception e) { |
300 |
JarClassLoader.annotate(e, 0, "Workaround for JDK #4646668 as part of IZ #21114 failed", null, null, null); |
301 |
JarClassLoader.notify(0, e); |
302 |
} |
241 |
} |
303 |
} |
242 |
} |
304 |
|
243 |
|