diff options
author | Jan Bartel | 2012-12-04 07:22:26 +0000 |
---|---|---|
committer | Jan Bartel | 2012-12-04 07:22:26 +0000 |
commit | 6bc507c3af82de4dd781d86cd42fa437c7a83b45 (patch) | |
tree | 9cbefafb531fcf1ade3aa785d80be40372c0f806 /jetty-runner/src/main/java/org/eclipse/jetty/runner | |
parent | 89e5fc93dcd7158e54ea8388bafec22a64151d28 (diff) | |
download | org.eclipse.jetty.project-6bc507c3af82de4dd781d86cd42fa437c7a83b45.tar.gz org.eclipse.jetty.project-6bc507c3af82de4dd781d86cd42fa437c7a83b45.tar.xz org.eclipse.jetty.project-6bc507c3af82de4dd781d86cd42fa437c7a83b45.zip |
395574 port jetty-runner and StatisticsServlet to jetty-9
Diffstat (limited to 'jetty-runner/src/main/java/org/eclipse/jetty/runner')
-rw-r--r-- | jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java | 424 |
1 files changed, 175 insertions, 249 deletions
diff --git a/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java b/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java index 19883158d3..95d46ff2ef 100644 --- a/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java +++ b/jetty-runner/src/main/java/org/eclipse/jetty/runner/Runner.java @@ -18,40 +18,33 @@ package org.eclipse.jetty.runner; -import java.io.File; -import java.io.FileInputStream; import java.io.IOException; import java.io.PrintStream; +import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Properties; -import java.util.Random; -import javax.transaction.UserTransaction; - -import org.eclipse.jetty.util.security.Constraint; -import org.eclipse.jetty.plus.jndi.Transaction; +import org.eclipse.jetty.security.ConstraintMapping; +import org.eclipse.jetty.security.ConstraintSecurityHandler; +import org.eclipse.jetty.security.HashLoginService; +import org.eclipse.jetty.security.authentication.BasicAuthenticator; +import org.eclipse.jetty.server.AbstractConnector; import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.ConnectorStatistics; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.NCSARequestLog; import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ContextHandlerCollection; import org.eclipse.jetty.server.handler.DefaultHandler; import org.eclipse.jetty.server.handler.HandlerCollection; import org.eclipse.jetty.server.handler.RequestLogHandler; import org.eclipse.jetty.server.handler.StatisticsHandler; -import org.eclipse.jetty.server.SelectChannelConnector; import org.eclipse.jetty.server.session.SessionHandler; -import org.eclipse.jetty.security.ConstraintMapping; -import org.eclipse.jetty.security.ConstraintSecurityHandler; -import org.eclipse.jetty.security.HashLoginService; -import org.eclipse.jetty.security.authentication.BasicAuthenticator; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.StatisticsServlet; @@ -59,11 +52,18 @@ import org.eclipse.jetty.util.RolloverFileOutputStream; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import org.eclipse.jetty.util.resource.Resource; +import org.eclipse.jetty.util.security.Constraint; import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.xml.XmlConfiguration; +/** + * Runner + * + * Combine jetty classes into a single executable jar and run webapps based on the args to it. + * + */ public class Runner { private static final Logger LOG = Log.getLogger(Runner.class); @@ -79,36 +79,99 @@ public class Runner org.eclipse.jetty.webapp.JettyWebXmlConfiguration.class.getCanonicalName(), org.eclipse.jetty.webapp.TagLibConfiguration.class.getCanonicalName() }; + public static final String __containerIncludeJarPattern = ".*/jetty-runner-[^/]*\\.jar$"; + public static final String __defaultContextPath = "/"; + public static final int __defaultPort = 8080; protected Server _server; protected Monitor _monitor; protected URLClassLoader _classLoader; - protected List<URL> _classpath=new ArrayList<URL>(); + protected Classpath _classpath = new Classpath(); protected ContextHandlerCollection _contexts; protected RequestLogHandler _logHandler; protected String _logFile; - protected String _configFile; - protected UserTransaction _ut; - protected String _utId; - protected String _txMgrPropertiesFile; - protected Random _random = new Random(); - protected boolean _isTxServiceAvailable=false; - protected boolean _enableStatsGathering=false; + protected ArrayList<String> _configFiles; + protected boolean _enableStats=false; protected String _statsPropFile; - protected boolean _clusteredSessions=true; + + /** + * Classpath + * + * + */ + public class Classpath + { + private List<URL> _classpath = new ArrayList<URL>(); + + public void addJars (Resource lib) throws MalformedURLException, IOException + { + if (lib == null || !lib.exists()) + throw new IllegalStateException ("No such lib: "+lib); + + String[] list = lib.list(); + if (list==null) + return; + + for (String path : list) + { + if (".".equals(path) || "..".equals(path)) + continue; + + Resource item = lib.addPath(path); + + if (item.isDirectory()) + addJars(item); + else + { + if (path.toLowerCase().endsWith(".jar") || + path.toLowerCase().endsWith(".zip")) + { + URL url = item.getURL(); + _classpath.add(url); + } + } + } + } + + + public void addPath (Resource path) + { + if (path == null || !path.exists()) + throw new IllegalStateException ("No such path: "+path); + _classpath.add(path.getURL()); + } + + + public URL[] asArray () + { + return _classpath.toArray(new URL[_classpath.size()]); + } + } + + + + + /** + * + */ public Runner() { } + /** + * Generate helpful usage message and exit + * + * @param error + */ public void usage(String error) { if (error!=null) System.err.println("ERROR: "+error); - System.err.println("Usage: java [-DDEBUG] [-Djetty.home=dir] -jar jetty-runner.jar [--help|--version] [ server opts] [[ context opts] context ...] "); + System.err.println("Usage: java [-Djetty.home=dir] -jar jetty-runner.jar [--help|--version] [ server opts] [[ context opts] context ...] "); System.err.println("Server Options:"); System.err.println(" --version - display version and exit"); System.err.println(" --log file - request log filename (with optional 'yyyy_mm_dd' wildcard"); @@ -117,48 +180,59 @@ public class Runner System.err.println(" --stop-port n - port to listen for stop command"); System.err.println(" --stop-key n - security string for stop command (required if --stop-port is present)"); System.err.println(" --jar file - a jar to be added to the classloader"); - System.err.println(" --jdbc classname properties jndiname - classname of XADataSource or driver; properties string; name to register in jndi"); System.err.println(" --lib dir - a directory of jars to be added to the classloader"); System.err.println(" --classes dir - a directory of classes to be added to the classloader"); - System.err.println(" --txFile - override properties file for Atomikos"); System.err.println(" --stats [unsecure|realm.properties] - enable stats gathering servlet context"); - System.err.println(" --config file - a jetty xml config file to use instead of command line options"); + System.err.println(" [--config file]*n - each --config parameter specifies the name of a jetty xml config file to apply (in the order defined)"); System.err.println("Context Options:"); - System.err.println(" --path /path - context path (default /)"); - System.err.println(" context - WAR file, web app dir or context.xml file"); + System.err.println(" --path /path - context path (default /)"); + System.err.println(" context - WAR file, web app dir or context xml file"); System.exit(1); } + + /** + * Generate version message and exit + */ + public void version () + { + System.err.println("org.eclipse.jetty.runner.Runner: "+Server.getVersion()); + System.exit(1); + } + + + + /** + * Configure a jetty instance and deploy the webapps presented as args + * + * @param args + * @throws Exception + */ public void configure(String[] args) throws Exception { // handle classpath bits first so we can initialize the log mechanism. for (int i=0;i<args.length;i++) { - if ("--version".equals(args[i])) - { - - } - if ("--lib".equals(args[i])) { Resource lib = Resource.newResource(args[++i]); if (!lib.exists() || !lib.isDirectory()) usage("No such lib directory "+lib); - expandJars(lib); + _classpath.addJars(lib); } else if ("--jar".equals(args[i])) { Resource jar = Resource.newResource(args[++i]); if (!jar.exists() || jar.isDirectory()) usage("No such jar "+jar); - _classpath.add(jar.getURL()); + _classpath.addPath(jar); } else if ("--classes".equals(args[i])) { Resource classes = Resource.newResource(args[++i]); if (!classes.exists() || !classes.isDirectory()) usage("No such classes directory "+classes); - _classpath.add(classes.getURL()); + _classpath.addPath(classes); } else if (args[i].startsWith("--")) i++; @@ -166,28 +240,15 @@ public class Runner initClassLoader(); - try - { - if (Thread.currentThread().getContextClassLoader().loadClass("com.atomikos.icatch.jta.UserTransactionImp")!=null) - _isTxServiceAvailable=true; - } - catch (ClassNotFoundException e) - { - _isTxServiceAvailable=false; - } - if (System.getProperties().containsKey("DEBUG")) - Log.getLog().setDebugEnabled(true); - LOG.info("Runner"); LOG.debug("Runner classpath {}",_classpath); - String contextPath="/"; - boolean contextPathSet=false; - int port=8080; - int stopPort=0; - String stopKey=null; + String contextPath = __defaultContextPath; + boolean contextPathSet = false; + int port = __defaultPort; + int stopPort = 0; + String stopKey = null; - boolean transactionManagerProcessed = false; boolean runnerServerInitialized = false; for (int i=0;i<args.length;i++) @@ -215,7 +276,9 @@ public class Runner } else if ("--config".equals(args[i])) { - _configFile=args[++i]; + if (_configFiles == null) + _configFiles = new ArrayList<String>(); + _configFiles.add(args[++i]); } else if ("--lib".equals(args[i])) { @@ -231,40 +294,28 @@ public class Runner } else if ("--stats".equals( args[i])) { - _enableStatsGathering = true; + _enableStats = true; _statsPropFile = args[++i]; _statsPropFile = ("unsecure".equalsIgnoreCase(_statsPropFile)?null:_statsPropFile); } - else if ("--txFile".equals(args[i])) - { - _txMgrPropertiesFile=args[++i]; - } - else if ("--jdbc".equals(args[i])) - { - i=configJDBC(args,i); - } else // process contexts { - if ( !transactionManagerProcessed ) // to be executed once upon starting to process contexts - { - processTransactionManagement(); - transactionManagerProcessed = true; - } - if (!runnerServerInitialized) // log handlers not registered, server maybe not created, etc { if (_server == null) // server not initialized yet { // build the server _server = new Server(); - } - //apply a config file if there is one - if (_configFile != null) + //apply jetty config files if there are any + if (_configFiles != null) { - XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.newResource(_configFile).getURL()); - xmlConfiguration.configure(_server); + for (String cfg:_configFiles) + { + XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.newResource(cfg).getURL()); + xmlConfiguration.configure(_server); + } } //check that everything got configured, and if not, make the handlers @@ -284,14 +335,19 @@ public class Runner } - - if (_enableStatsGathering) + if (_enableStats) { //if no stats handler already configured if (handlers.getChildHandlerByClass(StatisticsHandler.class) == null) { StatisticsHandler statsHandler = new StatisticsHandler(); - prependHandler(statsHandler,handlers); + + + Handler oldHandler = _server.getHandler(); + statsHandler.setHandler(oldHandler); + _server.setHandler(statsHandler); + + ServletContextHandler statsContext = new ServletContextHandler(_contexts, "/stats"); statsContext.addServlet(new ServletHolder(new StatisticsServlet()), "/"); statsContext.setSessionHandler(new SessionHandler()); @@ -335,19 +391,19 @@ public class Runner Connector[] connectors = _server.getConnectors(); if (connectors == null || connectors.length == 0) { - Connector connector = new SelectChannelConnector(); + ServerConnector connector = new ServerConnector(_server); connector.setPort(port); _server.addConnector(connector); - if (_enableStatsGathering) - connector.setStatsOn(true); + if (_enableStats) + connector.addBean(new ConnectorStatistics()); } else { - if (_enableStatsGathering) + if (_enableStats) { for (int j=0; j<connectors.length; j++) { - connectors[j].setStatsOn(true); + ((AbstractConnector)connectors[j]).addBean(new ConnectorStatistics()); } } } @@ -359,6 +415,9 @@ public class Runner Resource ctx = Resource.newResource(args[i]); if (!ctx.exists()) usage("Context '"+ctx+"' does not exist"); + + if (contextPathSet && !(contextPath.startsWith("/"))) + contextPath = "/"+contextPath; // Configure the context if (!ctx.isDirectory() && ctx.toString().toLowerCase().endsWith(".xml")) @@ -367,25 +426,23 @@ public class Runner XmlConfiguration xmlConfiguration=new XmlConfiguration(ctx.getURL()); xmlConfiguration.getIdMap().put("Server",_server); ContextHandler handler=(ContextHandler)xmlConfiguration.configure(); - _contexts.addHandler(handler); if (contextPathSet) handler.setContextPath(contextPath); - handler.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", - ".*/.*jsp-api-[^/]*\\.jar$|.*/.*jsp-[^/]*\\.jar$|.*/.*taglibs[^/]*\\.jar$"); + _contexts.addHandler(handler); + handler.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", __containerIncludeJarPattern); } else { // assume it is a WAR file - if (contextPathSet && !(contextPath.startsWith("/"))) - contextPath = "/"+contextPath; - - LOG.info("Deploying "+ctx.toString()+" @ "+contextPath); WebAppContext webapp = new WebAppContext(_contexts,ctx.toString(),contextPath); webapp.setConfigurationClasses(__plusConfigurationClasses); webapp.setAttribute("org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern", - ".*/.*jsp-api-[^/]*\\.jar$|.*/.*jsp-[^/]*\\.jar$|.*/.*taglibs[^/]*\\.jar$"); - System.err.println(Arrays.asList(_contexts.getHandlers())); + __containerIncludeJarPattern); } + + //reset + contextPathSet = false; + contextPath = __defaultContextPath; } } @@ -418,6 +475,10 @@ public class Runner } + /** + * @param handler + * @param handlers + */ protected void prependHandler (Handler handler, HandlerCollection handlers) { if (handler == null || handlers == null) @@ -432,72 +493,10 @@ public class Runner - - protected int configJDBC(String[] args,int i) throws Exception - { - String jdbcClass=null; - String jdbcProperties=null; - String jdbcJndiName=null; - - if (!_isTxServiceAvailable) - { - LOG.warn("JDBC TX support not found on classpath"); - i+=3; - } - else - { - jdbcClass=args[++i]; - jdbcProperties=args[++i]; - jdbcJndiName=args[++i]; - - //check for jdbc resources to register - if (jdbcClass!=null) - { - if (isXADataSource(jdbcClass)) - { - Class simpleDataSourceBeanClass = Thread.currentThread().getContextClassLoader().loadClass("com.atomikos.jdbc.SimpleDataSourceBean"); - Object o = simpleDataSourceBeanClass.newInstance(); - simpleDataSourceBeanClass.getMethod("setXaDataSourceClassName", new Class[] {String.class}).invoke(o, new Object[] {jdbcClass}); - simpleDataSourceBeanClass.getMethod("setXaDataSourceProperties", new Class[] {String.class}).invoke(o, new Object[] {jdbcProperties}); - simpleDataSourceBeanClass.getMethod("setUniqueResourceName", new Class[] {String.class}).invoke(o, new Object[] {jdbcJndiName}); - org.eclipse.jetty.plus.jndi.Resource jdbcResource = new org.eclipse.jetty.plus.jndi.Resource(jdbcJndiName, o); - - } - else - { - String[] props = jdbcProperties.split(";"); - String user=null; - String password=null; - String url=null; - - for (int j=0;props!=null && j<props.length;j++) - { - String[] pair = props[j].split("="); - if (pair!=null && pair[0].equalsIgnoreCase("user")) - user=pair[1]; - else if (pair!=null && pair[0].equalsIgnoreCase("password")) - password=pair[1]; - else if (pair!=null && pair[0].equalsIgnoreCase("url")) - url=pair[1]; - - } - - Class nonXADataSourceBeanClass = Thread.currentThread().getContextClassLoader().loadClass("com.atomikos.jdbc.nonxa.NonXADataSourceBean"); - Object o = nonXADataSourceBeanClass.newInstance(); - nonXADataSourceBeanClass.getMethod("setDriverClassName", new Class[] {String.class}).invoke(o, new Object[] {jdbcClass}); - nonXADataSourceBeanClass.getMethod("setUniqueResourceName", new Class[] {String.class}).invoke(o, new Object[] {jdbcJndiName}); - nonXADataSourceBeanClass.getMethod("setUrl", new Class[] {String.class}).invoke(o, new Object[] {url}); - nonXADataSourceBeanClass.getMethod("setUser", new Class[] {String.class}).invoke(o, new Object[] {user}); - nonXADataSourceBeanClass.getMethod("setPassword", new Class[] {String.class}).invoke(o, new Object[] {password}); - org.eclipse.jetty.plus.jndi.Resource jdbcResource = new org.eclipse.jetty.plus.jndi.Resource(jdbcJndiName, o); - } - } - } - - return i; - } - + /** + * @throws Exception + */ public void run() throws Exception { if (_monitor != null) @@ -509,106 +508,33 @@ public class Runner _server.join(); } - protected void expandJars(Resource lib) throws IOException - { - String[] list = lib.list(); - if (list==null) - return; - - for (String path : list) - { - if (".".equals(path) || "..".equals(path)) - continue; - - Resource item = lib.addPath(path); - - if (item.isDirectory()) - expandJars(item); - else - { - if (path.toLowerCase().endsWith(".jar") || - path.toLowerCase().endsWith(".zip")) - { - URL url = item.getURL(); - _classpath.add(url); - } - } - } - } + /** + * Establish a classloader with custom paths (if any) + */ protected void initClassLoader() { - if (_classLoader==null && _classpath!=null && _classpath.size()>0) + URL[] paths = _classpath.asArray(); + + if (_classLoader==null && paths !=null && paths.length > 0) { ClassLoader context=Thread.currentThread().getContextClassLoader(); if (context==null) - _classLoader=new URLClassLoader(_classpath.toArray(new URL[_classpath.size()])); + _classLoader=new URLClassLoader(paths); else - _classLoader=new URLClassLoader(_classpath.toArray(new URL[_classpath.size()]),context); + _classLoader=new URLClassLoader(paths, context); Thread.currentThread().setContextClassLoader(_classLoader); } } - protected boolean isXADataSource (String classname) - throws Exception - { - Class clazz = Thread.currentThread().getContextClassLoader().loadClass(classname); - boolean isXA=false; - while (!isXA && clazz!=null) - { - Class[] interfaces = clazz.getInterfaces(); - for (int i=0;interfaces!=null &&!isXA && i<interfaces.length; i++) - { - if (interfaces[i].getCanonicalName().equals("javax.sql.XADataSource")) - isXA=true; - } - clazz=clazz.getSuperclass(); - } - LOG.debug(isXA?"XA":"!XA"); - return isXA; - } - - private void processTransactionManagement() throws Exception - { - //set up a transaction manager - if (!_isTxServiceAvailable) - { - LOG.warn("No tx manager found"); - } - else - { - //this invocation of jetty needs a unique random number to identify the tx manager - _utId = Integer.toHexString(_random.nextInt()); - if (_txMgrPropertiesFile == null) - { - //Use system properties to config atomikos - System.setProperty("com.atomikos.icatch.no_file", "true"); - //create a directory for the tx mgr log and console files to go into that will be unique - File tmpDir = new File(System.getProperty("java.io.tmpdir")); - tmpDir = new File(tmpDir, _utId); - tmpDir.mkdir(); - LOG.debug("Made " + tmpDir.getAbsolutePath()); - System.setProperty("com.atomikos.icatch.log_base_dir ", tmpDir.getCanonicalPath()); - System.setProperty("com.atomikos.icatch.console_file_name", "tm-debug.log"); - System.setProperty("com.atomikos.icatch.output_dir", tmpDir.getCanonicalPath()); - System.setProperty("com.atomikos.icatch.tm_unique_name", _utId); - } - else - { - System.setProperty("com.atomikos.icatch.file", _txMgrPropertiesFile); - } - - //create UserTransaction - Class utsClass = Thread.currentThread().getContextClassLoader().loadClass("com.atomikos.icatch.jta.UserTransactionImp"); - //register in JNDI - Transaction txMgrResource = new Transaction((UserTransaction)utsClass.newInstance()); - } - } + /** + * @param args + */ public static void main(String[] args) { Runner runner = new Runner(); @@ -621,13 +547,13 @@ public class Runner } else if (args.length>0&&args[0].equalsIgnoreCase("--version")) { - System.err.println("org.mortbay.jetty.Runner: "+Server.getVersion()); - System.exit(1); + runner.version(); + } + else + { + runner.configure(args); + runner.run(); } - - runner.configure(args); - runner.run(); - } catch (Exception e) { |