From 57b527570531ccd8923342a6436c9094597a991c Mon Sep 17 00:00:00 2001 From: hns Date: Wed, 5 Nov 2008 12:49:06 +0000 Subject: [PATCH] Factor out jetty server into JettyServer wrapper class and duplicate InetAddrPort as InetEndpoint to avoid direct dependency of helma.main.Server on Jetty 4, which may be problematic when running Helma apps through helma.servlet.StandaloneServletClient within a servlet container. --- src/helma/main/ApplicationManager.java | 18 ++-- src/helma/main/JettyServer.java | 116 ++++++++++++++++++++++++ src/helma/main/Server.java | 121 +++++++++++-------------- src/helma/main/ServerConfig.java | 25 +++-- 4 files changed, 189 insertions(+), 91 deletions(-) create mode 100644 src/helma/main/JettyServer.java diff --git a/src/helma/main/ApplicationManager.java b/src/helma/main/ApplicationManager.java index a1716867..8b822d1f 100644 --- a/src/helma/main/ApplicationManager.java +++ b/src/helma/main/ApplicationManager.java @@ -42,7 +42,7 @@ public class ApplicationManager implements XmlRpcHandler { private ResourceProperties props; private Server server; private long lastModified; - private HttpServer httpServer = null; + private JettyServer jetty = null; /** * Creates a new ApplicationManager object. @@ -60,7 +60,7 @@ public class ApplicationManager implements XmlRpcHandler { applications = new Hashtable(); xmlrpcHandlers = new Hashtable(); lastModified = 0; - httpServer = server.http; + jetty = server.jetty; } /** @@ -88,7 +88,7 @@ public class ApplicationManager implements XmlRpcHandler { // check if application has been removed and should be stopped if (!props.containsKey(appDesc.appName)) { appDesc.stop(); - } else if (server.http != null) { + } else if (server.jetty != null) { // If application continues to run, remount // as the mounting options may have changed. AppDescriptor ndesc = new AppDescriptor(appDesc.appName); @@ -471,9 +471,9 @@ public class ApplicationManager implements XmlRpcHandler { } // bind to Jetty HTTP server - if (httpServer != null) { + if (jetty != null) { - HttpContext context = httpServer.addContext(pathPattern); + HttpContext context = jetty.addContext(pathPattern); if (encode) { // FIXME: ContentEncodingHandler is broken/removed in Jetty 4.2 @@ -534,7 +534,7 @@ public class ApplicationManager implements XmlRpcHandler { getLogger().info("Mounting static at " + staticMountpoint); - context = httpServer.addContext(staticMountpoint); + context = jetty.addContext(staticMountpoint); context.setWelcomeFiles(staticHome); context.setResourceBase(staticContent.getPath()); @@ -566,8 +566,8 @@ public class ApplicationManager implements XmlRpcHandler { } // unbind from Jetty HTTP server - if (httpServer != null) { - HttpContext context = httpServer.getContext(null, pathPattern); + if (jetty != null) { + HttpContext context = jetty.getContext(pathPattern); if (context != null) { context.stop(); @@ -575,7 +575,7 @@ public class ApplicationManager implements XmlRpcHandler { } if (staticDir != null) { - context = httpServer.getContext(null, staticMountpoint); + context = jetty.getContext(staticMountpoint); if (context != null) { context.stop(); diff --git a/src/helma/main/JettyServer.java b/src/helma/main/JettyServer.java new file mode 100644 index 00000000..afc14038 --- /dev/null +++ b/src/helma/main/JettyServer.java @@ -0,0 +1,116 @@ +/* + * Helma License Notice + * + * The contents of this file are subject to the Helma License + * Version 2.0 (the "License"). You may not use this file except in + * compliance with the License. A copy of the License is available at + * http://adele.helma.org/download/helma/license.txt + * + * Copyright 1998-2003 Helma Software. All Rights Reserved. + * + * $RCSfile$ + * $Author$ + * $Revision$ + * $Date$ + */ + +package helma.main; + +import org.mortbay.http.HttpServer; +import org.mortbay.http.HttpContext; +import org.mortbay.http.ajp.AJP13Listener; +import org.mortbay.util.InetAddrPort; + +import java.util.StringTokenizer; +import java.net.URL; +import java.net.MalformedURLException; +import java.io.IOException; + +public class JettyServer { + + // the embedded web server + protected HttpServer http; + + // the AJP13 Listener, used for connecting from external webserver to servlet via JK + protected AJP13Listener ajp13; + + public static JettyServer init(Server server) + throws MalformedURLException, IOException { + if (server.configFile != null && server.configFile.exists()) { + return new JettyServer(server.configFile.toURI().toURL()); + } else if (server.websrvPort != null || server.ajp13Port != null) { + return new JettyServer(server.websrvPort, server.ajp13Port, server); + } + return null; + } + + private JettyServer(URL url) throws IOException { + http = new org.mortbay.jetty.Server(url); + } + + private JettyServer(InetEndpoint webPort, InetEndpoint ajpPort, Server server) + throws IOException { + http = new HttpServer(); + + // start embedded web server if port is specified + if (webPort != null) { + http.addListener(new InetAddrPort(webPort.getInetAddress(), webPort.getPort())); + } + + // activate the ajp13-listener + if (ajpPort != null) { + // create AJP13Listener + ajp13 = new AJP13Listener(new InetAddrPort(ajpPort.getInetAddress(), ajpPort.getPort())); + ajp13.setHttpServer(http); + + String jkallow = server.sysProps.getProperty("allowAJP13"); + + // by default the AJP13-connection just accepts requests from 127.0.0.1 + if (jkallow == null) { + jkallow = "127.0.0.1"; + } + + StringTokenizer st = new StringTokenizer(jkallow, " ,;"); + String[] jkallowarr = new String[st.countTokens()]; + int cnt = 0; + + while (st.hasMoreTokens()) { + jkallowarr[cnt] = st.nextToken(); + cnt++; + } + + ajp13.setRemoteServers(jkallowarr); + server.getLogger().info("Starting AJP13-Listener on port " + (ajpPort)); + } + } + + public HttpServer getHttpServer() { + return http; + } + + public HttpContext getContext(String contextPath) { + return http.getContext(contextPath); + } + + public HttpContext addContext(String contextPath) { + return http.addContext(contextPath); + } + + public void start() throws Exception { + http.start(); + if (ajp13 != null) { + ajp13.start(); + } + } + + public void stop() throws InterruptedException { + http.stop(); + if (ajp13 != null) { + ajp13.stop(); + } + } + + public void destroy() { + http.destroy(); + } +} diff --git a/src/helma/main/Server.java b/src/helma/main/Server.java index 9deac298..deecfc02 100644 --- a/src/helma/main/Server.java +++ b/src/helma/main/Server.java @@ -24,9 +24,6 @@ import helma.util.*; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.xmlrpc.*; -import org.mortbay.http.*; -import org.mortbay.http.ajp.*; -import org.mortbay.util.InetAddrPort; import java.io.*; import java.rmi.registry.*; @@ -72,10 +69,10 @@ public class Server implements Runnable { private Thread mainThread; // server ports - InetAddrPort rmiPort = null; - InetAddrPort xmlrpcPort = null; - InetAddrPort websrvPort = null; - InetAddrPort ajp13Port = null; + InetEndpoint rmiPort = null; + InetEndpoint xmlrpcPort = null; + InetEndpoint websrvPort = null; + InetEndpoint ajp13Port = null; // Jetty configuration file File configFile = null; @@ -85,10 +82,7 @@ public class Server implements Runnable { // the embedded web server // protected Serve websrv; - protected HttpServer http; - - // the AJP13 Listener, used for connecting from external webserver to servlet via JK - protected AJP13Listener ajp13; + protected JettyServer jetty; // the XML-RPC server protected WebServer xmlrpc; @@ -195,7 +189,7 @@ public class Server implements Runnable { // check if there's a property setting for those ports not specified via command line if (!config.hasWebsrvPort() && sysProps.getProperty("webPort") != null) { try { - config.setWebsrvPort(new InetAddrPort(sysProps.getProperty("webPort"))); + config.setWebsrvPort(new InetEndpoint(sysProps.getProperty("webPort"))); } catch (Exception portx) { throw new Exception("Error parsing web server port property from server.properties: " + portx); } @@ -203,7 +197,7 @@ public class Server implements Runnable { if (!config.hasAjp13Port() && sysProps.getProperty("ajp13Port") != null) { try { - config.setAjp13Port(new InetAddrPort(sysProps.getProperty("ajp13Port"))); + config.setAjp13Port(new InetEndpoint(sysProps.getProperty("ajp13Port"))); } catch (Exception portx) { throw new Exception("Error parsing AJP1.3 server port property from server.properties: " + portx); } @@ -211,7 +205,7 @@ public class Server implements Runnable { if (!config.hasRmiPort() && sysProps.getProperty("rmiPort") != null) { try { - config.setRmiPort(new InetAddrPort(sysProps.getProperty("rmiPort"))); + config.setRmiPort(new InetEndpoint(sysProps.getProperty("rmiPort"))); } catch (Exception portx) { throw new Exception("Error parsing RMI server port property from server.properties: " + portx); } @@ -219,7 +213,7 @@ public class Server implements Runnable { if (!config.hasXmlrpcPort() && sysProps.getProperty("xmlrpcPort") != null) { try { - config.setXmlrpcPort(new InetAddrPort(sysProps.getProperty("xmlrpcPort"))); + config.setXmlrpcPort(new InetEndpoint(sysProps.getProperty("xmlrpcPort"))); } catch (Exception portx) { throw new Exception("Error parsing XML-RPC server port property from server.properties: " + portx); } @@ -242,25 +236,25 @@ public class Server implements Runnable { config.setPropFile(new File(args[++i])); } else if (args[i].equals("-p") && ((i + 1) < args.length)) { try { - config.setRmiPort(new InetAddrPort(args[++i])); + config.setRmiPort(new InetEndpoint(args[++i])); } catch (Exception portx) { throw new Exception("Error parsing RMI server port property: " + portx); } } else if (args[i].equals("-x") && ((i + 1) < args.length)) { try { - config.setXmlrpcPort(new InetAddrPort(args[++i])); + config.setXmlrpcPort(new InetEndpoint(args[++i])); } catch (Exception portx) { throw new Exception("Error parsing XML-RPC server port property: " + portx); } } else if (args[i].equals("-w") && ((i + 1) < args.length)) { try { - config.setWebsrvPort(new InetAddrPort(args[++i])); + config.setWebsrvPort(new InetEndpoint(args[++i])); } catch (Exception portx) { throw new Exception("Error parsing web server port property: " + portx); } } else if (args[i].equals("-jk") && ((i + 1) < args.length)) { try { - config.setAjp13Port(new InetAddrPort(args[++i])); + config.setAjp13Port(new InetEndpoint(args[++i])); } catch (Exception portx) { throw new Exception("Error parsing AJP1.3 server port property: " + portx); } @@ -382,7 +376,7 @@ public class Server implements Runnable { /** * Check whether a server port is available by trying to open a server socket */ - private static void checkPort(InetAddrPort addrPort) throws Exception { + private static void checkPort(InetEndpoint addrPort) throws Exception { InetAddress addr = addrPort.getInetAddress(); int port = addrPort.getPort(); if (addr == null) { @@ -524,10 +518,10 @@ public class Server implements Runnable { appManager.stopAll(); - if (http != null) { + if (jetty != null) { try { - http.stop(); - http.destroy(); + jetty.stop(); + jetty.destroy(); } catch (InterruptedException irx) { // http.stop() interrupted by another thread. ignore. } @@ -567,42 +561,7 @@ public class Server implements Runnable { */ public void run() { try { - if (configFile != null && configFile.exists()) { - http = new org.mortbay.jetty.Server(configFile.toURI().toURL()); - } else if ((websrvPort != null) || (ajp13Port != null)) { - http = new HttpServer(); - - // start embedded web server if port is specified - if (websrvPort != null) { - http.addListener(websrvPort); - } - - // activate the ajp13-listener - if (ajp13Port != null) { - // create AJP13Listener - ajp13 = new AJP13Listener(ajp13Port); - ajp13.setHttpServer(http); - - String jkallow = sysProps.getProperty("allowAJP13"); - - // by default the AJP13-connection just accepts requests from 127.0.0.1 - if (jkallow == null) { - jkallow = "127.0.0.1"; - } - - StringTokenizer st = new StringTokenizer(jkallow, " ,;"); - String[] jkallowarr = new String[st.countTokens()]; - int cnt = 0; - - while (st.hasMoreTokens()) { - jkallowarr[cnt] = st.nextToken(); - cnt++; - } - - ajp13.setRemoteServers(jkallowarr); - logger.info("Starting AJP13-Listener on port " + (ajp13Port)); - } - } + jetty = JettyServer.init(this); if (xmlrpcPort != null) { String xmlparser = sysProps.getProperty("xmlparser"); @@ -689,22 +648,14 @@ public class Server implements Runnable { } // start embedded web server - if (http != null) { + if (jetty != null) { try { - http.start(); + jetty.start(); } catch (Exception m) { throw new RuntimeException("Error starting embedded web server", m); } } - if (ajp13 != null) { - try { - ajp13.start(); - } catch (Exception m) { - throw new RuntimeException("Error starting AJP13 listener: " + m); - } - } - // start applications appManager.startAll(); @@ -894,4 +845,36 @@ public class Server implements Runnable { } } +class InetEndpoint { + + InetAddress addr; + int port; + + public InetEndpoint(String inetAddrPort) + throws java.net.UnknownHostException { + int c = inetAddrPort.indexOf(':'); + if (c >= 0) { + String addr = inetAddrPort.substring(0, c); + if (addr.indexOf('/') > 0) + addr = addr.substring(addr.indexOf('/') + 1); + inetAddrPort = inetAddrPort.substring(c + 1); + + if (addr.length() > 0 && !"0.0.0.0".equals(addr)) { + this.addr = InetAddress.getByName(addr); + } + } + + this.port = Integer.parseInt(inetAddrPort); + } + + public InetAddress getInetAddress() { + return addr; + } + + public int getPort() { + return port; + } + +} + diff --git a/src/helma/main/ServerConfig.java b/src/helma/main/ServerConfig.java index eab1d2d1..b762d789 100644 --- a/src/helma/main/ServerConfig.java +++ b/src/helma/main/ServerConfig.java @@ -16,7 +16,6 @@ package helma.main; -import org.mortbay.util.InetAddrPort; import java.io.File; /** @@ -25,10 +24,10 @@ import java.io.File; public class ServerConfig { - private InetAddrPort rmiPort = null; - private InetAddrPort xmlrpcPort = null; - private InetAddrPort websrvPort = null; - private InetAddrPort ajp13Port = null; + private InetEndpoint rmiPort = null; + private InetEndpoint xmlrpcPort = null; + private InetEndpoint websrvPort = null; + private InetEndpoint ajp13Port = null; private File propFile = null; private File homeDir = null; private File configFile = null; @@ -57,35 +56,35 @@ public class ServerConfig { return (ajp13Port != null); } - public InetAddrPort getRmiPort() { + public InetEndpoint getRmiPort() { return rmiPort; } - public void setRmiPort(InetAddrPort rmiPort) { + public void setRmiPort(InetEndpoint rmiPort) { this.rmiPort = rmiPort; } - public InetAddrPort getXmlrpcPort() { + public InetEndpoint getXmlrpcPort() { return xmlrpcPort; } - public void setXmlrpcPort(InetAddrPort xmlrpcPort) { + public void setXmlrpcPort(InetEndpoint xmlrpcPort) { this.xmlrpcPort = xmlrpcPort; } - public InetAddrPort getWebsrvPort() { + public InetEndpoint getWebsrvPort() { return websrvPort; } - public void setWebsrvPort(InetAddrPort websrvPort) { + public void setWebsrvPort(InetEndpoint websrvPort) { this.websrvPort = websrvPort; } - public InetAddrPort getAjp13Port() { + public InetEndpoint getAjp13Port() { return ajp13Port; } - public void setAjp13Port(InetAddrPort ajp13Port) { + public void setAjp13Port(InetEndpoint ajp13Port) { this.ajp13Port = ajp13Port; }