Posted By

vyemialyanchyk on 12/03/09


Tagged

file close jar ClassLoade


Versions (?)

Class loader which close opened jar files


 / Published in: Java
 

URL: http://www.stopka.us

  1. package org.hibernate.console;
  2.  
  3. import java.io.IOException;
  4. import java.lang.reflect.Field;
  5. import java.lang.reflect.InvocationTargetException;
  6. import java.net.URL;
  7. import java.net.URLClassLoader;
  8. import java.util.ArrayList;
  9. import java.util.HashMap;
  10. import java.util.HashSet;
  11. import java.util.Iterator;
  12. import java.util.Vector;
  13. import java.util.jar.JarFile;
  14.  
  15. import org.hibernate.util.ReflectHelper;
  16.  
  17. /**
  18.  * Workaround for jdk disgrace with open jar files & native libs,
  19.  * which is a reason of locked, "undelete" files.
  20.  *
  21.  * @author Vitali Yemialyanchyk
  22.  */
  23. public class ConsoleConfigClassLoader extends URLClassLoader {
  24.  
  25. protected HashSet<String> setJarFileNames2Close = new HashSet<String>();
  26.  
  27. public ConsoleConfigClassLoader(URL[] urls, ClassLoader parent) {
  28. super(urls, parent);
  29. }
  30.  
  31. public void close() {
  32. setJarFileNames2Close.clear();
  33. closeClassLoader(this);
  34. finalizeNativeLibs(this);
  35. cleanupJarFileFactory();
  36. }
  37.  
  38. /**
  39. * cleanup jar file factory cache
  40. */
  41. @SuppressWarnings({ "nls", "unchecked" })
  42. public boolean cleanupJarFileFactory()
  43. {
  44. boolean res = false;
  45. Class classJarURLConnection = null;
  46. try {
  47. classJarURLConnection = ReflectHelper.classForName("sun.net.www.protocol.jar.JarURLConnection");
  48. } catch (ClassNotFoundException e) {
  49. //ignore
  50. }
  51. if (classJarURLConnection == null) {
  52. return res;
  53. }
  54. Field f = null;
  55. try {
  56. f = classJarURLConnection.getDeclaredField("factory");
  57. } catch (NoSuchFieldException e) {
  58. //ignore
  59. }
  60. if (f == null) {
  61. return res;
  62. }
  63. f.setAccessible(true);
  64. Object obj = null;
  65. try {
  66. obj = f.get(null);
  67. } catch (IllegalAccessException e) {
  68. //ignore
  69. }
  70. if (obj == null) {
  71. return res;
  72. }
  73. Class classJarFileFactory = obj.getClass();
  74. //
  75. HashMap fileCache = null;
  76. try {
  77. f = classJarFileFactory.getDeclaredField("fileCache");
  78. f.setAccessible(true);
  79. obj = f.get(null);
  80. if (obj instanceof HashMap) {
  81. fileCache = (HashMap)obj;
  82. }
  83. } catch (NoSuchFieldException e) {
  84. } catch (IllegalAccessException e) {
  85. //ignore
  86. }
  87. HashMap urlCache = null;
  88. try {
  89. f = classJarFileFactory.getDeclaredField("urlCache");
  90. f.setAccessible(true);
  91. obj = f.get(null);
  92. if (obj instanceof HashMap) {
  93. urlCache = (HashMap)obj;
  94. }
  95. } catch (NoSuchFieldException e) {
  96. } catch (IllegalAccessException e) {
  97. //ignore
  98. }
  99. if (urlCache != null) {
  100. HashMap urlCacheTmp = (HashMap)urlCache.clone();
  101. Iterator it = urlCacheTmp.keySet().iterator();
  102. while (it.hasNext()) {
  103. obj = it.next();
  104. if (!(obj instanceof JarFile)) {
  105. continue;
  106. }
  107. JarFile jarFile = (JarFile)obj;
  108. if (setJarFileNames2Close.contains(jarFile.getName())) {
  109. try {
  110. jarFile.close();
  111. } catch (IOException e) {
  112. //ignore
  113. }
  114. if (fileCache != null) {
  115. fileCache.remove(urlCache.get(jarFile));
  116. }
  117. urlCache.remove(jarFile);
  118. }
  119. }
  120. res = true;
  121. } else if (fileCache != null) {
  122. // urlCache := null
  123. HashMap fileCacheTmp = (HashMap)fileCache.clone();
  124. Iterator it = fileCacheTmp.keySet().iterator();
  125. while (it.hasNext()) {
  126. Object key = it.next();
  127. obj = fileCache.get(key);
  128. if (!(obj instanceof JarFile)) {
  129. continue;
  130. }
  131. JarFile jarFile = (JarFile)obj;
  132. if (setJarFileNames2Close.contains(jarFile.getName())) {
  133. try {
  134. jarFile.close();
  135. } catch (IOException e) {
  136. //ignore
  137. }
  138. fileCache.remove(key);
  139. }
  140. }
  141. res = true;
  142. }
  143. setJarFileNames2Close.clear();
  144. return res;
  145. }
  146.  
  147. /**
  148. * close jar files of cl
  149. * @param cl
  150. * @return
  151. */
  152. @SuppressWarnings( { "nls", "unchecked" })
  153. public boolean closeClassLoader(ClassLoader cl) {
  154. boolean res = false;
  155. if (cl == null) {
  156. return res;
  157. }
  158. Class classURLClassLoader = URLClassLoader.class;
  159. Field f = null;
  160. try {
  161. f = classURLClassLoader.getDeclaredField("ucp");
  162. } catch (NoSuchFieldException e1) {
  163. //ignore
  164. }
  165. if (f != null) {
  166. f.setAccessible(true);
  167. Object obj = null;
  168. try {
  169. obj = f.get(cl);
  170. } catch (IllegalAccessException e1) {
  171. //ignore
  172. }
  173. if (obj != null) {
  174. final Object ucp = obj;
  175. f = null;
  176. try {
  177. f = ucp.getClass().getDeclaredField("loaders");
  178. } catch (NoSuchFieldException e1) {
  179. //ignore
  180. }
  181. if (f != null) {
  182. f.setAccessible(true);
  183. ArrayList loaders = null;
  184. try {
  185. loaders = (ArrayList) f.get(ucp);
  186. res = true;
  187. } catch (IllegalAccessException e1) {
  188. //ignore
  189. }
  190. for (int i = 0; loaders != null && i < loaders.size(); i++) {
  191. obj = loaders.get(i);
  192. f = null;
  193. try {
  194. f = obj.getClass().getDeclaredField("jar");
  195. } catch (NoSuchFieldException e) {
  196. //ignore
  197. }
  198. if (f != null) {
  199. f.setAccessible(true);
  200. try {
  201. obj = f.get(obj);
  202. } catch (IllegalAccessException e1) {
  203. // ignore
  204. }
  205. if (obj instanceof JarFile) {
  206. final JarFile jarFile = (JarFile)obj;
  207. setJarFileNames2Close.add(jarFile.getName());
  208. //try {
  209. // jarFile.getManifest().clear();
  210. //} catch (IOException e) {
  211. // // ignore
  212. //}
  213. try {
  214. jarFile.close();
  215. } catch (IOException e) {
  216. // ignore
  217. }
  218. }
  219. }
  220. }
  221. }
  222. }
  223. }
  224. return res;
  225. }
  226.  
  227. /**
  228. * finalize native libraries
  229. * @param cl
  230. * @return
  231. */
  232. @SuppressWarnings({ "nls", "unchecked" })
  233. public boolean finalizeNativeLibs(ClassLoader cl) {
  234. boolean res = false;
  235. Class classClassLoader = ClassLoader.class;
  236. java.lang.reflect.Field nativeLibraries = null;
  237. try {
  238. nativeLibraries = classClassLoader.getDeclaredField("nativeLibraries");
  239. } catch (NoSuchFieldException e1) {
  240. //ignore
  241. }
  242. if (nativeLibraries == null) {
  243. return res;
  244. }
  245. nativeLibraries.setAccessible(true);
  246. Object obj = null;
  247. try {
  248. obj = nativeLibraries.get(cl);
  249. } catch (IllegalAccessException e1) {
  250. //ignore
  251. }
  252. if (!(obj instanceof Vector)) {
  253. return res;
  254. }
  255. res = true;
  256. Vector java_lang_ClassLoader_NativeLibrary = (Vector)obj;
  257. for (Object lib : java_lang_ClassLoader_NativeLibrary) {
  258. java.lang.reflect.Method finalize = null;
  259. try {
  260. finalize = lib.getClass().getDeclaredMethod("finalize", new Class[0]);
  261. } catch (NoSuchMethodException e) {
  262. //ignore
  263. }
  264. if (finalize != null) {
  265. finalize.setAccessible(true);
  266. try {
  267. finalize.invoke(lib, new Object[0]);
  268. } catch (IllegalAccessException e) {
  269. //ignore
  270. }
  271. }
  272. }
  273. return res;
  274. }
  275. }

Report this snippet  

You need to login to post a comment.