1 package org.codehaus.plexus.classworlds.launcher;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.lang.reflect.InvocationTargetException;
22 import java.lang.reflect.Method;
23 import java.lang.reflect.Modifier;
24 import java.net.MalformedURLException;
25 import java.net.URL;
26 import java.nio.file.Files;
27 import java.nio.file.Paths;
28
29 import org.codehaus.plexus.classworlds.ClassWorld;
30 import org.codehaus.plexus.classworlds.realm.ClassRealm;
31 import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
32 import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47 public class Launcher {
48 protected static final String CLASSWORLDS_CONF = "classworlds.conf";
49
50 protected static final String UBERJAR_CONF_DIR = "WORLDS-INF/conf/";
51
52 protected ClassLoader systemClassLoader;
53
54 protected String mainClassName;
55
56 protected String mainRealmName;
57
58 protected ClassWorld world;
59
60 private int exitCode = 0;
61
62 public Launcher() {
63 this.systemClassLoader = Thread.currentThread().getContextClassLoader();
64 }
65
66 public void setSystemClassLoader(ClassLoader loader) {
67 this.systemClassLoader = loader;
68 }
69
70 public ClassLoader getSystemClassLoader() {
71 return this.systemClassLoader;
72 }
73
74 public int getExitCode() {
75 return exitCode;
76 }
77
78 public void setAppMain(String mainClassName, String mainRealmName) {
79 this.mainClassName = mainClassName;
80
81 this.mainRealmName = mainRealmName;
82 }
83
84 public String getMainRealmName() {
85 return this.mainRealmName;
86 }
87
88 public String getMainClassName() {
89 return this.mainClassName;
90 }
91
92 public void setWorld(ClassWorld world) {
93 this.world = world;
94 }
95
96 public ClassWorld getWorld() {
97 return this.world;
98 }
99
100
101
102
103
104
105
106
107
108
109
110
111
112 public void configure(InputStream is)
113 throws IOException, ConfigurationException, DuplicateRealmException, NoSuchRealmException {
114 Configurator configurator = new Configurator(this);
115
116 configurator.configure(is);
117 }
118
119
120
121
122
123
124
125
126 public Class<?> getMainClass() throws ClassNotFoundException, NoSuchRealmException {
127 return getMainRealm().loadClass(getMainClassName());
128 }
129
130
131
132
133
134
135
136 public ClassRealm getMainRealm() throws NoSuchRealmException {
137 return getWorld().getRealm(getMainRealmName());
138 }
139
140
141
142
143
144
145
146
147
148 protected Method getEnhancedMainMethod()
149 throws ClassNotFoundException, NoSuchMethodException, NoSuchRealmException {
150 Class<?> cwClass = getMainRealm().loadClass(ClassWorld.class.getName());
151
152 Method m = getMainClass().getMethod("main", String[].class, cwClass);
153
154 int modifiers = m.getModifiers();
155
156 if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)) {
157 if (m.getReturnType() == Integer.TYPE || m.getReturnType() == Void.TYPE) {
158 return m;
159 }
160 }
161
162 throw new NoSuchMethodException("public static void main(String[] args, ClassWorld world)");
163 }
164
165
166
167
168
169
170
171
172
173 protected Method getMainMethod() throws ClassNotFoundException, NoSuchMethodException, NoSuchRealmException {
174 Method m = getMainClass().getMethod("main", String[].class);
175
176 int modifiers = m.getModifiers();
177
178 if (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers)) {
179 if (m.getReturnType() == Integer.TYPE || m.getReturnType() == Void.TYPE) {
180 return m;
181 }
182 }
183
184 throw new NoSuchMethodException("public static void main(String[] args) in " + getMainClass());
185 }
186
187
188
189
190
191
192
193
194
195
196
197 public void launch(String[] args)
198 throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException,
199 NoSuchRealmException {
200 try {
201 launchEnhanced(args);
202
203 return;
204 } catch (NoSuchMethodException e) {
205
206 }
207
208 launchStandard(args);
209 }
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227 protected void launchEnhanced(String[] args)
228 throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException,
229 NoSuchRealmException {
230 ClassRealm mainRealm = getMainRealm();
231
232 Class<?> mainClass = getMainClass();
233
234 Method mainMethod = getEnhancedMainMethod();
235
236 ClassLoader cl = mainRealm;
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253 Thread.currentThread().setContextClassLoader(cl);
254
255 Object ret = mainMethod.invoke(mainClass, args, getWorld());
256
257 if (ret instanceof Integer) {
258 exitCode = (Integer) ret;
259 }
260
261 Thread.currentThread().setContextClassLoader(systemClassLoader);
262 }
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281 protected void launchStandard(String[] args)
282 throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException,
283 NoSuchRealmException {
284 ClassRealm mainRealm = getMainRealm();
285
286 Class<?> mainClass = getMainClass();
287
288 Method mainMethod = getMainMethod();
289
290 Thread.currentThread().setContextClassLoader(mainRealm);
291
292 Object ret = mainMethod.invoke(mainClass, new Object[] {args});
293
294 if (ret instanceof Integer) {
295 exitCode = (Integer) ret;
296 }
297
298 Thread.currentThread().setContextClassLoader(systemClassLoader);
299 }
300
301
302
303
304
305
306
307
308
309
310
311
312 public static void main(String[] args) {
313 try {
314 int exitCode = mainWithExitCode(args);
315
316 System.exit(exitCode);
317 } catch (Exception e) {
318 e.printStackTrace();
319
320 System.exit(100);
321 }
322 }
323
324
325
326
327
328
329
330
331 public static int mainWithExitCode(String[] args) throws Exception {
332 String classworldsConf = System.getProperty(CLASSWORLDS_CONF);
333
334 InputStream is;
335
336 Launcher launcher = new Launcher();
337
338 ClassLoader cl = Thread.currentThread().getContextClassLoader();
339
340 launcher.setSystemClassLoader(cl);
341
342 if (classworldsConf != null) {
343 is = Files.newInputStream(Paths.get(classworldsConf));
344 } else {
345 if ("true".equals(System.getProperty("classworlds.bootstrapped"))) {
346 is = cl.getResourceAsStream(UBERJAR_CONF_DIR + CLASSWORLDS_CONF);
347 } else {
348 is = cl.getResourceAsStream(CLASSWORLDS_CONF);
349 }
350 }
351
352 if (is == null) {
353 throw new Exception("classworlds configuration not specified nor found in the classpath");
354 }
355
356 launcher.configure(is);
357
358 is.close();
359
360 try {
361 launcher.launch(args);
362 } catch (InvocationTargetException e) {
363 ClassRealm realm = launcher.getWorld().getRealm(launcher.getMainRealmName());
364
365 URL[] constituents = realm.getURLs();
366
367 System.out.println("---------------------------------------------------");
368
369 for (int i = 0; i < constituents.length; i++) {
370 System.out.println("constituent[" + i + "]: " + constituents[i]);
371 }
372
373 System.out.println("---------------------------------------------------");
374
375
376 Throwable t = e.getTargetException();
377
378 if (t instanceof Exception) {
379 throw (Exception) t;
380 }
381 if (t instanceof Error) {
382 throw (Error) t;
383 }
384
385
386 throw e;
387 }
388
389 return launcher.getExitCode();
390 }
391 }