📄 server.java
字号:
/* Copyright (c) 2001-2005, The HSQL Development Group * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of the HSQL Development Group nor the names of its * contributors may be used to endorse or promote products derived from this * software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG, * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */package org.hsqldb;import java.io.File;import java.io.IOException;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket;import java.net.UnknownHostException;import java.util.Enumeration;import java.util.StringTokenizer;import org.hsqldb.lib.ArrayUtil;import org.hsqldb.lib.FileUtil;import org.hsqldb.lib.HashSet;import org.hsqldb.lib.Iterator;import org.hsqldb.lib.StopWatch;import org.hsqldb.lib.StringUtil;import org.hsqldb.lib.WrapperIterator;import org.hsqldb.lib.java.JavaSystem;import org.hsqldb.persist.HsqlDatabaseProperties;import org.hsqldb.persist.HsqlProperties;import org.hsqldb.resources.BundleHandler;// fredt@users 20020215 - patch 1.7.0// methods reorganised to use new HsqlProperties class// fredt@users 20020424 - patch 1.7.0 - shutdown without exit// see the comments in ServerConnection.java// unsaved@users 20021113 - patch 1.7.2 - SSL support// boucherb@users 20030510-14 - 1.7.2 - SSL support moved to factory interface// boucherb@users 20030510-14 - 1.7.2 - service control, JavaBean API// fredt@users 20030916 - 1.7.2 - review, simplification and multiple DB's// fredt@users 20040320 - 1.7.2 - review and correction// fredt@users 20050225 - 1.8.0 - minor corrections// fredt@users 20051231 - 1.8.1 - support for remote opening of databases/** * The HSQLDB HSQL protocol network database server. <p> * * A Server object acts as a network database server and is one way of using * the client-server mode of HSQLDB Database Engine. Instances of this * class handle native HSQL protocol connections exclusively, allowing database * queries to be performed efficienly across the network. Server's direct * descendent, WebServer, handles HTTP protocol connections exclusively, * allowing HSQL protocol to be tunneled over HTTP to avoid sandbox and * firewall issues, albeit less efficiently. <p> * * There are a number of ways to configure and start a Server instance. <p> * * When started from the command line or programatically via the main(String[]) * method, configuration occurs in three phases, with later phases overriding * properties set by previous phases: * * <ol> * <li>Upon construction, a Server object is assigned a set of default * properties. <p> * * <li>If it exists, properties are loaded from a file named * 'server.properties' in the present working directory. <p> * * <li>The command line arguments (alternatively, the String[] passed to * main()) are parsed and used to further configure the Server's * properties. <p> * * </ol> <p> * * From the command line, the options are as follows: <p> * <pre> * +----------------+-------------+----------+------------------------------+ * | OPTION | TYPE | DEFAULT | DESCRIPTION | * +----------------+-------------+----------+------------------------------| * | -? | -- | -- | prints this message | * | -address | name|number | any | server inet address | * | -port | number | 9001/544 | port at which server listens | * | -database.i | [type]spec | 0=test | path of database i | * | -dbname.i | alias | -- | url alias for database i | * | -silent | true|false | true | false => display all queries | * | -trace | true|false | false | display JDBC trace messages | * | -tls | true|false | false | TLS/SSL (secure) sockets | * | -no_system_exit| true|false | false | do not issue System.exit() | * | -remote_open | true|false | false | can open databases remotely | * +----------------+-------------+----------+------------------------------+ * </pre> * * The <em>database.i</em> and <em>dbname.i</em> options need further * explanation: * * <ul> * <li>Multiple databases can be served by each instance of the Server. * The value of <em>i</em> is currently limited to the range 0..9, * allowing up to 10 different databases. Any number is this range * can be used.<p> * * <li>The value assigned to <em>database.i</em> is interpreted using the * format <b>'[type]spec'</b>, where the optional <em>type</em> component * is one of <b>'file:'</b>, <b>'res:'</b> or <b>'mem:'</b> and the * <em>spec</em> component is interpreted in the context of the * <em>type</em> component. <p> * * If omitted, the <em>type</em> component is taken to be * <b>'file:'</b>. <p> * * A full description of how * <b>'[type]spec'</b> values are interpreted appears in the overview for * {@link org.hsqldb.jdbc.jdbcConnection jdbcConnection}. <p> * * <li>The value assigned to <em>dbname.i</em> is taken to be the key used to * look up the desired database instance and thus corresponds to the * <b><alias></b> component of the HSQLDB HSQL protocol database * connection url: * 'jdbc:hsqldb:hsql[s]://host[port][/<b><alias></b>]'. <p> * * <li>The value of <em>database.0</em> is special. If <em>dbname.0</em> * is not specified, then this defaults to an empty string and * a connection is made to <em>database.0</em> path when * the <b><alias></b> component of an HSQLDB HSQL protocol database * connection url is omitted. If a <em>database</em> key/value pair is * found in the properties when the main method is called, this * pair is supersedes the <em>database.0</em> setting<p> * * This behaviour allows the previous * database connection url format to work with essentially unchanged * semantics.<p> * </ul> * * From the 'server.properties' file, options can be set similarly, using a * slightly different format. <p> * * Here is an example 'server.properties' file: * * <pre> * server.port=9001 * server.database.0=test * server.dbname.0=... * ... * server.database.n=... * server.dbname.n=... * server.silent=true * </pre> * * Starting with 1.7.2, Server has been refactored to become a simple JavaBean * with non-blocking start() and stop() service methods. It is possible to * configure a Server instance through the JavaBean API as well, but this * part of the public interface is still under review and will not be finalized * or documented fully until the final 1.7.2 release. <p> * * <b>Note:</b> <p> * * The 'no_system_exit' property is of particular interest. <p> * * If a Server instance is to run embedded in, say, an application server, * such as when the jdbcDataSource or HsqlServerFactory classes are used, it * is typically necessary to avoid calling System.exit() when the Server * instance shuts down. <p> * * By default, 'no_system_exit' is set: <p> * * <ol> * <li><b>true</b> when a Server is started directly from the start() * method. <p> * * <li><b>false</b> when a Server is started from the main(String[]) * method. * </ol> <p> * * These values are natural to their context because the first case allows * the JVM to exit by default on Server shutdown when a Server instance is * started from a command line environment, whereas the second case prevents * a typically unwanted JVM exit on Server shutdown when a Server intance * is started as part of a larger framework. <p> * * Replaces original Hypersonic source of the same name. * * @author fredt@users * @version 1.8.0 * @since 1.7.2 * * @jmx.mbean * description="HSQLDB Server" * extends="org.hsqldb.mx.mbean.RegistrationSupportBaseMBean" * * @jboss.xmbean */public class Server implements HsqlSocketRequestHandler {// protected static final int serverBundleHandle = BundleHandler.getBundleHandle("org_hsqldb_Server_messages", null);// HsqlProperties serverProperties;// HashSet serverConnSet;// private String[] dbAlias; private String[] dbType; private String[] dbPath; private HsqlProperties[] dbProps; private int[] dbID;// Currently unused private int maxConnections;// protected String serverId; protected int serverProtocol; protected ThreadGroup serverConnectionThreadGroup; protected HsqlSocketFactory socketFactory; protected ServerSocket socket;// private Thread serverThread; private Throwable serverError; private volatile int serverState; private volatile boolean isSilent; private volatile boolean isRemoteOpen; private PrintWriter logWriter; private PrintWriter errWriter;// /** * A specialized Thread inner class in which the run() method of this * server executes. */ private class ServerThread extends Thread { /** * Constructs a new thread in which to execute the run method * of this server. * * @param name The thread name */ ServerThread(String name) { super(name); setName(name + '@' + Integer.toString(Server.this.hashCode(), 16)); } /** * Executes the run() method of this server */ public void run() { Server.this.run(); printWithThread("ServerThread.run() exited"); } } /** * Creates a new Server instance handling HSQL protocol connections. */ public Server() { this(ServerConstants.SC_PROTOCOL_HSQL); } /** * Creates a new Server instance handling the specified connection * protocol. <p> * * For example, the no-args WebServer constructor invokes this constructor * with ServerConstants.SC_PROTOCOL_HTTP, while the Server() no args * contructor invokes this constructor with * ServerConstants.SC_PROTOCOL_HSQL. <p> * * @param protocol the ServerConstants code indicating which * connection protocol to handle */ protected Server(int protocol) { init(protocol); } /** * Creates and starts a new Server. <p> * * Allows starting a Server via the command line interface. <p> * * @param args the command line arguments for the Server instance */ public static void main(String[] args) { String propsPath = FileUtil.canonicalOrAbsolutePath("server"); HsqlProperties fileProps = ServerConfiguration.getPropertiesFromFile(propsPath); HsqlProperties props = fileProps == null ? new HsqlProperties() : fileProps; HsqlProperties stringProps = HsqlProperties.argArrayToProps(args, ServerConstants.SC_KEY_PREFIX); if (stringProps != null) { if (stringProps.getErrorKeys().length != 0) { printHelp("server.help"); return; } props.addProperties(stringProps); } ServerConfiguration.translateDefaultDatabaseProperty(props); // Standard behaviour when started from the command line // is to halt the VM when the server shuts down. This may, of // course, be overridden by whatever, if any, security policy // is in place. ServerConfiguration.translateDefaultNoSystemExitProperty(props); // finished setting up properties; Server server = new Server(); server.setProperties(props); // now messages go to the channel specified in properties server.print("Startup sequence initiated from main() method"); if (fileProps != null) { server.print("Loaded properties from [" + propsPath + ".properties]"); } else { server.print("Could not load properties from file"); server.print("Using cli/default properties only"); } server.start(); } /** * Checks if this Server object is or is not running and throws if the * current state does not match the specified value. * * @param running if true, ensure the server is running, else ensure the * server is not running * @throws RuntimeException if the supplied value does not match the * current running status */ public void checkRunning(boolean running) throws RuntimeException { int state; boolean error; printWithThread("checkRunning(" + running + ") entered"); state = getState(); error = (running && state != ServerConstants.SERVER_STATE_ONLINE) || (!running && state != ServerConstants.SERVER_STATE_SHUTDOWN); if (error) { String msg = "server is " + (running ? "not " : "") + "running"; throw new RuntimeException(msg); } printWithThread("checkRunning(" + running + ") exited"); } /** * Closes all connections to this Server. * * @jmx.managed-operation * impact="ACTION" * description="Closes all open connections" */ public synchronized void signalCloseAllServerConnections() { Iterator it; printWithThread("signalCloseAllServerConnections() entered"); synchronized (serverConnSet) { // snapshot it = new WrapperIterator(serverConnSet.toArray(null)); } for (; it.hasNext(); ) { ServerConnection sc = (ServerConnection) it.next(); printWithThread("Closing " + sc); // also removes all but one connection from serverConnSet sc.signalClose(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -