KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > magnet > domain > java > JavaLauncher


1 package org.sapia.magnet.domain.java;
2
3 // Import of Sun's JDK classes
4
// ---------------------------
5
import java.util.ArrayList JavaDoc;
6 import java.util.Collection JavaDoc;
7 import java.util.Iterator JavaDoc;
8 import java.util.List JavaDoc;
9
10 // Import of Apache's log4j
11
// ------------------------
12
import org.apache.log4j.Logger;
13
14 // Import of Sapia's magnet classes
15
// --------------------------------
16
import org.sapia.console.CmdLine;
17 import org.sapia.magnet.MagnetException;
18 import org.sapia.magnet.Log;
19 import org.sapia.magnet.domain.DefaultLaunchHandler;
20 import org.sapia.magnet.domain.Magnet;
21 import org.sapia.magnet.domain.Param;
22 import org.sapia.magnet.domain.Profile;
23 import org.sapia.magnet.render.MagnetContext;
24 import org.sapia.magnet.render.RenderingException;
25
26 /**
27  *
28  *
29  * @author Jean-Cedric Desrochers
30  *
31  * <dl>
32  * <dt><b>Copyright:</b><dd>Copyright &#169; 2002-2003 <a HREF="http://www.sapia-oss.org">Sapia Open Source Software</a>. All Rights Reserved.</dd></dt>
33  * <dt><b>License:</b><dd>Read the license.txt file of the jar or visit the
34  * <a HREF="http://www.sapia-oss.org/license.html" target="sapia-license">license page</a> at the Sapia OSS web site</dd></dt>
35  * </dl>
36  */

