1 19 20 package com.sslexplorer.applications.types; 21 22 import java.io.File ; 23 import java.io.IOException ; 24 import java.util.ArrayList ; 25 import java.util.Enumeration ; 26 import java.util.Iterator ; 27 import java.util.List ; 28 import java.util.Map ; 29 30 import javax.servlet.http.HttpServletRequest ; 31 32 import org.apache.commons.logging.Log; 33 import org.apache.commons.logging.LogFactory; 34 import org.apache.struts.action.ActionForward; 35 import org.apache.struts.action.ActionMapping; 36 import org.jdom.Element; 37 38 import com.sslexplorer.applications.ApplicationLauncherType; 39 import com.sslexplorer.applications.ApplicationShortcut; 40 import com.sslexplorer.applications.server.ApplicationServerType; 41 import com.sslexplorer.applications.server.ProcessMonitor; 42 import com.sslexplorer.applications.server.ServerApplicationLauncher; 43 import com.sslexplorer.applications.server.ServerLauncher; 44 import com.sslexplorer.applications.server.ServerLauncherEvents; 45 import com.sslexplorer.boot.XMLElement; 46 import com.sslexplorer.extensions.ExtensionDescriptor; 47 import com.sslexplorer.extensions.ExtensionException; 48 import com.sslexplorer.policyframework.LaunchSession; 49 import com.sslexplorer.security.SessionInfo; 50 51 61 public class JavasType implements ApplicationLauncherType, 62 ApplicationServerType { 63 64 final static Log log = LogFactory.getLog(JavasType.class); 65 66 69 public final static String TYPE = "javas"; 70 71 private String jre; 73 74 private ExtensionDescriptor descriptor; 75 76 private String classpath = ""; 77 78 private String mainclass; 79 80 private File workingDir; 81 82 private String [] jvm; 83 84 private List <String > programArgs = new ArrayList <String >(); 85 86 private List <String > jvmArgs = new ArrayList <String >(); 87 88 private ProcessMonitor process; 89 90 private String javaLibraryPath = ""; 91 92 protected ServerLauncherEvents events; 93 94 protected ServerLauncher launcher; 95 96 102 public void start(ExtensionDescriptor descriptor, Element element) 103 throws ExtensionException { 104 this.descriptor = descriptor; 105 if (element.getName().equals(TYPE)) { 106 107 jre = element.getAttribute("jre").getValue(); 108 109 if (jre == null) { 110 throw new ExtensionException( 111 ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR, 112 "<application> element requires attribute 'jre'"); 113 } 114 115 try { 116 ExtensionDescriptor.getVersion(jre); 117 } catch (Throwable ex) { 118 throw new ExtensionException( 119 ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR, 120 "Invalid value '" + jre 121 + "' specified for 'jre' attribute"); 122 } 123 124 for (Iterator it = element.getChildren().iterator(); it.hasNext();) { 125 Element e = (Element) it.next(); 126 127 if (e.getName().equalsIgnoreCase("classpath")) { 128 verifyClasspath(e); 129 } else if (e.getName().equalsIgnoreCase("main")) { 130 verifyMain(e); 131 } else { 132 throw new ExtensionException( 133 ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR, 134 "Unexpected element <" + e.getName() 135 + "> found in <application>"); 136 } 137 } 138 139 } 140 141 } 142 143 148 public void verifyRequiredElements() throws ExtensionException { 149 } 150 151 156 public boolean isHidden() { 157 return false; 158 } 159 160 165 public String getType() { 166 return TYPE; 167 } 168 169 176 public void prepare(ServerLauncher launcher, ServerLauncherEvents events, 177 XMLElement element) throws IOException { 178 179 if (events != null) 180 events.debug("Processing <" + element.getName() 181 + "> for java application type"); 182 183 this.launcher = launcher; 184 this.events = events; 185 186 if (element.getName().equals("java")) { 187 188 String jre = (String ) element.getAttribute("jre"); 189 190 if (events != null) 191 events 192 .debug("Checking our version against the required application version " 193 + jre); 194 195 if (!ServerLauncher.checkVersion(jre)) { 196 throw new IOException ( 197 "Application requires Java Runtime Environment " + jre); 198 } 199 200 205 if (System.getProperty("java.version").startsWith("1.1") 206 && !System.getProperty("java.vendor").startsWith( 207 "Microsoft")) 208 classpath = System.getProperty("java.home") 209 + File.pathSeparator + "lib" + File.pathSeparator 210 + "classes.zip"; 211 212 Enumeration e = element.enumerateChildren(); 213 214 while (e.hasMoreElements()) { 215 XMLElement el = (XMLElement) e.nextElement(); 216 217 if (el.getName().equalsIgnoreCase("classpath")) { 218 buildClassPath(el); 219 } else if (el.getName().equalsIgnoreCase("main")) { 220 mainclass = (String ) el.getAttribute("class"); 221 if (events != null) 222 events.debug("Main class is " + mainclass); 223 String dir = (String ) el.getAttribute("dir"); 224 if (events != null) 225 events.debug("Dir is " + dir); 226 if (dir != null) { 227 workingDir = new File (launcher.replaceTokens(dir)); 228 } else { 229 workingDir = null; 230 } 231 buildProgramArguments(el); 232 } 233 } 234 235 if (events != null) 236 events.debug("Finished preparing application descriptor."); 237 } else { 238 if (events != null) 239 events.debug("Ignoring <" + element.getName() 240 + "> tag as it is not a java application tag"); 241 } 242 243 } 244 245 250 public void start() { 251 execute(classpath, mainclass, workingDir); 252 } 253 254 259 public boolean checkFileCondition(XMLElement el) throws IOException , 260 IllegalArgumentException { 261 String jre = (String ) el.getAttribute("jre"); 262 if (jre == null) { 263 throw new IllegalArgumentException ( 264 "No supported attributes in condition."); 265 } else { 266 return isSupportedJRE(jre); 267 } 268 } 269 270 275 public ProcessMonitor getProcessMonitor() { 276 return process; 277 } 278 279 284 public void stop() throws ExtensionException { 285 } 286 287 292 public void activate() throws ExtensionException { 293 } 294 295 300 public boolean canStop() throws ExtensionException { 301 return true; 302 } 303 304 314 public ActionForward launch(Map <String , String > parameters, 315 ExtensionDescriptor descriptor, ApplicationShortcut shortcut, 316 ActionMapping mapping, LaunchSession launchSession, 317 String returnTo, HttpServletRequest request) 318 throws ExtensionException { 319 if (log.isInfoEnabled()) 320 log.info("Starting Java server application " 321 + shortcut.getResourceName()); 322 323 ServerApplicationLauncher app; 324 try { 325 app = new ServerApplicationLauncher(parameters, shortcut 326 .getApplication(), launchSession.getSession(), shortcut); 327 app.start(); 328 } catch (Exception e) { 329 throw new ExtensionException(ExtensionException.FAILED_TO_LAUNCH, e); 330 } 331 332 return null; 333 } 334 335 341 public boolean isAgentRequired(ApplicationShortcut shortcut, 342 ExtensionDescriptor descriptor) { 343 return false; 344 } 345 346 protected void addClasspathEntry(XMLElement e) throws IOException { 347 addClasspathEntry(e, null); 348 } 349 350 protected void addClasspathEntry(XMLElement e, String app) 351 throws IOException { 352 353 events.debug("Adding " 354 + launcher.getInstallDir() 355 + (e.getContent() != null ? File.separatorChar + e.getContent() 356 : "") + " to CLASSPATH"); 357 358 classpath += (!classpath.equals("") ? File.pathSeparator : "") 359 + launcher.getInstallDir() 360 + (e.getContent() != null ? File.separatorChar + e.getContent() 361 : ""); 362 } 363 364 protected void buildClassPath(XMLElement element) throws IOException { 365 buildClassPath(element, null); 366 } 367 368 protected void buildClassPath(XMLElement element, String app) 369 throws IOException { 370 371 if (events != null) 372 events.debug("Building classpath"); 373 Enumeration en = element.enumerateChildren(); 374 XMLElement e; 375 376 while (en.hasMoreElements()) { 377 e = (XMLElement) en.nextElement(); 378 if (e.getName().equalsIgnoreCase("jar")) { 379 addClasspathEntry(e, app); 380 } else if (e.getName().equals("if")) { 381 382 String jre = (String ) e.getAttribute("jre"); 383 if (jre == null) { 384 String parameter = (String ) e.getAttribute("parameter"); 385 386 if (parameter != null) { 387 String requiredValue = (String ) e.getAttribute("value"); 388 boolean not = "true".equalsIgnoreCase(((String ) e 389 .getAttribute("not"))); 390 391 String value = (String ) launcher.getDescriptorParams() 393 .get(parameter); 394 395 if ((!not && requiredValue.equalsIgnoreCase(value)) 396 || (not && !requiredValue 397 .equalsIgnoreCase(value))) { 398 buildClassPath(e, app); 399 } 400 401 } else 402 throw new IOException ( 403 "<if> element requires jre or parameter attribute"); 404 } else { 405 406 if (isSupportedJRE(jre)) { 407 buildClassPath(e, app); 408 } 409 } 410 } else 411 throw new IOException ("Invalid element <" + e.getName() 412 + "> found in <classpath>"); 413 } 414 415 } 416 417 private boolean isSupportedJRE(String jre) { 418 419 int[] ourVersion = ServerLauncher.getVersion(System 420 .getProperty("java.version")); 421 422 if (jre.startsWith(">")) { 423 424 int[] requiredVersion = ServerLauncher.getVersion(jre.substring(1)); 426 for (int i = 0; i < ourVersion.length && i < requiredVersion.length; i++) { 427 if (ourVersion[i] < requiredVersion[i]) 428 return false; 429 } 430 return true; 431 432 } else if (jre.startsWith("<")) { 433 int[] requiredVersion = ServerLauncher.getVersion(jre.substring(1)); 435 for (int i = 0; i < ourVersion.length && i < requiredVersion.length; i++) { 436 if (ourVersion[i] > requiredVersion[i]) 437 return false; 438 } 439 return true; 440 441 } else { 442 int[] requiredVersion = ServerLauncher.getVersion(jre); 444 for (int i = 0; i < ourVersion.length && i < requiredVersion.length; i++) { 445 if (ourVersion[i] != requiredVersion[i]) 446 return false; 447 } 448 return true; 449 450 } 451 452 } 453 454 protected void addArgument(String arg) { 455 if (arg != null) 456 programArgs.add(launcher.replaceTokens(arg)); 457 } 458 459 protected void addJVMArgument(String arg) { 460 if (arg != null) { 461 462 if (arg.startsWith("java.library.path")) { 463 int idx = arg.indexOf('='); 464 465 if (idx > -1) { 466 String val = arg.substring(idx + 1).replace('/', 467 File.separatorChar); 468 javaLibraryPath += (javaLibraryPath.equals("") ? val 469 : System.getProperty("path.separator") + val); 470 471 if (events != null) 472 events 473 .debug(val 474 + " has been appened to system property java.library.path"); 475 } else if (events != null) 476 events.debug("Invalid java.library.path system property: " 477 + arg); 478 479 } else 480 jvmArgs.add(launcher.replaceTokens(arg)); 481 } 482 } 483 484 private void addArgument(XMLElement e) throws IOException { 485 if (e.getName().equalsIgnoreCase("arg")) 486 addArgument(e.getContent()); 487 else if (e.getName().equalsIgnoreCase("jvm")) { 488 addJVMArgument(e.getContent()); 489 } else { 490 throw new IOException ("Unexpected element <" + e.getName() 491 + "> found"); 492 } 493 } 494 495 private void buildProgramArguments(XMLElement element) throws IOException { 496 497 Enumeration en = element.enumerateChildren(); 498 499 while (en.hasMoreElements()) { 500 501 XMLElement e = (XMLElement) en.nextElement(); 502 if (e.getName().equalsIgnoreCase("arg")) 503 addArgument(e); 504 else if (e.getName().equalsIgnoreCase("jvm")) { 505 addArgument(e); 506 } else if (e.getName().equalsIgnoreCase("if")) { 507 508 String jre = (String ) e.getAttribute("jre"); 509 if (jre == null) { 510 String parameter = (String ) e.getAttribute("parameter"); 511 boolean not = "true".equalsIgnoreCase((String ) e 512 .getAttribute("not")); 513 514 if (parameter != null) { 515 String requiredValue = (String ) e.getAttribute("value"); 516 517 String value = (String ) launcher.getDescriptorParams() 519 .get(parameter); 520 521 if ((!not && requiredValue.equalsIgnoreCase(value)) 522 || (not && !requiredValue 523 .equalsIgnoreCase(value))) { 524 buildProgramArguments(e); 525 } 526 527 } else 528 throw new IOException ( 529 "<if> element requires jre or parameter attribute"); 530 } else { 531 if (isSupportedJRE(jre)) { 533 buildProgramArguments(e); 534 } 535 536 } 537 538 } else 539 throw new IOException ("Unexpected element <" + e.getName() 540 + "> found in <main>"); 541 } 542 543 } 544 545 private void execute(String classpath, String mainclass, File workingDir) { 546 547 String [] args = new String [programArgs.size()]; 548 programArgs.toArray(args); 549 550 if (!javaLibraryPath.equals("")) 551 jvmArgs.add("java.library.path=" 552 + launcher.replaceTokens(javaLibraryPath)); 553 554 jvm = new String [jvmArgs.size()]; 555 jvmArgs.toArray(jvm); 556 557 String [] cmdargs = new String [jvm.length + args.length + 4]; 558 562 cmdargs[0] = System.getProperty("java.home") + File.separator + "bin" 563 + File.separator + "java"; 564 cmdargs[1] = "-classpath"; 565 cmdargs[2] = classpath; 566 567 for (int i = 0; i < jvm.length; i++) { 568 cmdargs[3 + i] = "-D" + jvm[i]; 569 } 570 571 cmdargs[jvm.length + 3] = mainclass; 572 573 System.arraycopy(args, 0, cmdargs, jvm.length + 4, args.length); 574 575 String cmdline = ""; 576 for (int i = 0; i < cmdargs.length; i++) 577 cmdline += " " + cmdargs[i]; 578 579 if (events != null) 580 events.debug("Executing command: " + cmdline); 581 582 try { 583 584 if (events != null) 585 events.executingApplication(launcher.getName(), cmdline.trim()); 586 587 Process prc = Runtime.getRuntime().exec(cmdargs, null, workingDir); 589 process = new ProcessMonitor(launcher.getName(), prc); 590 } catch (IOException ex) { 591 if (events != null) 592 events.debug("Process execution failed: " + ex.getMessage()); 593 } 594 595 } 596 597 private void verifyClasspath(Element element) throws ExtensionException { 598 for (Iterator it = element.getChildren().iterator(); it.hasNext();) { 599 Element e = (Element) it.next(); 600 601 if (e.getName().equalsIgnoreCase("jar")) { 602 descriptor.processFile(e); 603 } else if (e.getName().equals("if")) { 604 verifyClasspath(e); 605 } else { 606 throw new ExtensionException( 607 ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR, 608 "Invalid element <" + e.getName() 609 + "> found in <classpath>"); 610 } 611 } 612 } 613 614 private void verifyMain(Element element) throws ExtensionException { 615 for (Iterator it = element.getChildren().iterator(); it.hasNext();) { 616 Element e = (Element) it.next(); 617 if (e.getName().equalsIgnoreCase("if")) { 618 verifyMain(e); 619 } else if (!e.getName().equalsIgnoreCase("arg") 620 && !e.getName().equalsIgnoreCase("jvm")) { 621 throw new ExtensionException( 622 ExtensionException.FAILED_TO_PROCESS_DESCRIPTOR, 623 "Unexpected element <" + e.getName() 624 + "> found in <main>"); 625 } 626 } 627 } 628 629 634 public void descriptorCreated(Element element, SessionInfo session) 635 throws IOException { 636 } 637 638 643 public String getTypeBundle() { 644 return "applications"; 645 } 646 647 652 public boolean isServerSide() { 653 return true; 654 } 655 } | Popular Tags |