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