1 package org.sapia.util; 2 3 4 import java.io.File ; 7 8 import java.lang.reflect.InvocationTargetException ; 9 import java.lang.reflect.Method ; 10 11 import java.net.MalformedURLException ; 12 import java.net.URL ; 13 import java.net.URLClassLoader ; 14 15 import java.util.ArrayList ; 16 import java.util.StringTokenizer ; 17 18 19 63 public class ApplicationStarter implements Runnable { 64 68 69 private Class _theMainClass; 70 71 72 private String [] _theArguments; 73 74 78 84 protected ApplicationStarter(Class aMainClass, String [] someArguments) { 85 _theMainClass = aMainClass; 86 _theArguments = someArguments; 87 } 88 89 93 100 public static void main(String [] args) { 101 try { 102 boolean isDebug = false; 103 String anApplicationClasspath = null; 104 String aClassName = null; 105 String [] someArguments = new String [0]; 106 107 for (int i = 0; i < args.length; i++) { 109 if (args[i].equals("-ashelp")) { 110 usage(); 111 System.exit(0); 112 } else if (args[i].equals("-asdebug")) { 113 isDebug = true; 114 } else if (args[i].equals("-ascp")) { 115 anApplicationClasspath = args[++i]; 116 } else if (aClassName == null) { 117 aClassName = args[i]; 118 } else { 119 if (someArguments.length == 0) { 120 someArguments = new String [args.length - i]; 121 } 122 123 someArguments[someArguments.length - (args.length - i)] = args[i]; 124 } 125 } 126 127 start(anApplicationClasspath, aClassName, someArguments, isDebug); 128 } catch (ApplicationStarterException ase) { 129 ase.printStackTrace(); 130 System.exit(1); 131 } 132 } 133 134 147 public static void start(String aClasspath, String aClassName, 148 String [] someArguments, boolean isDebug) throws ApplicationStarterException { 149 try { 150 if (isDebug) { 152 logState(aClasspath, aClassName, someArguments); 153 } 154 155 ClassLoader aClassLoader = createClassLoaderFor(aClasspath, isDebug); 157 158 if (isDebug) { 160 System.out.println("\nCreated the classloader " + aClassLoader); 161 } 162 163 Class aMainClass = aClassLoader.loadClass(aClassName); 165 ApplicationStarter aStarter = new ApplicationStarter(aMainClass, 166 someArguments); 167 168 Thread aThread = new Thread (aStarter); 170 aThread.setName(aClassName.substring(aClassName.lastIndexOf(".") + 1)); 171 aThread.setContextClassLoader(aClassLoader); 172 aThread.start(); 173 } catch (ClassNotFoundException cnfe) { 174 if (!isDebug) { 175 logState(aClasspath, aClassName, someArguments); 176 } 177 178 StringBuffer aMessage = new StringBuffer (); 179 aMessage.append("Unable to load the class ").append(aClassName) 180 .append(" - ").append(cnfe.getMessage()); 181 throw new ApplicationStarterException(aMessage.toString(), cnfe); 182 } catch (RuntimeException re) { 183 if (!isDebug) { 184 logState(aClasspath, aClassName, someArguments); 185 } 186 187 StringBuffer aMessage = new StringBuffer (); 188 aMessage.append("System error starting the class").append(aClassName); 189 throw new ApplicationStarterException(aMessage.toString(), re); 190 } 191 } 192 193 201 private static void logState(String anApplicationClasspath, 202 String aClassName, String [] someArguments) { 203 StringBuffer aBuffer = new StringBuffer ( 204 "\nSAPIA Application Starter 1.0\n============================="); 205 aBuffer.append("\nStarting application with this configuration:"); 206 aBuffer.append("\n appClasspath: ").append(anApplicationClasspath) 207 .append("\n className : ").append(aClassName); 208 209 if (aClassName != null) { 210 aBuffer.append("\n threadName : ").append(aClassName.substring(aClassName.lastIndexOf( 211 ".") + 1)); 212 } 213 214 aBuffer.append("\n appArguments: "); 215 216 if (someArguments.length == 0) { 217 aBuffer.append("[]"); 218 } else { 219 for (int i = 0; i < someArguments.length; i++) { 220 aBuffer.append("[").append(someArguments[i]).append("] "); 221 } 222 } 223 224 System.out.println(aBuffer.toString()); 225 } 226 227 230 public static void usage() { 231 StringBuffer aBuffer = new StringBuffer ("SAPIA Application Starter 1.0\n"); 232 aBuffer.append( 233 "Usage: java org.sapia.util.ApplicationStarter [options] {class} [args...]\n") 234 .append("Options:\n").append(" -ashelp\t\tprint this message\n") 235 .append(" -asdebug\t\tprint debugging information\n") 236 .append(" -ascp <resources>\tthe classpath of the classloader that will execute the main class\n") 237 .append("Example: java org.sapia.util.ApplicationStarter -ashelp\n") 238 .append("Example: java org.sapia.util.ApplicationStarter -asdebug -ascp test.jar MyMainClass foo bar\n"); 239 240 System.out.println(aBuffer.toString()); 241 } 242 243 251 private static ClassLoader createClassLoaderFor(String aClasspath, 252 boolean isDebug) { 253 ClassLoader aClassLoader; 254 255 if ((aClasspath == null) || (aClasspath.length() == 0)) { 256 aClassLoader = ClassLoader.getSystemClassLoader(); 257 } else { 258 try { 259 ArrayList someURLs = new ArrayList (); 260 String aHomeDir = System.getProperty("user.dir"); 261 262 for (StringTokenizer st = new StringTokenizer (aClasspath, 263 File.pathSeparator); st.hasMoreTokens();) { 264 String aToken = st.nextToken(); 265 266 if (!aToken.startsWith("file:/") || !aToken.startsWith("http:/")) { 267 File aFile = new File (aToken); 268 269 if (aFile.exists()) { 270 aToken = aFile.toURL().toExternalForm(); 271 } else { 272 aFile = new File (aHomeDir, aToken); 273 274 if (aFile.exists()) { 275 aToken = aFile.toURL().toExternalForm(); 276 } 277 } 278 } 279 280 URL anURL = new URL (aToken); 281 someURLs.add(anURL); 282 } 283 284 if (isDebug) { 285 for (int i = 0; i < someURLs.size(); i++) { 286 System.out.println(((URL ) someURLs.get(i)).toExternalForm()); 287 } 288 } 289 290 aClassLoader = URLClassLoader.newInstance((URL []) someURLs.toArray( 291 new URL [0]), ClassLoader.getSystemClassLoader()); 292 } catch (MalformedURLException mue) { 293 throw new RuntimeException ( 294 "Unable to create a class loader using the classpath: " + aClasspath); 295 } 296 } 297 298 return aClassLoader; 299 } 300 301 305 308 public void run() { 309 try { 310 Method aMainMethod = _theMainClass.getDeclaredMethod("main", 311 new Class [] { String [].class }); 312 aMainMethod.invoke(_theMainClass, new Object [] { _theArguments }); 313 } catch (NoSuchMethodException nsme) { 314 StringBuffer aBuffer = new StringBuffer (); 315 aBuffer.append("Method main(String[]) not found on class ") 316 .append(_theMainClass.getName()).append(" - ").append(nsme.getMessage()); 317 throw new RuntimeException (aBuffer.toString()); 318 } catch (InvocationTargetException ite) { 319 StringBuffer aBuffer = new StringBuffer (); 320 aBuffer.append("Error calling main method on class ") 321 .append(_theMainClass.getName()).append(" - "); 322 323 if (ite.getTargetException() != null) { 324 aBuffer.append(ite.getTargetException().getMessage()); 325 } else { 326 aBuffer.append(ite.getMessage()); 327 } 328 329 throw new RuntimeException (aBuffer.toString()); 330 } catch (IllegalAccessException iae) { 331 StringBuffer aBuffer = new StringBuffer (); 332 aBuffer.append( 333 "main(String[]) method was found but is not accessible on class ") 334 .append(_theMainClass.getName()).append(" - ").append(iae.getMessage()); 335 throw new RuntimeException (aBuffer.toString()); 336 } 337 } 338 } 339 | Popular Tags |