Java tutorial
package de.th.wildau.dsc.sne.webserver; import java.io.File; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.apache.commons.cli.PosixParser; /** * This is the main web server class. License creative commons (cc) by-nc-sa. */ public class WebServer { protected static List<ScriptLanguage> supportedScriptLanguages; /** * The main method for the web server program. * * @param args */ public static void main(String[] startArguments) { new WebServer(startArguments); } /** * Web server / main constructor. * * @param startArguments */ public WebServer(String[] startArguments) { loadConfiguration(startArguments); Log.debug(Configuration.getInstance().toString()); Log.debug("Information about the OS: " + System.getProperty("os.name") + " - " + System.getProperty("os.version") + " - " + System.getProperty("os.arch")); if (Configuration.getConfig().getProxyHost() != null) { Log.debug("setup proxy configuration"); System.setProperty("http.proxyHost", Configuration.getConfig().getProxyHost()); System.setProperty("http.proxyPort", String.valueOf(Configuration.getConfig().getProxyPort())); } Log.debug("find supported scripting languages"); supportedScriptLanguages = Collections.unmodifiableList(ScriptExecutor.getSupportedScriptLanguages()); Log.debug("Supported Script Languages " + Arrays.toString(supportedScriptLanguages.toArray())); Log.info("instantiating web server"); try { ServerSocket server = new ServerSocket(Configuration.getConfig().getServerPort()); Log.debug("bound port " + Configuration.getConfig().getServerPort()); int corePoolSize = Runtime.getRuntime().availableProcessors(); int maxPoolSize = (2 * corePoolSize) + 1; Log.debug("core/max pool size: " + corePoolSize + "/" + maxPoolSize); LinkedBlockingQueue<Runnable> workerQueue = new LinkedBlockingQueue<Runnable>(); long keepAliveTime = 30; /* * keepAliveTime - If the pool currently has more than corePoolSize * threads, excess threads will be terminated if they have been idle * for more than the keepAliveTime. */ ThreadPoolExecutor threadPool = new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, TimeUnit.SECONDS, workerQueue); threadPool.prestartAllCoreThreads(); Socket socket = null; while (true) { try { socket = server.accept(); Log.info(socket.getInetAddress().getHostName() + " client request"); threadPool.execute(new HttpHandler(socket)); Log.debug("current threads: " + threadPool.getActiveCount()); } catch (final IOException ex) { Log.error("Connection failed!", ex); } catch (final RejectedExecutionException ex) { // XXX [sne] RejectedExecutionException // http://stackoverflow.com/questions/1519725/why-does-executors-newcachedthreadpool-throw-java-util-concurrent-rejectedexecut // http://www.javamex.com/tutorials/threads/thread_pools_queues.shtml // http://stackoverflow.com/questions/2001086/how-to-make-threadpoolexecutors-submit-method-block-if-it-is-saturated Log.error("RejectedExecutionException", ex); socket.close(); } catch (final Exception ex) { Log.fatal("Unknown error!", ex); } } } catch (final IOException ex) { Log.fatal("Can not start the server!", ex); System.err.println("Can not start the server! " + ex.getMessage()); } catch (final Exception ex) { Log.fatal("Unknown error!", ex); } } /** * Load the web server configuration. <b>DON'T USE LOG BEFORE THIS METHOD * CALL!</b> * * @param startArguments * array */ private void loadConfiguration(String[] startArguments) { Options options = new Options(); options.addOption("c", true, "specify server configuration file"); HelpFormatter helpFormatter = new HelpFormatter(); helpFormatter.printHelp("WebServer", options); CommandLineParser parser = new PosixParser(); CommandLine cmd; try { cmd = parser.parse(options, startArguments); } catch (final ParseException ex) { throw new IllegalStateException("Can not parse start arguments. " + ex.getMessage()); } try { if (cmd.hasOption("c")) { File configFile = new File(cmd.getOptionValue("c")); if (configFile.isFile() && configFile.canRead()) { Configuration.createInstance(configFile); } } else { // load default configuration Configuration.createInstance(); System.out.println("Load default config: " + Configuration.getConfig().toString()); } Log.createInstance(); Log.info("loaded server configuration"); } catch (final Exception ex) { System.err.println("Can not load server configuration file."); } } }