OSDN Git Service

Merge remote branch 'origin/HEAD'
[stigmata/digger.git] / src / main / java / jp / sourceforge / stigmata / digger / WarClassLoader.java
1 package jp.sourceforge.stigmata.digger;
2
3 import java.io.ByteArrayOutputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.net.URL;
7 import java.net.URLClassLoader;
8 import java.net.URLStreamHandlerFactory;
9
10 /**
11  * ClassLoader for war file.
12  * A war file layouts classes in /WEB-INF/classes directory.
13  * Therefore, plain jar class loader cannot load classes included in war file.
14  * Because plain jar class loader only loads classes in top directory.
15  * Then, this class loader can load classes included in a plain jar file and a war file.
16  * 
17  * @author Haruaki Tamada
18  */
19 public class WarClassLoader extends URLClassLoader{
20     public WarClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory){
21         super(urls, parent, factory);
22     }
23
24     public WarClassLoader(URL[] urls, ClassLoader parent){
25         super(urls, parent);
26     }
27
28     public WarClassLoader(URL... urls){
29         super(urls);
30     }
31
32     public WarClassLoader(ClassLoader parent, URL... urls){
33         this(urls, parent);
34     }
35
36     public WarClassLoader(ClassLoader parent, URLStreamHandlerFactory factory, URL... urls){
37         this(urls, parent, factory);
38     }
39
40     @Override
41     protected Class<?> findClass(String name) throws ClassNotFoundException{
42         Class<?> clazz = null;
43         try{
44             clazz = super.findClass(name);
45         } catch(ClassNotFoundException e){
46             String path = "WEB-INF/classes/" + name.replace('.', '/') + ".class";
47             for(URL url: getURLs()){
48                 if(url.toString().endsWith(".war")){
49                     InputStream in = null;
50                     ByteArrayOutputStream out = new ByteArrayOutputStream();
51                     try{
52                         URL newurl = new URL("jar:" + url + "!/" + path);
53                         in = newurl.openStream();
54                         byte[] data = new byte[256];
55                         int read = 0;
56                         while((read = in.read(data, 0, data.length)) != -1){
57                             out.write(data, 0, read);
58                         }
59                         byte[] classdata = out.toByteArray();
60                         clazz = defineClass(name, classdata, 0, classdata.length);
61                     } catch(IOException exp){
62                         throw e;
63                     } finally{
64                         if(in != null){
65                             try{ in.close(); }
66                             catch(IOException exception){
67                                 throw new InternalError(exception.getMessage());
68                             }
69                         }
70                         try{ 
71                             out.close();
72                         } catch(IOException exception){
73                             throw new InternalError(exception.getMessage());
74                         }
75                     }
76                     break;
77                 }
78             }
79         }
80         if(clazz == null){
81             throw new ClassNotFoundException(name);
82         }
83         return clazz;
84     }
85 }