1 18 19 package org.apache.tools.ant.taskdefs; 20 21 import java.io.File ; 22 import java.io.IOException ; 23 import java.io.PrintStream ; 24 import java.lang.reflect.InvocationTargetException ; 25 import java.lang.reflect.Method ; 26 import java.lang.reflect.Modifier ; 27 import org.apache.tools.ant.AntClassLoader; 28 import org.apache.tools.ant.BuildException; 29 import org.apache.tools.ant.Project; 30 import org.apache.tools.ant.ProjectComponent; 31 import org.apache.tools.ant.Task; 32 import org.apache.tools.ant.taskdefs.condition.Os; 33 import org.apache.tools.ant.types.Commandline; 34 import org.apache.tools.ant.types.CommandlineJava; 35 import org.apache.tools.ant.types.Path; 36 import org.apache.tools.ant.types.Permissions; 37 import org.apache.tools.ant.util.JavaEnvUtils; 38 import org.apache.tools.ant.util.TimeoutObserver; 39 import org.apache.tools.ant.util.Watchdog; 40 41 45 public class ExecuteJava implements Runnable , TimeoutObserver { 46 47 private Commandline javaCommand = null; 48 private Path classpath = null; 49 private CommandlineJava.SysProperties sysProperties = null; 50 private Permissions perm = null; 51 private Method main = null; 52 private Long timeout = null; 53 private volatile Throwable caught = null; 54 private volatile boolean timedOut = false; 55 private Thread thread = null; 56 57 61 public void setJavaCommand(Commandline javaCommand) { 62 this.javaCommand = javaCommand; 63 } 64 65 70 public void setClasspath(Path p) { 71 classpath = p; 72 } 73 74 78 public void setSystemProperties(CommandlineJava.SysProperties s) { 79 sysProperties = s; 80 } 81 82 87 public void setPermissions(Permissions permissions) { 88 perm = permissions; 89 } 90 91 98 public void setOutput(PrintStream out) { 99 } 100 101 106 public void setTimeout(Long timeout) { 107 this.timeout = timeout; 108 } 109 110 115 public void execute(Project project) throws BuildException { 116 final String classname = javaCommand.getExecutable(); 117 118 AntClassLoader loader = null; 119 try { 120 if (sysProperties != null) { 121 sysProperties.setSystem(); 122 } 123 Class target = null; 124 try { 125 if (classpath == null) { 126 target = Class.forName(classname); 127 } else { 128 loader = project.createClassLoader(classpath); 129 loader.setParent(project.getCoreLoader()); 130 loader.setParentFirst(false); 131 loader.addJavaLibraries(); 132 loader.setIsolated(true); 133 loader.setThreadContextLoader(); 134 loader.forceLoadClass(classname); 135 target = Class.forName(classname, true, loader); 136 } 137 } catch (ClassNotFoundException e) { 138 throw new BuildException("Could not find " + classname + "." 139 + " Make sure you have it in your" 140 + " classpath"); 141 } 142 main = target.getMethod("main", new Class [] {String [].class}); 143 if (main == null) { 144 throw new BuildException("Could not find main() method in " 145 + classname); 146 } 147 if ((main.getModifiers() & Modifier.STATIC) == 0) { 148 throw new BuildException("main() method in " + classname 149 + " is not declared static"); 150 } 151 if (timeout == null) { 152 run(); 153 } else { 154 thread = new Thread (this, "ExecuteJava"); 155 Task currentThreadTask 156 = project.getThreadTask(Thread.currentThread()); 157 project.registerThreadTask(thread, currentThreadTask); 159 thread.setDaemon(true); 164 Watchdog w = new Watchdog(timeout.longValue()); 165 w.addTimeoutObserver(this); 166 synchronized (this) { 167 thread.start(); 168 w.start(); 169 try { 170 wait(); 171 } catch (InterruptedException e) { 172 } 174 if (timedOut) { 175 project.log("Timeout: sub-process interrupted", 176 Project.MSG_WARN); 177 } else { 178 thread = null; 179 w.stop(); 180 } 181 } 182 } 183 if (caught != null) { 184 throw caught; 185 } 186 } catch (BuildException e) { 187 throw e; 188 } catch (SecurityException e) { 189 throw e; 190 } catch (ThreadDeath e) { 191 throw e; 193 } catch (Throwable e) { 194 throw new BuildException(e); 195 } finally { 196 if (loader != null) { 197 loader.resetThreadContextLoader(); 198 loader.cleanup(); 199 loader = null; 200 } 201 if (sysProperties != null) { 202 sysProperties.restoreSystem(); 203 } 204 } 205 } 206 207 211 public void run() { 212 final Object [] argument = {javaCommand.getArguments()}; 213 try { 214 if (perm != null) { 215 perm.setSecurityManager(); 216 } 217 main.invoke(null, argument); 218 } catch (InvocationTargetException e) { 219 Throwable t = e.getTargetException(); 220 if (!(t instanceof InterruptedException )) { 221 caught = t; 222 } 223 } catch (Throwable t) { 224 caught = t; 225 } finally { 226 if (perm != null) { 227 perm.restoreSecurityManager(); 228 } 229 synchronized (this) { 230 notifyAll(); 231 } 232 } 233 } 234 235 240 public synchronized void timeoutOccured(Watchdog w) { 241 if (thread != null) { 242 timedOut = true; 243 thread.interrupt(); 244 } 245 notifyAll(); 246 } 247 248 253 public synchronized boolean killedProcess() { 254 return timedOut; 255 } 256 257 266 public int fork(ProjectComponent pc) throws BuildException { 267 CommandlineJava cmdl = new CommandlineJava(); 268 cmdl.setClassname(javaCommand.getExecutable()); 269 String [] args = javaCommand.getArguments(); 270 for (int i = 0; i < args.length; i++) { 271 cmdl.createArgument().setValue(args[i]); 272 } 273 if (classpath != null) { 274 cmdl.createClasspath(pc.getProject()).append(classpath); 275 } 276 if (sysProperties != null) { 277 cmdl.addSysproperties(sysProperties); 278 } 279 Redirector redirector = new Redirector(pc); 280 Execute exe 281 = new Execute(redirector.createHandler(), 282 timeout == null 283 ? null 284 : new ExecuteWatchdog(timeout.longValue())); 285 exe.setAntRun(pc.getProject()); 286 if (Os.isFamily("openvms")) { 287 setupCommandLineForVMS(exe, cmdl.getCommandline()); 288 } else { 289 exe.setCommandline(cmdl.getCommandline()); 290 } 291 try { 292 int rc = exe.execute(); 293 redirector.complete(); 294 return rc; 295 } catch (IOException e) { 296 throw new BuildException(e); 297 } finally { 298 timedOut = exe.killedProcess(); 299 } 300 } 301 302 310 public static void setupCommandLineForVMS(Execute exe, String [] command) { 311 exe.setVMLauncher(true); 313 File vmsJavaOptionFile = null; 314 try { 315 String [] args = new String [command.length - 1]; 316 System.arraycopy(command, 1, args, 0, command.length - 1); 317 vmsJavaOptionFile = JavaEnvUtils.createVmsJavaOptionFile(args); 318 vmsJavaOptionFile.deleteOnExit(); 323 String [] vmsCmd = {command[0], "-V", vmsJavaOptionFile.getPath()}; 324 exe.setCommandline(vmsCmd); 325 } catch (IOException e) { 326 throw new BuildException("Failed to create a temporary file for \"-V\" switch"); 327 } 328 } 329 330 } 331 | Popular Tags |