37 public class JavaLauncher extends DefaultLaunchHandler {
38
39   /////////////////////////////////////////////////////////////////////////////////////////
40
////////////////////////////////// CLASS ATTRIBUTES ///////////////////////////////////
41
/////////////////////////////////////////////////////////////////////////////////////////
42

43   /** Defines the logger instance for this class. */
44   private static final Logger _theLogger = Logger.getLogger(JavaLauncher.class);
45
46   /////////////////////////////////////////////////////////////////////////////////////////
47
///////////////////////////////// INSTANCE ATTRIBUTES /////////////////////////////////
48
/////////////////////////////////////////////////////////////////////////////////////////
49

50   /** The main class of this java launcher. */
51   private String JavaDoc _theMainClass;
52
53   /** The arguments of this java launcher. */
54   private String JavaDoc _theArguments;
55
56   /** The daemon indicator of this java launcher. */
57   private String JavaDoc _isDaemon;
58
59   /////////////////////////////////////////////////////////////////////////////////////////
60
//////////////////////////////////// CONSTRUCTORS /////////////////////////////////////
61
/////////////////////////////////////////////////////////////////////////////////////////
62

63   /**
64    * Creates a new JavaLauncher instance.
65    */

66   public JavaLauncher() {
67   }
68
69   /////////////////////////////////////////////////////////////////////////////////////////
70
////////////////////////////////// ACCESSOR METHODS ///////////////////////////////////
71
/////////////////////////////////////////////////////////////////////////////////////////
72

73   /**
74    * Returns the main class of this java launcher.
75    *
76    * @return The main class of this java launcher.
77    */

78   public String JavaDoc getMainClass() {
79     return _theMainClass;
80   }
81
82   /**
83    * Returns the application arguments of this java launcher.
84    *
85    * @return The application arguments of this java launcher.
86    */

87   public String JavaDoc getArgs() {
88     return _theArguments;
89   }
90
91   /**
92    * Returns the daemon indicator of this java launcher.
93    *
94    * @return The daemon indicator of this java launcher.
95    */

96   public boolean isDaemon() {
97     return _isDaemon != null && _isDaemon.equals("true");
98   }
99
100   /////////////////////////////////////////////////////////////////////////////////////////
101
/////////////////////////////////// MUTATOR METHODS ///////////////////////////////////
102
/////////////////////////////////////////////////////////////////////////////////////////
103

104   /**
105    * Changes the main class of this java launcher.
106    *
107    * @param aMainClass The name of the new main class.
108    */

109   public void setMainClass(String JavaDoc aMainClass) {
110     _theMainClass = aMainClass;
111   }
112
113   /**
114    * Changes the application arguments of this java launcher.
115    *
116    * @param anArguments The new application arguments.
117    */

118   public void setArgs(String JavaDoc anArguments) {
119     _theArguments = anArguments;
120   }
121
122   /**
123    * Changes the daemon indicator of this java launcher.
124    *
125    * @param isDaemon The daemon indicator.
126    */

127   public void setIsDaemon(boolean isDaemon) {
128     if (isDaemon) {
129       _isDaemon = "true";
130     } else {
131       _isDaemon = "false";
132     }
133   }
134
135   /////////////////////////////////////////////////////////////////////////////////////////
136
/////////////////////////////////// HELPER METHODS ////////////////////////////////////
137
/////////////////////////////////////////////////////////////////////////////////////////
138

139   /**
140    * Finds the classpath identifier by the ID passed in.
141    *
142    * @param anId The identifier of the classpath to retrieve.
143    * @param someMagnets The collection of magnets in which the classpath is.
144    * @return The found classpath or <CODE>null</CODE> if it's not found.
145    * @exception IllegalArgumentException If the id passed in is null.
146    */

147   protected Classpath findClasspath(String JavaDoc anId, Collection JavaDoc someMagnets) {
148     // Validate the arguments
149
if (anId == null) {
150       throw new IllegalArgumentException JavaDoc("The classpath identifer passed in is null");
151     } else if (someMagnets == null) {
152       throw new IllegalArgumentException JavaDoc("The collection of magnet passed in is null");
153     }
154     
155     Classpath aResult = null;
156     for (Iterator JavaDoc it = someMagnets.iterator(); aResult == null && it.hasNext(); ) {
157       Magnet aParentMagnet = (Magnet) it.next();
158       aResult = findClasspath(anId, aParentMagnet);
159     }
160     
161     return aResult;
162   }
163   
164   /**
165    * Finds the classpath identifier by the ID passed in.
166    *
167    * @param anId The identifier of the classpath to retrieve.
168    * @param aMagnet The magnet in which the classpath is.
169    * @return The found classpath or <CODE>null</CODE> if it's not found.
170    * @exception IllegalArgumentException If the id passed in is null.
171    */

172   protected Classpath findClasspath(String JavaDoc anId, Magnet aMagnet) {
173     // Validate the arguments
174
if (anId == null) {
175       throw new IllegalArgumentException JavaDoc("The classpath identifer passed in is null");
176     } else if (aMagnet == null) {
177       throw new IllegalArgumentException JavaDoc("The magnet passed in is null");
178     }
179
180     // Search for the classpath
181
boolean isFound = false;
182     Classpath aResult = null;
183
184     for (Iterator JavaDoc it = aMagnet.getObjectsFor("classpath").iterator(); !isFound && it.hasNext(); ) {
185       Classpath aClasspath = (Classpath) it.next();
186       if (anId.equals(aClasspath.getId())) {
187         isFound = true;
188         aResult = aClasspath;
189       }
190     }
191
192     if (aResult == null && aMagnet.getParents().size() != 0) {
193       return findClasspath(anId, aMagnet.getParents());
194     } else {
195       return aResult;
196     }
197   }
198
199   /**
200    * Returns the class loader of the parent classpath passed.
201    *
202    * @param aClasspath The child classpath.
203    * @return The parent class loader created.
204    */

205   protected ClassLoader JavaDoc getParentClassloader(Classpath aClasspath) throws MagnetException {
206     // Validate the argument
207
if (aClasspath == null) {
208       throw new RuntimeException JavaDoc("The classpath passed in is null");
209     }
210
211     ArrayList JavaDoc someIdentifiers = new ArrayList JavaDoc();
212     return getParentClassloaderIter(aClasspath, someIdentifiers);
213   }
214
215   /**
216    *
217    */

218   private ClassLoader JavaDoc getParentClassloaderIter(Classpath aClasspath, List JavaDoc someIdentifiers) throws MagnetException {
219     // Validate for circular references
220
if (someIdentifiers.contains(aClasspath.getId())) {
221       throw new IllegalStateException JavaDoc("Circular referenced classpath objects detected: " + aClasspath.getId());
222     } else {
223       someIdentifiers.add(aClasspath.getId());
224     }
225
226     if (aClasspath.getParent() == null) {
227       return ClassLoader.getSystemClassLoader();
228     } else {
229       Classpath aParentClasspath = findClasspath(aClasspath.getParent(), getMagnet());
230       if (aParentClasspath == null) {
231         String JavaDoc aMessage = "Unable to find the parent classpath: " + aClasspath.getParent();
232         _theLogger.error(aMessage);
233         throw new MagnetException(aMessage);
234       }
235
236       ClassLoader JavaDoc aParentClassloader = getParentClassloaderIter(aParentClasspath, someIdentifiers);
237       return aParentClasspath.createClassLoader(aParentClassloader);
238     }
239   }
240
241   /**
242    * Parses the command string of this launcher to generate an array of command arguments.
243    *
244    * @return An array of command arguments
245    */

246   protected String JavaDoc[] parseCommandString() {
247     if (_theArguments != null && _theArguments.length() > 0) {
248       CmdLine aCommandLine = CmdLine.parse(_theArguments);
249       return aCommandLine.toArray();
250     } else {
251       return new String JavaDoc[0];
252     }
253   }
254
255   /**
256    *
257    */

258   private void logClassLoader(ClassLoader JavaDoc aClassLoader) {
259     StringBuffer JavaDoc aBuffer = new StringBuffer JavaDoc();
260     aBuffer.append("Context class loader is: ").append(aClassLoader).append("\n");
261     if (aClassLoader instanceof java.net.URLClassLoader JavaDoc) {
262       java.net.URL JavaDoc[] someURLs = ((java.net.URLClassLoader JavaDoc) aClassLoader).getURLs();
263       for (int i = 0; i < someURLs.length; i++) {
264         aBuffer.append("\t[").append(i+1).append("] ").append(someURLs[i]).append("\n");
265       }
266     }
267     while (aClassLoader.getParent() != null) {
268       aClassLoader = aClassLoader.getParent();
269       aBuffer.append("Parent class loader is: ").append(aClassLoader).append("\n");
270       if (aClassLoader instanceof java.net.URLClassLoader JavaDoc) {
271         java.net.URL JavaDoc[] someURLs = ((java.net.URLClassLoader JavaDoc) aClassLoader).getURLs();
272         for (int i = 0; i < someURLs.length; i++) {
273           aBuffer.append("\t[").append(i+1).append("] ").append(someURLs[i]).append("\n");
274         }
275       }
276     }
277     _theLogger.info(aBuffer.toString());
278   }
279
280   /////////////////////////////////////////////////////////////////////////////////////////
281
////////////////////////////////// OVERRIDEN METHODS //////////////////////////////////
282
////////////////////////////////////////////////////////////////////////////////////////
283

284   /**
285    * Renders this objects to the magnet context passed in.
286    *
287    * @param aContext The magnet context to use.
288    * @exception RenderingException If an error occurs while rendering this object.
289    */

290   public void render(MagnetContext aContext) throws RenderingException {
291     // Render the super class
292
super.render(aContext);
293
294     // Find a profile object
295
Profile aProfile = findProfile(aContext.getProfile());
296
297     if (aProfile != null) {
298       // Render the profile and generate a new context
299
aProfile.render(aContext);
300       MagnetContext aSubContext = new MagnetContext(aContext);
301       if (aProfile.getParameters() != null) {
302         for (Iterator JavaDoc it = aProfile.getParameters().getParams().iterator(); it.hasNext(); ) {
303           Param aParam = (Param) it.next();
304           aSubContext.addParameter(aParam, false);
305         }
306       }
307
308       // Resolving the attribute with the subcontext
309
_theMainClass = resolveValue(aSubContext, _theMainClass);
310       _theArguments = resolveValue(aSubContext, _theArguments);
311       _isDaemon = resolveValue(aSubContext, _isDaemon);
312     } else {
313       // The profile specified is not found
314
if (aContext.getProfile() == null || aContext.getProfile().length() == 0) {
315         Log.warn("Unable to find a default profile in this system launcher", this);
316       } else {
317         Log.warn("Unable to find the profile " + aContext.getProfile() + " in this system launcher", this);
318       }
319     }
320   }
321
322   /**
323    * Executes this launch handler for the passed in profile.
324    *
325    * @param aProfileName The name of the profile to execute.
326    */

327   public void execute(String JavaDoc aProfileName) {
328     try {
329       // Find a profile object
330
Profile aProfile = findProfile(aProfileName);
331       if (aProfile == null) {
332         if (aProfileName == null || aProfileName.length() == 0) {
333           Log.warn("Skipping this java launcher --> no default profile defined", this);
334         } else {
335           Log.warn("Skipping this java launcher --> no profile found for the name " + aProfileName, this);
336         }
337         return;
338       }
339
340       Log.info("Executing profile " + aProfile.getName(), this);
341
342       // Find the classpath
343
ClassLoader JavaDoc aClassloader = ClassLoader.getSystemClassLoader();
344       Collection JavaDoc someClasspath = aProfile.getObjectsFor("classpath");
345       if (!someClasspath.isEmpty()) {
346         // Create the class loader
347
Classpath aClasspath = (Classpath) someClasspath.iterator().next();
348         ClassLoader JavaDoc aParentClassloader = getParentClassloader(aClasspath);
349         aClassloader = aClasspath.createClassLoader(aParentClassloader);
350       }
351
352       // Defining the arguments of the main method
353
String JavaDoc[] someArguments = parseCommandString();
354
355       // Logging info on the java class to execute
356
logClassLoader(aClassloader);
357       Log.info("Calling the main() method on the class " + _theMainClass, this);
358
359       if (isDaemon()) {
360         Log.info("Executing the main() method using a daemon thread", this);
361       }
362
363       if (someArguments.length > 0) {
364         StringBuffer JavaDoc aBuffer = new StringBuffer JavaDoc();
365         Log.info("Applicatiom arguments passed to the main() method:", this);
366         for (int i = 0; i < someArguments.length; i++) {
367           aBuffer.setLength(0);
368           aBuffer.append("\targs[").append(i).append("] = ").append(someArguments[i]);
369           Log.info(aBuffer.toString(), this);
370         }
371       }
372       
373       // Load the main class
374
Class JavaDoc aClass = aClassloader.loadClass(_theMainClass);
375       JavaTask aTask = new JavaTask(aClass, someArguments);
376       Thread JavaDoc aThread = new Thread JavaDoc(aTask);
377       aThread.setName(getName() + "-" + aProfile.getName());
378       aThread.setContextClassLoader(aClassloader);
379       aThread.setDaemon(isDaemon());
380       aThread.start();
381
382     } catch (MagnetException de) {
383       String JavaDoc aMessage = "Application error spawning this java process";
384       _theLogger.error(aMessage, de);
385       Log.error(aMessage + " - " + Log.extactMessage(de), this);
386
387     } catch (ClassNotFoundException JavaDoc cnfe) {
388       String JavaDoc aMessage = "Unable to spawn a java process\n\t---> the class specified is not found";
389       _theLogger.error(aMessage, cnfe);
390       Log.error(aMessage + " - " + Log.extactMessage(cnfe), this);
391
392     } catch (RuntimeException JavaDoc re) {
393       String JavaDoc aMessage = "System error spawning this java process";
394       _theLogger.error(aMessage, re);
395       Log.error(aMessage + " - " + Log.extactMessage(re), this);
396     }
397   }
398
399   /**
400    * Returns a string representation of this java launcher.
401    *
402    * @return The string representation of this java launcher.
403    */

404   public String JavaDoc toString() {
405     StringBuffer JavaDoc aBuffer = new StringBuffer JavaDoc(super.toString());
406     aBuffer.append("[mainClass=").append(_theMainClass).
407             append(" arguments=").append(_theArguments).
408             append(" isDaemon=").append(_isDaemon).
409             append("]");
410
411     return aBuffer.toString();
412   }
413 }
414
415
Popular Tags