1 22 package org.jboss.system.server; 23 24 import java.io.File ; 25 import java.lang.reflect.Method ; 26 import java.net.URL ; 27 import java.util.ArrayList ; 28 import java.util.Date ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import java.util.Properties ; 32 import java.util.logging.LogManager ; 33 34 import javax.management.Attribute ; 35 import javax.management.ListenerNotFoundException ; 36 import javax.management.MBeanNotificationInfo ; 37 import javax.management.MBeanServer ; 38 import javax.management.MBeanServerFactory ; 39 import javax.management.Notification ; 40 import javax.management.NotificationEmitter ; 41 import javax.management.NotificationFilter ; 42 import javax.management.NotificationListener ; 43 import javax.management.ObjectInstance ; 44 import javax.management.ObjectName ; 45 46 import org.jboss.Version; 47 import org.jboss.deployment.IncompleteDeploymentException; 48 import org.jboss.deployment.MainDeployerMBean; 49 import org.jboss.logging.JBossJDKLogManager; 50 import org.jboss.logging.Logger; 51 import org.jboss.mx.loading.RepositoryClassLoader; 52 import org.jboss.mx.server.ServerConstants; 53 import org.jboss.mx.util.JBossNotificationBroadcasterSupport; 54 import org.jboss.mx.util.JMXExceptionDecoder; 55 import org.jboss.mx.util.MBeanProxyExt; 56 import org.jboss.mx.util.MBeanServerLocator; 57 import org.jboss.mx.util.ObjectNameFactory; 58 import org.jboss.net.protocol.URLStreamHandlerFactory; 59 import org.jboss.system.ServiceControllerMBean; 60 import org.jboss.system.server.jmx.LazyMBeanServer; 61 import org.jboss.util.StopWatch; 62 import org.jboss.util.file.FileSuffixFilter; 63 import org.jboss.util.file.Files; 64 65 79 public class ServerImpl 80 implements Server, ServerImplMBean, NotificationEmitter 81 { 82 private final static ObjectName DEFAULT_LOADER_NAME = 83 ObjectNameFactory.create(ServerConstants.DEFAULT_LOADER_NAME); 84 85 86 private Logger log; 87 88 89 private final Version version = Version.getInstance(); 90 91 92 private final Package jbossPackage = Package.getPackage("org.jboss"); 93 94 95 private ServerConfigImpl config; 96 97 98 private MBeanServer server; 99 100 101 private Date startDate; 102 103 104 private boolean started; 105 106 107 private ShutdownHook shutdownHook; 108 109 110 private LifeThread lifeThread; 111 112 113 private JBossNotificationBroadcasterSupport broadcasterSupport; 114 115 116 private ObjectName bootstrapUCLName; 117 118 private boolean isInShutdown; 119 120 123 public ServerImpl() 124 { 125 } 126 127 135 public void init(final Properties props) throws IllegalStateException , Exception 136 { 137 if (props == null) 138 throw new IllegalArgumentException ("props is null"); 139 if (config != null) 140 throw new IllegalStateException ("already initialized"); 141 142 ClassLoader oldCL = Thread.currentThread().getContextClassLoader(); 143 144 try 145 { 146 Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); 147 doInit(props); 148 } 149 finally 150 { 151 Thread.currentThread().setContextClassLoader(oldCL); 152 } 153 } 154 155 156 private void doInit(final Properties props) throws Exception 157 { 158 BaseServerConfig baseConfig = new BaseServerConfig(props); 160 this.config = new ServerConfigImpl(baseConfig); 161 162 166 config.getServerLogDir(); 167 log = Logger.getLogger(Server.class); 168 169 broadcasterSupport = new JBossNotificationBroadcasterSupport(); 171 172 boolean overrideTmpDir = Boolean.getBoolean("jboss.server.temp.dir.overrideJavaTmpDir"); 174 if( overrideTmpDir ) 175 { 176 File serverTmpDir = config.getServerTempDir(); 177 System.setProperty("java.io.tmpdir", serverTmpDir.getCanonicalPath()); 178 } 179 180 initURLHandlers(); 182 baseConfig.initURLs(); 183 184 log.info("Starting JBoss (MX MicroKernel)..."); 185 186 if (jbossPackage != null) 187 { 188 log.info("Release ID: " + 190 jbossPackage.getImplementationTitle() + " " + 191 jbossPackage.getImplementationVersion()); 192 } 193 else 194 { 195 log.warn("could not get package info to display release, either the " + 196 "jar manifest in jboss-system.jar has been mangled or you're " + 197 "running unit tests from ant outside of JBoss itself."); 198 } 199 200 log.debug("Using config: " + config); 201 202 log.debug("Server type: " + getClass()); 204 205 ClassLoader cl = getClass().getClassLoader(); 207 log.debug("Server loaded through: " + cl.getClass().getName()); 208 209 if (cl instanceof NoAnnotationURLClassLoader) 211 { 212 NoAnnotationURLClassLoader nacl = (NoAnnotationURLClassLoader)cl; 213 URL [] bootURLs = nacl.getAllURLs(); 214 log.debug("Boot URLs:"); 215 for (int i = 0; i < bootURLs.length; i++) 216 { 217 log.debug(" " + bootURLs[i]); 218 } 219 } 220 221 log.info("Home Dir: " + config.getHomeDir()); 223 log.info("Home URL: " + config.getHomeURL()); 224 log.debug("Library URL: " + config.getLibraryURL()); 225 log.info("Patch URL: " + config.getPatchURL()); 226 log.info("Server Name: " + config.getServerName()); 227 log.info("Server Home Dir: " + config.getServerHomeDir()); 228 log.info("Server Home URL: " + config.getServerHomeURL()); 229 log.debug("Server Data Dir: " + config.getServerDataDir()); 230 log.info("Server Temp Dir: " + config.getServerTempDir()); 231 log.debug("Server Config URL: " + config.getServerConfigURL()); 232 log.debug("Server Library URL: " + config.getServerLibraryURL()); 233 log.info("Root Deployment Filename: " + config.getRootDeploymentFilename()); 234 } 235 236 242 private void initURLHandlers() 243 { 244 if (config.getRequireJBossURLStreamHandlerFactory()) 245 { 246 internalInitURLHandlers(); 247 } else 249 { 250 try 251 { 252 internalInitURLHandlers(); 253 } 254 catch (SecurityException e) 255 { 256 log.warn("You do not have permissions to set URLStreamHandlerFactory", e); 257 } catch (Error e) 259 { 260 log.warn("URLStreamHandlerFactory already set", e); 261 } } } 264 265 270 private void internalInitURLHandlers() 271 { 272 try 273 { 274 URL.setURLStreamHandlerFactory(new URLStreamHandlerFactory()); 276 277 URLStreamHandlerFactory.preload(); 279 } 280 catch (Error error) 281 { log.warn("Caught Throwable Error, this probably means " + 284 "we've already set the URLStreamHAndlerFactory before"); 285 } 287 288 String handlerPkgs = System.getProperty("java.protocol.handler.pkgs"); 290 if (handlerPkgs != null) 291 { 292 handlerPkgs += "|org.jboss.net.protocol"; 293 } 294 else 295 { 296 handlerPkgs = "org.jboss.net.protocol"; 297 } 298 System.setProperty("java.protocol.handler.pkgs", handlerPkgs); 299 } 300 301 309 public ServerConfig getConfig() throws IllegalStateException 310 { 311 if (config == null) 312 throw new IllegalStateException ("not initialized"); 313 314 return config.getConfig(); 315 } 316 317 323 public boolean isStarted() 324 { 325 return started; 326 } 327 328 333 public boolean isInShutdown() 334 { 335 return isInShutdown; 336 } 337 338 344 public void start() throws IllegalStateException , Exception 345 { 346 getConfig(); 348 349 if (started) 351 throw new IllegalStateException ("already started"); 352 353 ClassLoader oldCL = Thread.currentThread().getContextClassLoader(); 354 355 try 356 { 357 Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); 358 359 try 361 { 362 doStart(); 363 } 364 catch (Exception e) 365 { 366 JMXExceptionDecoder.rethrow(e); 367 } 368 } 369 catch (Throwable t) 370 { 371 log.debug("Failed to start", t); 372 373 if (t instanceof Exception ) 374 throw (Exception )t; 375 if (t instanceof Error ) 376 throw (Error )t; 377 378 throw new org.jboss.util.UnexpectedThrowable(t); 379 } 380 finally 381 { 382 Thread.currentThread().setContextClassLoader(oldCL); 383 } 384 } 385 386 387 private void doStart() throws Exception 388 { 389 StopWatch watch = new StopWatch(true); 391 392 startDate = new Date (); 394 395 log.debug("Starting General Purpose Architecture (GPA)..."); 396 397 String builder = System.getProperty(ServerConstants.MBEAN_SERVER_BUILDER_CLASS_PROPERTY, 399 ServerConstants.DEFAULT_MBEAN_SERVER_BUILDER_CLASS); 400 System.setProperty(ServerConstants.MBEAN_SERVER_BUILDER_CLASS_PROPERTY, builder); 401 402 if (config.getPlatformMBeanServer() == true) 404 { 405 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 407 Class clazz = cl.loadClass("java.lang.management.ManagementFactory"); 408 Method method = clazz.getMethod("getPlatformMBeanServer", null); 409 server = (MBeanServer )method.invoke(null, null); 410 MBeanServerLocator.setJBoss(server); 412 415 server = LazyMBeanServer.resetToJBossServer(server); 416 } 417 else 418 { 419 server = MBeanServerFactory.createMBeanServer("jboss"); 421 } 422 log.debug("Created MBeanServer: " + server); 423 424 server.registerMBean(this, ServerImplMBean.OBJECT_NAME); 426 server.registerMBean(config, ServerConfigImplMBean.OBJECT_NAME); 427 428 RepositoryClassLoader ucl = initBootLibraries(); 430 bootstrapUCLName = ucl.getObjectName(); 431 server.registerMBean(ucl, bootstrapUCLName); 432 433 Thread.currentThread().setContextClassLoader(ucl); 436 437 createMBean("org.jboss.system.server.ServerInfo", 439 "jboss.system:type=ServerInfo"); 440 441 ObjectName controller = createMBean("org.jboss.system.ServiceController", 443 "jboss.system:service=ServiceController"); 444 445 ObjectName mainDeployer = startBootService(controller, 447 "org.jboss.deployment.MainDeployer", "jboss.system:service=MainDeployer"); 448 server.setAttribute(mainDeployer, 449 new Attribute ("ServiceController", controller)); 450 451 shutdownHook = new ShutdownHook(controller, mainDeployer); 453 shutdownHook.setDaemon(true); 454 455 try 456 { 457 Runtime.getRuntime().addShutdownHook(shutdownHook); 458 log.debug("Shutdown hook added"); 459 } 460 catch (Exception e) 461 { 462 log.warn("Failed to add shutdown hook; ignoring", e); 463 } 464 465 startBootService(controller, "org.jboss.deployment.JARDeployer", 467 "jboss.system:service=JARDeployer"); 468 469 startBootService(controller, "org.jboss.deployment.SARDeployer", 471 "jboss.system:service=ServiceDeployer"); 472 473 log.info("Core system initialized"); 474 475 477 MainDeployerMBean md = (MainDeployerMBean) 478 MBeanProxyExt.create(MainDeployerMBean.class, mainDeployer, server); 479 480 try 481 { 482 md.deploy(config.getServerConfigURL() + config.getRootDeploymentFilename()); 483 } 484 catch (IncompleteDeploymentException e) 485 { 486 log.error("Root deployment has missing dependencies; continuing", e); 487 } 488 489 lifeThread = new LifeThread(); 490 lifeThread.start(); 491 492 started = true; 493 494 Notification msg = new Notification (START_NOTIFICATION_TYPE, this, 1); 496 msg.setUserData(new Long (watch.getLapTime())); 497 sendNotification(msg); 498 499 watch.stop(); 500 501 if (jbossPackage != null) 502 { 503 log.info("JBoss (MX MicroKernel) [" + jbossPackage.getImplementationVersion() + 505 "] Started in " + watch); 506 } 507 else 508 { 509 log.warn("could not get package info to display release, either the " + 510 "jar manifest in jboss-boot.jar has been mangled or you're " + 511 "running unit tests from ant outside of JBoss itself."); 512 } 513 } 514 515 518 private ObjectName createMBean(final String classname, String name) 519 throws Exception 520 { 521 ObjectName mbeanName = null; 522 if( name != null ) 523 mbeanName = new ObjectName (name); 524 try 525 { 526 URL xmbeanDD = new URL ("resource:xmdesc/"+classname+"-xmbean.xml"); 528 Object resource = server.instantiate(classname); 529 Object [] args = {resource, xmbeanDD}; 531 String [] sig = {Object .class.getName(), URL .class.getName()}; 532 ObjectInstance instance = server.createMBean("org.jboss.mx.modelmbean.XMBean", 533 mbeanName, 534 bootstrapUCLName, 535 args, 536 sig); 537 mbeanName = instance.getObjectName(); 538 log.debug("Created system XMBean: "+mbeanName); 539 } 540 catch(Exception e) 541 { 542 log.debug("Failed to create xmbean for: "+classname); 543 mbeanName = server.createMBean(classname, mbeanName).getObjectName(); 544 log.debug("Created system MBean: " + mbeanName); 545 } 546 547 return mbeanName; 548 } 549 550 553 private ObjectName startBootService(final ObjectName controllerName, 554 final String classname, final String name) 555 throws Exception 556 { 557 ObjectName mbeanName = createMBean(classname, name); 558 559 561 Object [] args = { mbeanName }; 562 String [] sig = { ObjectName .class.getName() }; 563 564 server.invoke(controllerName, "create", args, sig); 565 server.invoke(controllerName, "start", args, sig); 566 567 return mbeanName; 568 } 569 570 573 private RepositoryClassLoader initBootLibraries() throws Exception 574 { 575 List list = new ArrayList (); 577 578 URL patchURL = config.getPatchURL(); 581 if (patchURL != null) 582 { 583 if (patchURL.getProtocol().equals("file")) 584 { 585 File dir = new File (patchURL.getFile()); 586 if (dir.exists()) 587 { 588 list.add(dir.toURL()); 590 591 File [] jars = dir.listFiles(new FileSuffixFilter(new String [] { ".jar", ".zip" }, true)); 593 594 for (int j = 0; jars != null && j < jars.length; j++) 595 { 596 list.add(jars[j].getCanonicalFile().toURL()); 597 } 598 } 599 } 600 else 601 { 602 list.add(patchURL); 603 } 604 } 605 606 list.add(config.getServerConfigURL()); 608 609 613 616 log.debug("Boot url list: " + list); 617 618 RepositoryClassLoader loader = null; 620 for (Iterator iter = list.iterator(); iter.hasNext();) 621 { 622 URL url = (URL )iter.next(); 623 log.debug("Creating loader for URL: " + url); 624 625 Object [] args = {url, Boolean.TRUE}; 627 String [] sig = {"java.net.URL", "boolean"}; 628 loader = (RepositoryClassLoader) server.invoke(DEFAULT_LOADER_NAME, "newClassLoader", args, sig); 629 } 630 return loader; 631 } 632 633 643 public void shutdown() throws IllegalStateException 644 { 645 if (log.isTraceEnabled()) 646 log.trace("Shutdown caller:", new Throwable ("Here")); 647 648 if (!started) 649 throw new IllegalStateException ("Server not started"); 650 651 isInShutdown = true; 652 boolean exitOnShutdown = config.getExitOnShutdown(); 653 boolean blockingShutdown = config.getBlockingShutdown(); 654 log.info("Shutting down the server, blockingShutdown: " + blockingShutdown); 655 656 if (exitOnShutdown) 657 { 658 exit(0); 659 } 660 else 661 { 662 lifeThread.interrupt(); 665 666 if (blockingShutdown) 667 { 668 shutdownHook.shutdown(); 669 } 670 else 671 { 672 new Thread () 675 { 676 public void run() 677 { 678 shutdownHook.shutdown(); 681 } 682 }.start(); 683 } 684 } 685 } 686 687 694 public void exit(final int exitcode) 695 { 696 new Thread () 699 { 700 public void run() 701 { 702 log.info("Server exit(" + exitcode + ") called"); 703 704 shutdownHook.setHaltExitCode(exitcode); 706 707 Runtime.getRuntime().exit(exitcode); 709 } 710 }.start(); 711 } 712 713 718 public void exit() 719 { 720 exit(1); 721 } 722 723 730 public void halt(final int exitcode) 731 { 732 new Thread () 735 { 736 public void run() 737 { 738 System.err.println("Server halt(" + exitcode + ") called, halting the JVM now!"); 739 Runtime.getRuntime().halt(exitcode); 740 } 741 }.start(); 742 } 743 744 750 public void halt() 751 { 752 halt(1); 753 } 754 755 756 760 761 private void logMemoryUsage(final Runtime rt) 762 { 763 log.info("Total/free memory: " + rt.totalMemory() + "/" + rt.freeMemory()); 764 } 765 766 771 public void runGarbageCollector() 772 { 773 Runtime rt = Runtime.getRuntime(); 774 775 logMemoryUsage(rt); 776 rt.gc(); 777 log.info("Hinted to the JVM to run garbage collection"); 778 logMemoryUsage(rt); 779 } 780 781 786 public void runFinalization() 787 { 788 Runtime.getRuntime().runFinalization(); 789 log.info("Hinted to the JVM to run any pending object finalizations"); 790 } 791 792 797 public void traceMethodCalls(final Boolean flag) 798 { 799 Runtime.getRuntime().traceMethodCalls(flag.booleanValue()); 800 } 801 802 807 public void traceInstructions(final Boolean flag) 808 { 809 Runtime.getRuntime().traceInstructions(flag.booleanValue()); 810 } 811 812 813 817 820 public Date getStartDate() 821 { 822 return startDate; 823 } 824 825 828 public String getVersion() 829 { 830 return version.toString(); 831 } 832 833 836 public String getVersionName() 837 { 838 return version.getName(); 839 } 840 841 844 public String getBuildNumber() 845 { 846 return version.getBuildNumber(); 847 } 848 849 852 public String getBuildJVM() 853 { 854 return version.getBuildJVM(); 855 } 856 857 860 public String getBuildOS() 861 { 862 return version.getBuildOS(); 863 } 864 865 868 public String getBuildID() 869 { 870 return version.getBuildID(); 871 } 872 873 876 public String getBuildDate() 877 { 878 return version.getBuildDate(); 879 } 880 881 885 public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) 886 { 887 broadcasterSupport.addNotificationListener(listener, filter, handback); 888 } 889 890 public void removeNotificationListener(NotificationListener listener) throws ListenerNotFoundException 891 { 892 broadcasterSupport.removeNotificationListener(listener); 893 } 894 895 public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback) 896 throws ListenerNotFoundException 897 { 898 broadcasterSupport.removeNotificationListener(listener, filter, handback); 899 } 900 901 public MBeanNotificationInfo [] getNotificationInfo() 902 { 903 return broadcasterSupport.getNotificationInfo(); 904 } 905 906 public void sendNotification(Notification notification) 907 { 908 broadcasterSupport.sendNotification(notification); 909 } 910 911 915 918 private class LifeThread 919 extends Thread 920 { 921 Object lock = new Object (); 922 LifeThread() 923 { 924 super("JBossLifeThread"); 925 } 926 public void run() 927 { 928 synchronized (lock) 929 { 930 try 931 { 932 lock.wait(); 933 } 934 catch (InterruptedException ignore) 935 { 936 } 937 } 938 log.debug("LifeThread.run() exits!"); 939 } 940 } 941 942 946 private class ShutdownHook 947 extends Thread 948 { 949 950 private ObjectName controller; 951 952 953 private ObjectName mainDeployer; 954 955 956 private boolean forceHalt = true; 957 958 959 private int haltExitCode; 960 961 962 private boolean shutdownCalled; 963 964 public ShutdownHook(final ObjectName controller, final ObjectName mainDeployer) 965 { 966 super("JBoss Shutdown Hook"); 967 968 this.controller = controller; 969 this.mainDeployer = mainDeployer; 970 971 String value = System.getProperty("jboss.shutdown.forceHalt", null); 972 if (value != null) 973 { 974 forceHalt = new Boolean (value).booleanValue(); 975 } 976 } 977 978 public void setHaltExitCode(int haltExitCode) 979 { 980 this.haltExitCode = haltExitCode; 981 } 982 983 public void run() 984 { 985 log.info("Runtime shutdown hook called, forceHalt: " + forceHalt); 986 987 shutdown(); 989 990 LogManager lm = LogManager.getLogManager(); 992 if (lm instanceof JBossJDKLogManager) 993 { 994 JBossJDKLogManager jbosslm = (JBossJDKLogManager)lm; 995 jbosslm.doReset(); 996 } 997 998 if (forceHalt) 1000 { 1001 System.out.println("Halting VM"); 1002 Runtime.getRuntime().halt(haltExitCode); 1003 } 1004 } 1005 1006 public void shutdown() 1007 { 1008 if (log.isTraceEnabled()) 1009 log.trace("Shutdown caller:", new Throwable ("Here")); 1010 1011 if (shutdownCalled) 1015 return; 1016 else 1017 shutdownCalled = true; 1018 1019 Notification msg = new Notification (STOP_NOTIFICATION_TYPE, this, 2); 1021 sendNotification(msg); 1022 1023 log.info("JBoss SHUTDOWN: Undeploying all packages"); 1025 shutdownDeployments(); 1026 1027 log.debug("Shutting down all services"); 1029 shutdownServices(); 1030 1031 removeMBeans(); 1033 1034 log.debug("Deleting server tmp/deploy directory"); 1036 File tmp = config.getServerTempDir(); 1037 File tmpDeploy = new File (tmp, "deploy"); 1038 Files.delete(tmpDeploy); 1039 1040 log.info("Shutdown complete"); 1042 System.out.println("Shutdown complete"); 1043 } 1044 1045 protected void shutdownDeployments() 1046 { 1047 try 1048 { 1049 server.invoke(mainDeployer, 1051 "shutdown", 1052 new Object [0], 1053 new String [0]); 1054 } 1055 catch (Exception e) 1056 { 1057 Throwable t = JMXExceptionDecoder.decode(e); 1058 log.error("Failed to shutdown deployer", t); 1059 } 1060 } 1061 1062 1066 protected void shutdownServices() 1067 { 1068 try 1069 { 1070 server.invoke(controller, 1072 "shutdown", 1073 new Object [0], 1074 new String [0]); 1075 } 1076 catch (Exception e) 1077 { 1078 Throwable t = JMXExceptionDecoder.decode(e); 1079 log.error("Failed to shutdown services", t); 1080 } 1081 } 1082 1083 1087 protected void removeMBeans() 1088 { 1089 try 1090 { 1091 server.unregisterMBean(ServiceControllerMBean.OBJECT_NAME); 1092 server.unregisterMBean(ServerConfigImplMBean.OBJECT_NAME); 1093 server.unregisterMBean(ServerImplMBean.OBJECT_NAME); 1094 } 1095 catch (Exception e) 1096 { 1097 Throwable t = JMXExceptionDecoder.decode(e); 1098 log.error("Failed to unregister mbeans", t); 1099 } 1100 try 1101 { 1102 MBeanServer registeredServer = server; 1103 if (config.getPlatformMBeanServer() == true) 1104 registeredServer = LazyMBeanServer.getRegisteredMBeanServer(server); 1105 MBeanServerFactory.releaseMBeanServer(registeredServer); 1106 } 1107 catch (Exception e) 1108 { 1109 Throwable t = JMXExceptionDecoder.decode(e); 1110 log.error("Failed to release mbean server", t); 1111 } 1112 } 1113 } 1114} 1115 | Popular Tags |