1 29 30 package com.caucho.server.resin; 31 32 import com.caucho.config.Config; 33 import com.caucho.config.ConfigELContext; 34 import com.caucho.config.ConfigException; 35 import com.caucho.config.SchemaBean; 36 import com.caucho.config.types.Bytes; 37 import com.caucho.config.types.InitProgram; 38 import com.caucho.config.types.Period; 39 import com.caucho.el.EL; 40 import com.caucho.el.MapVariableResolver; 41 import com.caucho.el.SystemPropertiesResolver; 42 import com.caucho.jsp.cfg.JspPropertyGroup; 43 import com.caucho.license.LicenseCheck; 44 import com.caucho.lifecycle.Lifecycle; 45 import com.caucho.lifecycle.LifecycleState; 46 import com.caucho.loader.Environment; 47 import com.caucho.loader.EnvironmentBean; 48 import com.caucho.loader.EnvironmentClassLoader; 49 import com.caucho.loader.EnvironmentLocal; 50 import com.caucho.loader.EnvironmentProperties; 51 import com.caucho.log.EnvironmentStream; 52 import com.caucho.log.RotateStream; 53 import com.caucho.management.j2ee.J2EEDomain; 54 import com.caucho.management.j2ee.J2EEManagedObject; 55 import com.caucho.management.j2ee.JVM; 56 import com.caucho.management.server.ClusterMXBean; 57 import com.caucho.naming.Jndi; 58 import com.caucho.server.cluster.Cluster; 59 import com.caucho.server.cluster.ClusterServer; 60 import com.caucho.server.cluster.Server; 61 import com.caucho.transaction.cfg.TransactionManagerConfig; 62 import com.caucho.util.Alarm; 63 import com.caucho.util.CompileException; 64 import com.caucho.util.L10N; 65 import com.caucho.util.QDate; 66 import com.caucho.util.RandomUtil; 67 import com.caucho.vfs.Path; 68 import com.caucho.vfs.QJniServerSocket; 69 import com.caucho.vfs.QServerSocket; 70 import com.caucho.vfs.Vfs; 71 import com.caucho.vfs.WriteStream; 72 73 import javax.annotation.PostConstruct; 74 import javax.el.ELResolver; 75 import javax.management.ObjectName ; 76 import java.io.FileInputStream ; 77 import java.io.InputStream ; 78 import java.io.InterruptedIOException ; 79 import java.net.BindException ; 80 import java.net.InetAddress ; 81 import java.net.Socket ; 82 import java.net.SocketException ; 83 import java.net.SocketTimeoutException ; 84 import java.security.Provider ; 85 import java.security.Security ; 86 import java.util.ArrayList ; 87 import java.util.Date ; 88 import java.util.HashMap ; 89 import java.util.logging.Level ; 90 import java.util.logging.Logger ; 91 92 96 public class Resin implements EnvironmentBean, SchemaBean 97 { 98 private static Logger _log; 99 private static L10N _L; 100 101 private static final String OBJECT_NAME= "resin:type=Resin"; 102 103 private static final EnvironmentLocal<Resin> _resinLocal = 104 new EnvironmentLocal<Resin>(); 105 106 private final EnvironmentLocal<String > _serverIdLocal = 107 new EnvironmentLocal<String >("caucho.server-id"); 108 109 private ObjectName _objectName; 110 111 private EnvironmentClassLoader _classLoader; 112 private boolean _isGlobal; 113 114 private String _serverId = ""; 115 116 private Path _resinHome; 117 private Path _rootDirectory; 118 119 private boolean _isGlobalSystemProperties; 120 private boolean _isResinProfessional; 121 122 private long _minFreeMemory = 2 * 1024L * 1024L; 123 private long _shutdownWaitMax = 60000L; 124 125 private SecurityManager _securityManager; 126 127 private HashMap <String ,Object > _variableMap = new HashMap <String ,Object >(); 128 129 private ArrayList <InitProgram> _clusterDefaults 130 = new ArrayList <InitProgram>(); 131 132 private ArrayList <Cluster> _clusters 133 = new ArrayList <Cluster>(); 134 135 private Lifecycle _lifecycle; 136 137 private Server _server; 138 139 private long _initialStartTime; 140 private long _startTime; 141 private J2EEDomain _j2eeDomainManagedObject; 142 private JVM _jvmManagedObject; 143 144 private String _configFile; 145 private String _configServer; 146 147 private Path _resinConf; 148 149 private ClassLoader _systemClassLoader; 150 private Thread _mainThread; 151 152 private ArrayList <BoundPort> _boundPortList 153 = new ArrayList <BoundPort>(); 154 155 private InputStream _waitIn; 156 157 private Socket _pingSocket; 158 159 162 public Resin() 163 { 164 this(Thread.currentThread().getContextClassLoader()); 165 } 166 167 170 public Resin(ClassLoader loader) 171 { 172 Environment.init(); 173 174 if (loader == null) 175 loader = ClassLoader.getSystemClassLoader(); 176 177 _isGlobal = (loader == ClassLoader.getSystemClassLoader()); 178 179 if (loader instanceof EnvironmentClassLoader) 180 _classLoader = (EnvironmentClassLoader) loader; 181 else 182 _classLoader = new EnvironmentClassLoader(); 183 184 _resinLocal.set(this, _classLoader); 185 186 _lifecycle = new Lifecycle(log(), "Resin[]"); 187 188 _startTime = Alarm.getCurrentTime(); 189 190 String resinHome = System.getProperty("resin.home"); 191 192 if (resinHome != null) 193 setResinHome(Vfs.lookup(resinHome)); 194 else 195 setResinHome(Vfs.getPwd()); 196 197 String serverRoot = System.getProperty("server.root"); 199 200 if (serverRoot != null) 201 setRootDirectory(Vfs.lookup(serverRoot)); 202 203 207 _variableMap.put("resin", new Var()); 208 _variableMap.put("server", new Var()); 209 _variableMap.put("java", new JavaVar()); 210 211 ELResolver varResolver = new SystemPropertiesResolver(); 212 ConfigELContext elContext = new ConfigELContext(varResolver); 213 elContext.push(new MapVariableResolver(_variableMap)); 214 215 EL.setEnvironment(elContext); 216 EL.setVariableMap(_variableMap, _classLoader); 217 218 _variableMap.put("fmt", new com.caucho.config.functions.FmtFunctions()); 219 220 try { 221 _variableMap.put("jndi", Jndi.class.getMethod("lookup", new Class [] { String .class })); 222 _variableMap.put("jndi:lookup", Jndi.class.getMethod("lookup", new Class [] { String .class })); 223 } catch (Exception e) { 224 throw new ConfigException(e); 225 } 226 227 ThreadPoolAdmin.create(); 228 229 new ResinAdmin(this); 230 } 231 232 235 public static Resin getLocal() 236 { 237 return _resinLocal.get(); 238 } 239 240 243 public ClassLoader getClassLoader() 244 { 245 return _classLoader; 246 } 247 248 public ObjectName getObjectName() 249 { 250 return _objectName; 251 } 252 253 256 public void setEnvironmentClassLoader(EnvironmentClassLoader loader) 257 { 258 _classLoader = loader; 259 } 260 261 264 public String getSchema() 265 { 266 return "com/caucho/server/resin/resin.rnc"; 267 } 268 269 272 public void setServerId(String serverId) 273 { 274 _variableMap.put("serverId", serverId); 275 276 _serverId = serverId; 277 _serverIdLocal.set(serverId); 278 } 279 280 283 public String getServerId() 284 { 285 return _serverId; 286 } 287 288 291 public void setConfigFile(String configFile) 292 { 293 _configFile = configFile; 294 } 295 296 299 public void setResinHome(Path home) 300 { 301 _resinHome = home; 302 303 _variableMap.put("resinHome", _resinHome); 304 _variableMap.put("resin-home", _resinHome); 305 } 306 307 310 public Path getResinHome() 311 { 312 return _resinHome; 313 } 314 315 318 public void setRootDirectory(Path root) 319 { 320 _rootDirectory = root; 321 322 _variableMap.put("serverRoot", root); 323 _variableMap.put("server-root", root); 324 } 325 326 329 public Path getRootDirectory() 330 { 331 return _rootDirectory; 332 } 333 334 337 public Path getResinConf() 338 { 339 return _resinConf; 340 } 341 342 345 void setResinProfessional(boolean isPro) 346 { 347 _isResinProfessional = isPro; 348 } 349 350 353 public boolean isProfessional() 354 { 355 return _isResinProfessional; 356 } 357 358 361 public ClusterMXBean []getClusters() 362 { 363 ClusterMXBean []clusters = new ClusterMXBean[_clusters.size()]; 364 365 for (int i = 0; i < _clusters.size(); i++) 366 clusters[i] = _clusters.get(i).getAdmin(); 367 368 return clusters; 369 } 370 371 public void addClusterDefault(InitProgram program) 372 { 373 _clusterDefaults.add(program); 374 } 375 376 public Cluster createCluster() 377 throws Throwable 378 { 379 Cluster cluster = new Cluster(this); 380 381 for (int i = 0; i < _clusterDefaults.size(); i++) 382 _clusterDefaults.get(i).configure(cluster); 383 384 return cluster; 385 } 386 387 public void addCluster(Cluster cluster) 388 { 389 _clusters.add(cluster); 390 } 391 392 public ArrayList <Cluster> getClusterList() 393 { 394 return _clusters; 395 } 396 397 401 public void setEnvironmentSystemProperties(boolean isEnable) 402 { 403 EnvironmentProperties.enableEnvironmentSystemProperties(isEnable); 404 } 405 406 409 public ServerCompatConfig createServer() 410 { 411 return new ServerCompatConfig(this); 412 437 } 438 439 442 public ThreadPoolConfig createThreadPool() 443 throws Exception 444 { 445 return new ThreadPoolConfig(); 446 } 447 448 451 public void setUserName(String userName) 452 { 453 } 454 455 458 public void setGroupName(String groupName) 459 { 460 } 461 462 465 public void setMinFreeMemory(Bytes minFreeMemory) 466 { 467 _minFreeMemory = minFreeMemory.getBytes(); 468 } 469 470 473 public long getMinFreeMemory() 474 { 475 return _minFreeMemory; 476 } 477 478 481 public void setShutdownWaitMax(Period shutdownWaitMax) 482 { 483 _shutdownWaitMax = shutdownWaitMax.getPeriod(); 484 } 485 486 489 public long getShutdownWaitMax() 490 { 491 return _shutdownWaitMax; 492 } 493 494 497 public void setGlobalSystemProperties(boolean isGlobal) 498 { 499 _isGlobalSystemProperties = isGlobal; 500 } 501 502 505 public void addTransactionManager(TransactionManagerConfig tm) 506 throws ConfigException 507 { 508 510 tm.start(); 511 } 512 513 public SecurityManagerConfig createSecurityManager() 514 { 515 return new SecurityManagerConfig(); 516 } 517 518 521 public void addSecurityProvider(Class providerClass) 522 throws Exception 523 { 524 if (! Provider .class.isAssignableFrom(providerClass)) 525 throw new ConfigException(L().l("security-provider {0} must implement java.security.Provider", 526 providerClass.getName())); 527 528 Security.addProvider((Provider ) providerClass.newInstance()); 529 } 530 531 534 public JspPropertyGroup createJsp() 535 { 536 return new JspPropertyGroup(); 537 } 538 539 542 public void addBoot(InitProgram program) 543 throws Exception 544 { 545 } 546 547 550 void setInitialStartTime(long now) 551 { 552 _initialStartTime = now; 553 } 554 555 558 public Date getInitialStartTime() 559 { 560 return new Date(_initialStartTime); 561 } 562 563 566 public Date getStartTime() 567 { 568 return new Date(_startTime); 569 } 570 571 574 public LifecycleState getLifecycleState() 575 { 576 return _lifecycle; 577 } 578 579 582 @PostConstruct 583 public void init() 584 { 585 _lifecycle.toInit(); 586 } 587 588 591 public Server getServer() 592 { 593 return _server; 594 } 595 596 599 public void start() 600 throws Throwable 601 { 602 if (! _lifecycle.toActive()) 603 return; 604 605 long start = Alarm.getCurrentTime(); 606 607 _j2eeDomainManagedObject = J2EEManagedObject.register(new J2EEDomain()); 608 _jvmManagedObject = J2EEManagedObject.register(new JVM()); 609 610 System.gc(); 612 613 615 ClusterServer clusterServer = findClusterServer(_serverId); 616 617 if (clusterServer == null) 618 throw new ConfigException(L().l("server-id '{0}' has no matching <server> definition.", 619 _serverId)); 620 621 622 _server = clusterServer.startServer(); 623 624 633 634 Environment.start(getClassLoader()); 635 636 642 643 log().info("Resin started in " + (Alarm.getCurrentTime() - _startTime) + "ms"); 644 } 645 646 public Cluster findCluster(String id) 647 { 648 for (int i = 0; i < _clusters.size(); i++) { 649 Cluster cluster = _clusters.get(i); 650 651 if (cluster.getId().equals(id)) 652 return cluster; 653 } 654 655 return null; 656 } 657 658 public ClusterServer findClusterServer(String id) 659 { 660 for (int i = 0; i < _clusters.size(); i++) { 661 Cluster cluster = _clusters.get(i); 662 663 ClusterServer server = cluster.findServer(id); 664 665 if (server != null) 666 return server; 667 } 668 669 return null; 670 } 671 672 675 public boolean isActive() 676 { 677 return _lifecycle.isActive(); 678 } 679 680 683 public boolean isClosing() 684 { 685 return _lifecycle.isDestroying(); 686 } 687 688 691 public boolean isClosed() 692 { 693 return _lifecycle.isDestroyed(); 694 } 695 696 699 public void destroy() 700 { 701 if (! _lifecycle.toDestroying()) 702 return; 703 704 try { 705 synchronized (this) { 707 notifyAll(); 708 } 709 710 Socket socket = _pingSocket; 711 712 if (socket != null) 713 socket.setSoTimeout(1000); 714 } catch (Throwable e) { 715 log().log(Level.WARNING, e.toString(), e); 716 } 717 718 try { 719 Server server = _server; 720 _server = null; 721 722 if (server != null) 723 server.destroy(); 724 } catch (Throwable e) { 725 log().log(Level.WARNING, e.toString(), e); 726 } 727 728 try { 729 if (_isGlobal) 730 Environment.closeGlobal(); 731 else 732 _classLoader.destroy(); 733 } finally { 734 _lifecycle.toDestroy(); 735 } 736 } 737 738 744 757 758 private void parseCommandLine(String []argv) 759 throws Exception 760 { 761 int len = argv.length; 762 int i = 0; 763 764 while (i < len) { 765 RandomUtil.addRandom(argv[i]); 766 767 if (i + 1 < len && 768 (argv[i].equals("-stdout") || 769 argv[i].equals("--stdout"))) { 770 Path path = Vfs.lookup(argv[i + 1]); 771 772 RotateStream stream = RotateStream.create(path); 773 stream.init(); 774 WriteStream out = stream.getStream(); 775 out.setDisableClose(true); 776 777 EnvironmentStream.setStdout(out); 778 779 i += 2; 780 } 781 else if (i + 1 < len && 782 (argv[i].equals("-stderr") || 783 argv[i].equals("--stderr"))) { 784 Path path = Vfs.lookup(argv[i + 1]); 785 786 RotateStream stream = RotateStream.create(path); 787 stream.init(); 788 WriteStream out = stream.getStream(); 789 out.setDisableClose(true); 790 791 EnvironmentStream.setStderr(out); 792 793 i += 2; 794 } 795 else if (i + 1 < len && 796 (argv[i].equals("-conf") || 797 argv[i].equals("--conf"))) { 798 _configFile = argv[i + 1]; 799 i += 2; 800 } 801 else if (i + 1 < len && 802 (argv[i].equals("-server") || 803 argv[i].equals("--server"))) { 804 _serverId = argv[i + 1]; 805 i += 2; 806 } 807 else if (argv[i].equals("-version") 808 || argv[i].equals("--version")) { 809 System.out.println(com.caucho.Version.FULL_VERSION); 810 System.exit(66); 811 } 812 else if (argv[i].equals("-resin-home") 813 || argv[i].equals("--resin-home")) { 814 _resinHome = Vfs.lookup(argv[i + 1]); 815 816 i += 2; 817 } 818 else if (argv[i].equals("-root-directory") 819 || argv[i].equals("--root-directory")) { 820 _rootDirectory = _resinHome.lookup(argv[i + 1]); 821 822 i += 2; 823 } 824 else if (argv[i].equals("-server-root") || argv[i].equals("--server-root")) { 826 _rootDirectory = _resinHome.lookup(argv[i + 1]); 827 828 i += 2; 829 } 830 else if (argv[i].equals("-config-server") || 831 argv[i].equals("--config-server")) { 832 _configServer = argv[i + 1]; 833 i += 2; 834 } 835 else if (argv[i].equals("-socketwait") || 836 argv[i].equals("--socketwait") || 837 argv[i].equals("-pingwait") || 838 argv[i].equals("--pingwait")) { 839 int socketport = Integer.parseInt(argv[i + 1]); 840 841 Socket socket = null; 842 for (int k = 0; k < 15 && socket == null; k++) { 843 try { 844 socket = new Socket("127.0.0.1", socketport); 845 } catch (Throwable e) { 846 System.out.println(new Date()); 847 e.printStackTrace(); 848 } 849 850 if (socket == null) 851 Thread.sleep(1000); 852 } 853 854 if (socket == null) { 855 System.err.println("Can't connect to parent process through socket " + socketport); 856 System.err.println("Resin needs to connect to its parent."); 857 System.exit(0); 858 } 859 860 if (argv[i].equals("-socketwait") || argv[i].equals("--socketwait")) 861 _waitIn = socket.getInputStream(); 862 else 863 _pingSocket = socket; 864 865 socket.setSoTimeout(60000); 866 867 i += 2; 868 } 869 else if ("-port".equals(argv[i]) || "--port".equals(argv[i])) { 870 int fd = Integer.parseInt(argv[i + 1]); 871 String addr = argv[i + 2]; 872 if ("null".equals(addr)) 873 addr = null; 874 int port = Integer.parseInt(argv[i + 3]); 875 876 _boundPortList.add(new BoundPort(QJniServerSocket.openJNI(fd, port), 877 addr, 878 port)); 879 880 i += 4; 881 } 882 else if ("start".equals(argv[i]) 883 || "restart".equals(argv[i])) { 884 i++; 885 } 886 else if (argv[i].equals("-verbose") 887 || argv[i].equals("--verbose")) { 888 i += 1; 889 } 890 else if (argv[i].equals("-fine") 891 || argv[i].equals("--fine")) { 892 i += 1; 893 } 894 else if (argv[i].equals("-finer") 895 || argv[i].equals("--finer")) { 896 i += 1; 897 } 898 else { 899 System.out.println(L().l("unknown argument '{0}'", argv[i])); 900 System.out.println(); 901 usage(); 902 System.exit(66); 903 } 904 } 905 } 906 907 private static void usage() 908 { 909 System.err.println(L().l("usage: Resin [-conf resin.conf] [-server id]")); 910 } 911 912 915 public void initMain() 916 throws Throwable 917 { 918 _mainThread = Thread.currentThread(); 919 _mainThread.setContextClassLoader(_systemClassLoader); 920 921 addRandom(); 922 923 System.out.println(com.caucho.Version.FULL_VERSION); 924 System.out.println(com.caucho.Version.COPYRIGHT); 925 System.out.println(); 926 927 boolean isResinProfessional = false; 928 929 try { 930 Class cl = Class.forName("com.caucho.license.LicenseCheckImpl", 931 false, 932 ClassLoader.getSystemClassLoader()); 933 934 LicenseCheck license = (LicenseCheck) cl.newInstance(); 935 936 try { 937 license.validate(0); 938 939 license.doLogging(1); 940 941 license.validate(1); 942 943 isResinProfessional = true; 944 System.setProperty("isResinProfessional", "true"); 945 946 Vfs.initJNI(); 947 948 } catch (Throwable e) { 950 String msg; 951 952 if (e instanceof ConfigException) 953 msg = e.getMessage() + "\n"; 954 else { 955 e.printStackTrace(); 956 957 msg = e.toString() + "\n"; 958 959 log().log(Level.WARNING, e.toString(), e); 960 } 961 962 log().log(Level.FINE, e.toString(), e); 963 964 msg += L().l("\n" + 965 "Using Resin Open Source under the GNU Public License (GPL).\n" + 966 "\n" + 967 " See http://www.caucho.com for information on Resin Professional.\n"); 968 969 log().warning(msg); 970 System.err.println(msg); 971 } 972 } catch (Throwable e) { 973 log().log(Level.FINER, e.toString(), e); 974 975 String msg = L().l(" Using Resin(R) Open Source under the GNU Public License (GPL).\n" + 976 "\n" + 977 " See http://www.caucho.com for information on Resin Professional,\n" + 978 " including caching, clustering, JNI acceleration, and OpenSSL integration.\n"); 979 980 log().warning(msg); 981 System.err.println(msg); 982 } 983 984 System.out.println("Starting Resin on " + QDate.formatLocal(Alarm.getCurrentTime())); 985 System.out.println(); 986 987 EnvironmentClassLoader.initializeEnvironment(); 988 989 991 993 if (_classLoader != null) 994 _mainThread.setContextClassLoader(_classLoader); 995 996 1011 1012 Path pwd = Vfs.getPwd(); 1013 1014 if (_rootDirectory == null) 1015 _rootDirectory = _resinHome; 1016 1017 Vfs.setPwd(_rootDirectory); 1018 1019 Path resinConf = null; 1020 1021 if (_configFile != null) { 1022 if (log().isLoggable(Level.FINER)) 1023 log().log(Level.FINER, "looking for conf in " + pwd.lookup(_configFile)); 1024 1025 resinConf = pwd.lookup(_configFile); 1026 } 1027 1028 if (_configFile == null) 1029 _configFile = "conf/resin.conf"; 1030 1031 if (resinConf == null || !resinConf.exists()) { 1032 if (log().isLoggable(Level.FINER)) 1033 log().log(Level.FINER, "looking for conf in " + _rootDirectory.lookup(_configFile)); 1034 1035 resinConf = _rootDirectory.lookup(_configFile); 1036 } 1037 1038 if (!resinConf.exists() && ! _resinHome.equals(_rootDirectory)) { 1039 if (log().isLoggable(Level.FINER)) 1040 log().log(Level.FINER, "looking for conf in " + _resinHome.lookup(_configFile)); 1041 1042 resinConf = _resinHome.lookup(_configFile); 1043 } 1044 1045 if (!resinConf.exists()) 1047 resinConf = _rootDirectory.lookup(_configFile); 1048 1049 _resinConf = resinConf; 1050 1051 1053 setResinProfessional(isResinProfessional); 1054 1055 _mainThread.setContextClassLoader(_systemClassLoader); 1056 1057 Config config = new Config(); 1058 1061 config.configure(this, resinConf, getSchema()); 1062 1063 ClusterServer clusterServer = findClusterServer(_serverId); 1064 for (int i = 0; i < _boundPortList.size(); i++) { 1065 BoundPort port = _boundPortList.get(i); 1066 1067 clusterServer.bind(port.getAddress(), 1068 port.getPort(), 1069 port.getServerSocket()); 1070 } 1071 1072 start(); 1073 } 1074 1075 private void addRandom() 1076 { 1077 RandomUtil.addRandom(System.currentTimeMillis()); 1078 RandomUtil.addRandom(Runtime.getRuntime().freeMemory()); 1079 1080 RandomUtil.addRandom(System.identityHashCode(_mainThread)); 1081 RandomUtil.addRandom(System.identityHashCode(_systemClassLoader)); 1082 RandomUtil.addRandom(com.caucho.Version.FULL_VERSION); 1083 1084 try { 1085 RandomUtil.addRandom(InetAddress.getLocalHost().toString()); 1086 } catch (Throwable e) { 1087 } 1088 1089 try { 1091 InputStream is = new FileInputStream ("/dev/urandom"); 1092 1093 for (int i = 0; i < 16; i++) 1094 RandomUtil.addRandom(is.read()); 1095 1096 is.close(); 1097 } catch (Throwable e) { 1098 } 1099 1100 RandomUtil.addRandom(System.currentTimeMillis()); 1101 } 1102 1103 1106 public void waitForExit() 1107 { 1108 int socketExceptionCount = 0; 1109 Integer memoryTest; 1110 Runtime runtime = Runtime.getRuntime(); 1111 1112 1116 while (! isClosing()) { 1117 try { 1118 Thread.sleep(10); 1119 1120 long minFreeMemory = getMinFreeMemory(); 1121 1122 if (minFreeMemory <= 0) { 1123 } 1125 else if (2 * minFreeMemory < getFreeMemory(runtime)) { 1126 } 1128 else { 1129 if (log().isLoggable(Level.FINER)) { 1130 log().finer(L().l("free memory {0} max:{1} total:{2} free:{3}", 1131 "" + getFreeMemory(runtime), 1132 "" + runtime.maxMemory(), 1133 "" + runtime.totalMemory(), 1134 "" + runtime.freeMemory())); 1135 } 1136 1137 log().info(L().l("Forcing GC due to low memory. {0} free bytes.", 1138 getFreeMemory(runtime))); 1139 1140 runtime.gc(); 1141 1142 Thread.sleep(1000); 1143 1144 runtime.gc(); 1145 1146 if (getFreeMemory(runtime) < minFreeMemory) { 1147 log().severe(L().l("Restarting due to low free memory. {0} free bytes", 1148 getFreeMemory(runtime))); 1149 destroy(); 1150 return; 1151 } 1152 } 1153 1154 memoryTest = new Integer (0); 1156 1157 long alarmTime = Alarm.getCurrentTime(); 1158 long systemTime = System.currentTimeMillis(); 1159 1160 long diff = alarmTime - systemTime; 1161 if (diff < 0) 1162 diff = -diff; 1163 1164 if (10 * 60000L < diff) { 1167 log().severe(L().l("Restarting due to frozen Resin timer manager thread (Alarm). This error generally indicates a JVM freeze, not an application deadlock.")); 1168 Runtime.getRuntime().halt(1); 1169 } 1170 1171 if (_waitIn != null) { 1172 int len; 1173 if ((len = _waitIn.read()) >= 0) { 1174 socketExceptionCount = 0; 1175 } 1176 1177 return; 1178 } 1179 else { 1180 synchronized (this) { 1181 wait(10000); 1182 } 1183 } 1184 } catch (SocketTimeoutException e) { 1185 socketExceptionCount = 0; 1186 } catch (InterruptedIOException e) { 1187 socketExceptionCount = 0; 1188 } catch (InterruptedException e) { 1189 socketExceptionCount = 0; 1190 } catch (SocketException e) { 1191 1195 if (socketExceptionCount++ == 0) { 1199 log().log(Level.FINE, e.toString(), e); 1200 } 1201 else if (socketExceptionCount > 100) 1202 return; 1203 } catch (OutOfMemoryError e) { 1204 try { 1205 System.err.println("Out of memory"); 1206 } finally { 1207 Runtime.getRuntime().halt(1); 1208 } 1209 } catch (Throwable e) { 1210 log().log(Level.FINE, e.toString(), e); 1211 1212 return; 1213 } 1214 } 1215 } 1216 1217 private static long getFreeMemory(Runtime runtime) 1218 { 1219 long maxMemory = runtime.maxMemory(); 1220 long totalMemory = runtime.totalMemory(); 1221 long freeMemory = runtime.freeMemory(); 1222 1223 if (maxMemory < totalMemory) 1225 return freeMemory; 1226 else 1227 return maxMemory - totalMemory + freeMemory; 1228 } 1229 1230 1233 public static void shutdown() 1234 { 1235 Resin resin = getLocal(); 1236 1237 if (resin != null) { 1238 resin.destroy(); 1239 } 1240 } 1241 1242 1250 public static void main(String []argv) 1251 { 1252 try { 1253 validateEnvironment(); 1254 1255 final Resin resin = new Resin(); 1256 1257 resin.parseCommandLine(argv); 1258 1259 resin.initMain(); 1260 1261 resin.waitForExit(); 1262 1263 System.err.println(L().l("closing server")); 1264 1265 new Thread () { 1266 public void run() 1267 { 1268 setName("resin-destroy"); 1269 1270 resin.destroy(); 1271 } 1272 }.start(); 1273 1274 Server server = resin.getServer(); 1275 1276 long stopTime = System.currentTimeMillis(); 1277 long endTime = stopTime + 15000L; 1278 1279 if (server != null) 1280 endTime = stopTime + server.getShutdownWaitMax() ; 1281 1282 while (System.currentTimeMillis() < endTime && ! resin.isClosed()) { 1283 try { 1284 Thread.interrupted(); 1285 Thread.sleep(100); 1286 } catch (Throwable e) { 1287 } 1288 } 1289 1290 if (! resin.isClosed()) 1291 Runtime.getRuntime().halt(1); 1292 1293 System.exit(0); 1294 } catch (BindException e) { 1295 System.out.println(e); 1296 1297 log().log(Level.FINE, e.toString(), e); 1298 1299 System.exit(67); 1300 } catch (Throwable e) { 1301 boolean isCompile = false; 1302 Throwable cause; 1303 1304 for (cause = e; cause != null; cause = cause.getCause()) { 1305 if (cause instanceof CompileException) { 1306 System.err.println(cause.getMessage()); 1307 isCompile = true; 1308 break; 1309 } 1310 } 1311 1312 if (! isCompile) 1313 e.printStackTrace(System.err); 1314 else 1315 log().log(Level.CONFIG, e.toString(), e); 1316 } finally { 1317 System.exit(1); 1318 } 1319 } 1320 1321 1324 private static void validateEnvironment() 1325 throws ConfigException 1326 { 1327 String loggingManager = System.getProperty("java.util.logging.manager"); 1328 1329 if (loggingManager == null || 1330 ! loggingManager.equals("com.caucho.log.LogManagerImpl")) { 1331 throw new ConfigException(L().l("The following system property must be set:\n -Djava.util.logging.manager=com.caucho.log.LogManagerImpl\nThe JDK 1.4 Logging manager must be set to Resin's log manager.")); 1332 } 1333 1334 validatePackage("javax.servlet.Servlet", new String [] {"2.5", "1.5"}); 1335 validatePackage("javax.servlet.jsp.jstl.core.Config", new String [] {"1.1"}); 1336 validatePackage("javax.management.MBeanServer", new String [] { "1.2", "1.5" }); 1337 validatePackage("javax.resource.spi.ResourceAdapter", new String [] {"1.5", "1.4"}); 1338 } 1339 1340 1343 private static void validatePackage(String className, String []versions) 1344 throws ConfigException 1345 { 1346 Class cl = null; 1347 1348 try { 1349 cl = Class.forName(className); 1350 } catch (Throwable e) { 1351 throw new ConfigException(L().l("class {0} is not loadable on startup. Resin requires {0} to be in the classpath on startup.", 1352 className)); 1353 1354 } 1355 1356 Package pkg = cl.getPackage(); 1357 1358 if (pkg == null) { 1359 log().warning(L().l("package for class {0} is missing. Resin requires class {0} in the classpath on startup.", 1360 className)); 1361 1362 return; 1363 } 1364 else if (pkg.getSpecificationVersion() == null) { 1365 log().warning(L().l("{0} has no specification version. Resin {1} requires version {2}.", 1366 pkg, com.caucho.Version.VERSION, 1367 versions[0])); 1368 1369 return; 1370 } 1371 1372 for (int i = 0; i < versions.length; i++) { 1373 if (versions[i].compareTo(pkg.getSpecificationVersion()) <= 0) 1374 return; 1375 } 1376 1377 log().warning(L().l("Specification version {0} of {1} is not compatible with Resin {2}. Resin {2} requires version {3}.", 1378 pkg.getSpecificationVersion(), 1379 pkg, com.caucho.Version.VERSION, 1380 versions[0])); 1381 } 1382 1383 private static L10N L() 1384 { 1385 if (_L == null) 1386 _L = new L10N(Resin.class); 1387 1388 return _L; 1389 } 1390 1391 private static Logger log() 1392 { 1393 if (_log == null) 1394 _log = Logger.getLogger(Resin.class.getName()); 1395 1396 return _log; 1397 } 1398 1399 static class BoundPort { 1400 private QServerSocket _ss; 1401 private String _address; 1402 private int _port; 1403 1404 BoundPort(QServerSocket ss, String address, int port) 1405 { 1406 if (ss == null) 1407 throw new NullPointerException (); 1408 1409 _ss = ss; 1410 _address = address; 1411 _port = port; 1412 } 1413 1414 public QServerSocket getServerSocket() 1415 { 1416 return _ss; 1417 } 1418 1419 public int getPort() 1420 { 1421 return _port; 1422 } 1423 1424 public String getAddress() 1425 { 1426 return _address; 1427 } 1428 } 1429 1430 1433 public class Var { 1434 1437 public String getId() 1438 { 1439 return _serverId; 1440 } 1441 1442 1447 public String getAddress() 1448 { 1449 try { 1450 if (Alarm.isTest()) 1451 return "127.0.0.1"; 1452 else 1453 return InetAddress.getLocalHost().getHostAddress(); 1454 } catch (Exception e) { 1455 log().log(Level.FINE, e.toString(), e); 1456 1457 return "localhost"; 1458 } 1459 } 1460 1461 1464 public Path getConf() 1465 { 1466 return getResinConf(); 1467 } 1468 1469 1472 public Path getHome() 1473 { 1474 return Resin.this.getResinHome(); 1475 } 1476 1477 1482 public Path getRoot() 1483 { 1484 return Resin.this.getRootDirectory(); 1485 } 1486 1487 1492 public String getVersion() 1493 { 1494 if (Alarm.isTest()) 1495 return "3.1.test"; 1496 else 1497 return com.caucho.Version.VERSION; 1498 } 1499 1500 1505 public String getVersionDate() 1506 { 1507 if (Alarm.isTest()) 1508 return "19980508T0251"; 1509 else 1510 return com.caucho.Version.VERSION_DATE; 1511 } 1512 1513 1518 public String getHostName() 1519 { 1520 try { 1521 if (Alarm.isTest()) 1522 return "localhost"; 1523 else 1524 return InetAddress.getLocalHost().getHostName(); 1525 } catch (Exception e) { 1526 log().log(Level.FINE, e.toString(), e); 1527 1528 return "localhost"; 1529 } 1530 } 1531 1532 1537 public Path getRootDir() 1538 { 1539 return getRoot(); 1540 } 1541 1542 1547 public Path getRootDirectory() 1548 { 1549 return getRoot(); 1550 } 1551 1552 1555 public boolean isProfessional() 1556 { 1557 return _isResinProfessional; 1558 } 1559 1560 1563 public String getServerId() 1564 { 1565 return _serverId; 1566 } 1567 } 1568 1569 1572 public class JavaVar { 1573 1576 public boolean isJava5() 1577 { 1578 return true; 1579 } 1580 1583 public String getVersion() 1584 { 1585 return System.getProperty("java.version"); 1586 } 1587 } 1588 1589 class SecurityManagerConfig { 1590 private boolean _isEnable; 1591 1592 SecurityManagerConfig() 1593 { 1594 if (_securityManager == null) 1595 _securityManager = new SecurityManager (); 1596 } 1597 1598 public void setEnable(boolean enable) 1599 { 1600 _isEnable = enable; 1601 } 1602 1603 public void setValue(boolean enable) 1604 { 1605 setEnable(enable); 1606 } 1607 1608 public void setPolicyFile(Path path) 1609 throws ConfigException 1610 { 1611 if (! path.canRead()) 1612 throw new ConfigException(L().l("policy-file '{0}' must be readable.", 1613 path)); 1614 1615 } 1616 1617 public void init() 1618 { 1619 if (_isEnable) 1620 System.setSecurityManager(_securityManager); 1621 } 1622 } 1623} 1624 | Popular Tags |