1 package org.tanukisoftware.wrapper; 2 3 45 46 import java.lang.reflect.InvocationTargetException ; 47 import java.lang.reflect.Method ; 48 import java.lang.reflect.Modifier ; 49 50 86 public class WrapperStartStopApp 87 implements WrapperListener, Runnable 88 { 89 92 private Method m_startMainMethod; 93 94 97 private String [] m_startMainArgs; 98 99 102 private Method m_stopMainMethod; 103 104 108 private boolean m_stopWait; 109 110 113 private String [] m_stopMainArgs; 114 115 119 private boolean m_mainStarted; 120 121 125 private boolean m_mainComplete; 126 127 130 private Integer m_mainExitCode; 131 132 135 private boolean m_startComplete; 136 137 140 protected WrapperStartStopApp( String args[] ) 141 { 142 143 Class wmClass = WrapperManager.class; 145 146 if ( args.length < 5 ) 148 { 149 System.out.println( "WrapperStartStopApp: Not enough argments. Minimum 5 required." ); 150 showUsage(); 151 WrapperManager.stop( 1 ); 152 return; } 154 155 156 m_startMainMethod = getMainMethod( args[0] ); 158 String [] startArgs = getArgs( args, 1 ); 160 161 162 int stopArgBase = 2 + startArgs.length; 164 if ( args.length < stopArgBase + 3 ) 165 { 166 System.out.println( "WrapperStartStopApp: Not enough argments. Minimum 3 after start " 167 + "arguments." ); 168 showUsage(); 169 WrapperManager.stop( 1 ); 170 return; } 172 m_stopMainMethod = getMainMethod( args[stopArgBase] ); 174 if ( args[stopArgBase + 1].equalsIgnoreCase( "true" ) ) 176 { 177 m_stopWait = true; 178 } 179 else if ( args[stopArgBase + 1].equalsIgnoreCase( "false" ) ) 180 { 181 m_stopWait = false; 182 } 183 else 184 { 185 System.out.println( "WrapperStartStopApp: The stop_wait argument must be either true " 186 + "or false." ); 187 showUsage(); 188 WrapperManager.stop( 1 ); 189 return; } 191 m_stopMainArgs = getArgs( args, stopArgBase + 2 ); 193 194 WrapperManager.start( this, startArgs ); 199 200 } 203 204 205 protected WrapperStartStopApp( Method startMainMethod, 206 Method stopMainMethod, 207 boolean stopWait, 208 String [] stopMainArgs ) 209 { 210 m_startMainMethod = startMainMethod; 211 m_stopMainMethod = stopMainMethod; 212 m_stopWait = stopWait; 213 m_stopMainArgs = stopMainArgs; 214 } 215 216 219 222 public void run() 223 { 224 synchronized( this ) 226 { 227 m_mainStarted = true; 228 notifyAll(); 229 } 230 231 Throwable t = null; 232 try 233 { 234 if ( WrapperManager.isDebugEnabled() ) 235 { 236 System.out.println( "WrapperStartStopApp: invoking start main method" ); 237 } 238 m_startMainMethod.invoke( null, new Object [] { m_startMainArgs } ); 239 if ( WrapperManager.isDebugEnabled() ) 240 { 241 System.out.println( "WrapperStartStopApp: start main method completed" ); 242 } 243 244 synchronized(this) 245 { 246 m_mainComplete = true; 249 this.notifyAll(); 250 } 251 252 return; 253 } 254 catch ( IllegalAccessException e ) 255 { 256 t = e; 257 } 258 catch ( IllegalArgumentException e ) 259 { 260 t = e; 261 } 262 catch ( InvocationTargetException e ) 263 { 264 t = e.getTargetException(); 265 if ( t == null ) 266 { 267 t = e; 268 } 269 } 270 271 System.out.println(); 274 System.out.println( "WrapperStartStopApp: Encountered an error running start main: " + t ); 275 276 t.printStackTrace(); 280 281 synchronized(this) 282 { 283 if ( m_startComplete ) 284 { 285 WrapperManager.stop( 1 ); 287 return; } 289 else 290 { 291 m_mainComplete = true; 293 m_mainExitCode = new Integer ( 1 ); 294 this.notifyAll(); 295 return; 296 } 297 } 298 } 299 300 303 312 public Integer start( String [] args ) 313 { 314 boolean waitForStartMain = WrapperSystemPropertyUtil.getBooleanProperty( 316 WrapperStartStopApp.class.getName() + ".waitForStartMain", false ); 317 int maxStartMainWait = WrapperSystemPropertyUtil.getIntProperty( 318 WrapperStartStopApp.class.getName() + ".maxStartMainWait", 2 ); 319 maxStartMainWait = Math.max( 1, maxStartMainWait ); 320 321 int maxLoops; 323 if ( waitForStartMain ) 324 { 325 maxLoops = Integer.MAX_VALUE; 326 if ( WrapperManager.isDebugEnabled() ) 327 { 328 System.out.println( "WrapperStartStopApp: start(args) Will wait indefinitely " 329 + "for the main method to complete." ); 330 } 331 } 332 else 333 { 334 maxLoops = maxStartMainWait; if ( WrapperManager.isDebugEnabled() ) 336 { 337 System.out.println( "WrapperStartStopApp: start(args) Will wait up to " + maxLoops 338 + " seconds for the main method to complete." ); 339 } 340 } 341 342 Thread mainThread = new Thread ( this, "WrapperStartStopAppMain" ); 343 synchronized(this) 344 { 345 m_startMainArgs = args; 346 mainThread.start(); 347 348 while ( !m_mainStarted ) 351 { 352 try 353 { 354 this.wait( 1000 ); 355 } 356 catch ( InterruptedException e ) 357 { 358 } 360 } 361 362 int loops = 0; 364 while ( ( loops < maxLoops ) && ( !m_mainComplete ) ) 365 { 366 try 367 { 368 this.wait( 1000 ); 369 } 370 catch ( InterruptedException e ) 371 { 372 } 374 375 if ( !m_mainComplete ) 376 { 377 WrapperManager.signalStarting( 5000 ); 380 } 381 382 loops++; 383 } 384 385 m_startComplete = true; 390 391 if ( WrapperManager.isDebugEnabled() ) 394 { 395 System.out.println( "WrapperStartStopApp: start(args) end. Main Completed=" 396 + m_mainComplete + ", exitCode=" + m_mainExitCode ); 397 } 398 return m_mainExitCode; 399 } 400 } 401 402 405 public int stop( int exitCode ) 406 { 407 if ( WrapperManager.isDebugEnabled() ) 408 { 409 System.out.println( "WrapperStartStopApp: stop(" + exitCode + ")" ); 410 } 411 412 Throwable t = null; 414 try 415 { 416 if ( WrapperManager.isDebugEnabled() ) 417 { 418 System.out.println( "WrapperStartStopApp: invoking stop main method" ); 419 } 420 m_stopMainMethod.invoke( null, new Object [] { m_stopMainArgs } ); 421 if ( WrapperManager.isDebugEnabled() ) 422 { 423 System.out.println( "WrapperStartStopApp: stop main method completed" ); 424 } 425 426 if ( m_stopWait ) 427 { 428 433 int systemThreadCount = WrapperSystemPropertyUtil.getIntProperty( 434 WrapperStartStopApp.class.getName() + ".systemThreadCount", 1 ); 435 systemThreadCount = Math.max( 0, systemThreadCount ); 436 437 int threadCnt; 438 while( ( threadCnt = getNonDaemonThreadCount() ) > systemThreadCount ) 439 { 440 if ( WrapperManager.isDebugEnabled() ) 441 { 442 System.out.println( "WrapperStartStopApp: stopping. Waiting for " 443 + ( threadCnt - systemThreadCount ) + " threads to complete." ); 444 } 445 try 446 { 447 Thread.sleep( 1000 ); 448 } 449 catch ( InterruptedException e ) 450 { 451 } 452 } 453 } 454 455 return exitCode; 457 } 458 catch ( IllegalAccessException e ) 459 { 460 t = e; 461 } 462 catch ( IllegalArgumentException e ) 463 { 464 t = e; 465 } 466 catch ( InvocationTargetException e ) 467 { 468 t = e; 469 } 470 471 System.out.println( "Encountered an error running stop main: " + t ); 473 474 t.printStackTrace(); 478 479 return 1; 481 } 482 483 490 public void controlEvent( int event ) 491 { 492 if ( ( event == WrapperManager.WRAPPER_CTRL_LOGOFF_EVENT ) 493 && WrapperManager.isLaunchedAsService() ) 494 { 495 if ( WrapperManager.isDebugEnabled() ) 497 { 498 System.out.println( "WrapperStartStopApp: controlEvent(" + event + ") Ignored" ); 499 } 500 } 501 else 502 { 503 if ( WrapperManager.isDebugEnabled() ) 504 { 505 System.out.println( "WrapperStartStopApp: controlEvent(" + event + ") Stopping" ); 506 } 507 WrapperManager.stop( 0 ); 508 } 510 } 511 512 515 521 private int getNonDaemonThreadCount() 522 { 523 ThreadGroup topGroup = Thread.currentThread().getThreadGroup(); 525 while ( topGroup.getParent() != null ) 526 { 527 topGroup = topGroup.getParent(); 528 } 529 530 Thread [] threads = new Thread [topGroup.activeCount() * 2]; 533 topGroup.enumerate( threads, true ); 534 535 int liveCount = 0; 538 for ( int i = 0; i < threads.length; i++ ) 539 { 540 547 if ( ( threads[i] != null ) && threads[i].isAlive() ) 548 { 549 if ( ( Thread.currentThread() != threads[i] ) && ( !threads[i].isDaemon() ) ) 551 { 552 liveCount++; 554 } 556 } 557 } 558 560 return liveCount; 561 } 562 563 568 private Method getMainMethod( String className ) 569 { 570 Class mainClass; 572 try 573 { 574 mainClass = Class.forName( className ); 575 } 576 catch ( ClassNotFoundException e ) 577 { 578 System.out.println( "WrapperStartStopApp: Unable to locate the class " + className 579 + ": " + e ); 580 showUsage(); 581 WrapperManager.stop( 1 ); 582 return null; } 584 catch ( LinkageError e ) 585 { 586 System.out.println( "WrapperStartStopApp: Unable to locate the class " + className 587 + ": " + e ); 588 showUsage(); 589 WrapperManager.stop( 1 ); 590 return null; } 592 593 Method mainMethod; 595 try 596 { 597 mainMethod = mainClass.getMethod( "main", new Class [] { String [].class } ); 601 } 602 catch ( NoSuchMethodException e ) 603 { 604 System.out.println( 605 "WrapperStartStopApp: Unable to locate a public static main method in " 606 + "class " + className + ": " + e ); 607 showUsage(); 608 WrapperManager.stop( 1 ); 609 return null; } 611 catch ( SecurityException e ) 612 { 613 System.out.println( 614 "WrapperStartStopApp: Unable to locate a public static main method in " 615 + "class " + className + ": " + e ); 616 showUsage(); 617 WrapperManager.stop( 1 ); 618 return null; } 620 621 int modifiers = mainMethod.getModifiers(); 623 if ( !( Modifier.isPublic( modifiers ) && Modifier.isStatic( modifiers ) ) ) 624 { 625 System.out.println( "WrapperStartStopApp: The main method in class " + className 626 + " must be declared public and static." ); 627 showUsage(); 628 WrapperManager.stop( 1 ); 629 return null; } 631 632 return mainMethod; 633 } 634 635 private String [] getArgs( String [] args, int argBase ) 636 { 637 int argCount; 639 try 640 { 641 argCount = Integer.parseInt( args[argBase] ); 642 } 643 catch ( NumberFormatException e ) 644 { 645 System.out.println( "WrapperStartStopApp: Illegal argument count: " + args[argBase] ); 646 showUsage(); 647 WrapperManager.stop( 1 ); 648 return null; } 650 if ( argCount < 0 ) 651 { 652 System.out.println( "WrapperStartStopApp: Illegal argument count: " + args[argBase] ); 653 showUsage(); 654 WrapperManager.stop( 1 ); 655 return null; } 657 658 if ( args.length < argBase + 1 + argCount ) 660 { 661 System.out.println( "WrapperStartStopApp: Not enough argments. Argument count of " 662 + argCount + " was specified." ); 663 showUsage(); 664 WrapperManager.stop( 1 ); 665 return null; } 667 668 String [] mainArgs = new String [argCount]; 670 System.arraycopy( args, argBase + 1, mainArgs, 0, argCount ); 671 672 return mainArgs; 673 } 674 675 678 protected void showUsage() 679 { 680 System.out.println(); 681 System.out.println( 682 "WrapperStartStopApp Usage:" ); 683 System.out.println( 684 " java org.tanukisoftware.wrapper.WrapperStartStopApp {start_class} {start_arg_count} " 685 + "[start_arguments] {stop_class} {stop_wait} {stop_arg_count} [stop_arguments]" ); 686 System.out.println(); 687 System.out.println( 688 "Where:" ); 689 System.out.println( 690 " start_class: The fully qualified class name to run to start the " ); 691 System.out.println( 692 " application." ); 693 System.out.println( 694 " start_arg_count: The number of arguments to be passed to the start class's " ); 695 System.out.println( 696 " main method." ); 697 System.out.println( 698 " start_arguments: The arguments that would normally be passed to the start " ); 699 System.out.println( 700 " class application." ); 701 System.out.println( 702 " stop_class: The fully qualified class name to run to stop the " ); 703 System.out.println( 704 " application." ); 705 System.out.println( 706 " stop_wait: When stopping, should the Wrapper wait for all threads to " ); 707 System.out.println( 708 " complete before exiting (true/false)." ); 709 System.out.println( 710 " stop_arg_count: The number of arguments to be passed to the stop class's " ); 711 System.out.println( 712 " main method." ); 713 System.out.println( 714 " stop_arguments: The arguments that would normally be passed to the stop " ); 715 System.out.println( 716 " class application." ); 717 } 718 719 722 729 public static void main( String args[] ) 730 { 731 new WrapperStartStopApp( args ); 732 } 733 } 734 735 | Popular Tags |