1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package net.sf.webmancer.util.lang;
23
24 import java.io.ByteArrayOutputStream;
25 import java.io.IOException;
26 import java.io.InputStream;
27 import java.util.HashMap;
28 import java.util.jar.JarFile;
29 import java.util.zip.ZipEntry;
30
31
32
33
34
35 public class JarClassLoader extends ClassLoader {
36
37
38
39 private JarFile jarFiles[];
40
41
42
43
44 private HashMap<String, Boolean> fromDefault;
45
46
47
48
49
50
51
52
53 public JarClassLoader(String[] jarFileNames, String[] whatLoadFromDefault) throws IOException {
54 jarFiles = new JarFile[jarFileNames.length];
55 for (int i = 0; i < jarFileNames.length; i++) {
56 jarFiles[i] = new JarFile(jarFileNames[i]);
57 }
58 fromDefault = new HashMap<String, Boolean>();
59 for (String element: whatLoadFromDefault) {
60 fromDefault.put(element, true);
61 }
62 }
63
64
65
66
67 @Override
68 protected synchronized Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
69 Class c = findLoadedClass(name);
70 if (c == null && !fromDefault.containsKey(name)) {
71 c = findClass(name);
72 }
73 if (c == null) {
74 c = super.loadClass(name, resolve);
75 } else {
76 if (resolve) {
77 resolveClass(c);
78 }
79 }
80 return c;
81 }
82
83
84
85
86 @Override
87 public Class<?> findClass(String name) {
88 byte[] b = loadClassData(name);
89 if (b == null) {
90 return null;
91 } else {
92 return defineClass(name, b, 0, b.length);
93 }
94 }
95
96
97
98
99
100 private synchronized byte[] loadClassData(String name) {
101 for (JarFile element: jarFiles) {
102 byte[] result = tryJarfile(element, name);
103 if (result != null) {
104 return result;
105 }
106 }
107 return null;
108 }
109
110
111
112
113
114
115 private byte[] tryJarfile(JarFile jarFile, String name) {
116 ZipEntry entry = jarFile.getEntry(formatName(name));
117 if (entry == null) {
118 return null;
119 }
120 try {
121 InputStream input = jarFile.getInputStream(entry);
122 ByteArrayOutputStream output = new ByteArrayOutputStream();
123 byte[] buf = new byte[1024];
124 int r;
125 while ((r = input.read(buf)) > 0) {
126 output.write(buf, 0, r);
127 }
128 input.close();
129 output.close();
130 return output.toByteArray();
131 } catch (IOException e) {
132
133 e.printStackTrace();
134 }
135 return null;
136
137 }
138
139
140
141
142
143 private String formatName(String className) {
144 return className.replace('.', '/') + ".class";
145 }
146 }