395574 port jetty-runner and StatisticsServlet to jetty-9
This commit is contained in:
parent
89e5fc93dc
commit
6bc507c3af
|
@ -80,6 +80,16 @@
|
|||
<artifactId>jetty-annotations</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jaas</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.websocket</groupId>
|
||||
<artifactId>websocket-server</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jndi</artifactId>
|
||||
|
@ -89,13 +99,6 @@
|
|||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>jetty-jsp</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<exclusions>
|
||||
<!-- tlds must be found in jar on path, not inside runner jar -->
|
||||
<exclusion>
|
||||
<groupId>org.eclipse.jetty.orbit</groupId>
|
||||
<artifactId>org.apache.taglibs.standard.glassfish</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -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(" 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,41 +294,29 @@ 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());
|
||||
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
|
||||
HandlerCollection handlers = (HandlerCollection) _server.getChildHandlerByClass(HandlerCollection.class);
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -360,6 +416,9 @@ public class Runner
|
|||
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)
|
||||
|
@ -433,71 +494,9 @@ 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();
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,282 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2012 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.servlet;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.MemoryMXBean;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
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.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.StatisticsHandler;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
/**
|
||||
* StatisticsServlet
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class StatisticsServlet extends HttpServlet
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(StatisticsServlet.class);
|
||||
|
||||
boolean _restrictToLocalhost = true; // defaults to true
|
||||
private StatisticsHandler _statsHandler;
|
||||
private MemoryMXBean _memoryBean;
|
||||
private Connector[] _connectors;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see javax.servlet.GenericServlet#init()
|
||||
*/
|
||||
public void init() throws ServletException
|
||||
{
|
||||
ServletContext context = getServletContext();
|
||||
ContextHandler.Context scontext = (ContextHandler.Context) context;
|
||||
Server _server = scontext.getContextHandler().getServer();
|
||||
|
||||
Handler handler = _server.getChildHandlerByClass(StatisticsHandler.class);
|
||||
|
||||
if (handler != null)
|
||||
{
|
||||
_statsHandler = (StatisticsHandler) handler;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG.warn("Statistics Handler not installed!");
|
||||
return;
|
||||
}
|
||||
|
||||
_memoryBean = ManagementFactory.getMemoryMXBean();
|
||||
_connectors = _server.getConnectors();
|
||||
|
||||
if (getInitParameter("restrictToLocalhost") != null)
|
||||
{
|
||||
_restrictToLocalhost = "true".equals(getInitParameter("restrictToLocalhost"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||
*/
|
||||
public void doPost(HttpServletRequest sreq, HttpServletResponse sres) throws ServletException, IOException
|
||||
{
|
||||
doGet(sreq, sres);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
|
||||
*/
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
||||
{
|
||||
if (_statsHandler == null)
|
||||
{
|
||||
LOG.warn("Statistics Handler not installed!");
|
||||
resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
|
||||
return;
|
||||
}
|
||||
if (_restrictToLocalhost)
|
||||
{
|
||||
if (!"127.0.0.1".equals(req.getRemoteAddr()))
|
||||
{
|
||||
resp.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
String wantXml = req.getParameter("xml");
|
||||
if (wantXml == null)
|
||||
wantXml = req.getParameter("XML");
|
||||
|
||||
if (wantXml != null && "true".equalsIgnoreCase(wantXml))
|
||||
{
|
||||
sendXmlResponse(resp);
|
||||
}
|
||||
else
|
||||
{
|
||||
sendTextResponse(resp);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param response
|
||||
* @throws IOException
|
||||
*/
|
||||
private void sendXmlResponse(HttpServletResponse response) throws IOException
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
sb.append("<statistics>\n");
|
||||
|
||||
sb.append(" <requests>\n");
|
||||
sb.append(" <statsOnMs>").append(_statsHandler.getStatsOnMs()).append("</statsOnMs>\n");
|
||||
|
||||
sb.append(" <requests>").append(_statsHandler.getRequests()).append("</requests>\n");
|
||||
sb.append(" <requestsActive>").append(_statsHandler.getRequestsActive()).append("</requestsActive>\n");
|
||||
sb.append(" <requestsActiveMax>").append(_statsHandler.getRequestsActiveMax()).append("</requestsActiveMax>\n");
|
||||
sb.append(" <requestsTimeTotal>").append(_statsHandler.getRequestTimeTotal()).append("</requestsTimeTotal>\n");
|
||||
sb.append(" <requestsTimeMean>").append(_statsHandler.getRequestTimeMean()).append("</requestsTimeMean>\n");
|
||||
sb.append(" <requestsTimeMax>").append(_statsHandler.getRequestTimeMax()).append("</requestsTimeMax>\n");
|
||||
sb.append(" <requestsTimeStdDev>").append(_statsHandler.getRequestTimeStdDev()).append("</requestsTimeStdDev>\n");
|
||||
|
||||
sb.append(" <dispatched>").append(_statsHandler.getDispatched()).append("</dispatched>\n");
|
||||
sb.append(" <dispatchedActive>").append(_statsHandler.getDispatchedActive()).append("</dispatchedActive>\n");
|
||||
sb.append(" <dispatchedActiveMax>").append(_statsHandler.getDispatchedActiveMax()).append("</dispatchedActiveMax>\n");
|
||||
sb.append(" <dispatchedTimeTotalMs>").append(_statsHandler.getDispatchedTimeTotal()).append("</dispatchedTimeTotalMs>\n");
|
||||
sb.append(" <dispatchedTimeMeanMs>").append(_statsHandler.getDispatchedTimeMean()).append("</dispatchedTimeMeanMs>\n");
|
||||
sb.append(" <dispatchedTimeMaxMs>").append(_statsHandler.getDispatchedTimeMax()).append("</dispatchedTimeMaxMs>\n");
|
||||
sb.append(" <dispatchedTimeStdDevMs>").append(_statsHandler.getDispatchedTimeStdDev()).append("</dispatchedTimeStdDevMs>\n");
|
||||
|
||||
sb.append(" <asyncRequests>").append(_statsHandler.getAsyncRequests()).append("</asyncRequests>\n");
|
||||
sb.append(" <requestsSuspended>").append(_statsHandler.getAsyncRequestsWaiting()).append("</requestsSuspended>\n");
|
||||
sb.append(" <requestsSuspendedMax>").append(_statsHandler.getAsyncRequestsWaitingMax()).append("</requestsSuspendedMax>\n");
|
||||
sb.append(" <requestsResumed>").append(_statsHandler.getAsyncDispatches()).append("</requestsResumed>\n");
|
||||
sb.append(" <requestsExpired>").append(_statsHandler.getExpires()).append("</requestsExpired>\n");
|
||||
sb.append(" </requests>\n");
|
||||
|
||||
sb.append(" <responses>\n");
|
||||
sb.append(" <responses1xx>").append(_statsHandler.getResponses1xx()).append("</responses1xx>\n");
|
||||
sb.append(" <responses2xx>").append(_statsHandler.getResponses2xx()).append("</responses2xx>\n");
|
||||
sb.append(" <responses3xx>").append(_statsHandler.getResponses3xx()).append("</responses3xx>\n");
|
||||
sb.append(" <responses4xx>").append(_statsHandler.getResponses4xx()).append("</responses4xx>\n");
|
||||
sb.append(" <responses5xx>").append(_statsHandler.getResponses5xx()).append("</responses5xx>\n");
|
||||
sb.append(" <responsesBytesTotal>").append(_statsHandler.getResponsesBytesTotal()).append("</responsesBytesTotal>\n");
|
||||
sb.append(" </responses>\n");
|
||||
|
||||
sb.append(" <connections>\n");
|
||||
for (Connector connector : _connectors)
|
||||
{
|
||||
sb.append(" <connector>\n");
|
||||
sb.append(" <name>").append(connector.getClass().getName()).append("@").append(connector.hashCode()).append("</name>\n");
|
||||
sb.append(" <protocols>\n");
|
||||
for (String protocol:connector.getProtocols())
|
||||
sb.append(" <protocol>").append(protocol).append("</protocol>\n");
|
||||
sb.append(" </protocols>\n");
|
||||
|
||||
ConnectorStatistics connectorStats = null;
|
||||
|
||||
if (connector instanceof AbstractConnector)
|
||||
connectorStats = ((AbstractConnector)connector).getBean(ConnectorStatistics.class);
|
||||
if (connectorStats == null)
|
||||
sb.append(" <statsOn>false</statsOn>\n");
|
||||
else
|
||||
{
|
||||
sb.append(" <statsOn>true</statsOn>\n");
|
||||
sb.append(" <connections>").append(connectorStats.getConnections()).append("</connections>\n");
|
||||
sb.append(" <connectionsOpen>").append(connectorStats.getConnectionsOpen()).append("</connectionsOpen>\n");
|
||||
sb.append(" <connectionsOpenMax>").append(connectorStats.getConnectionsOpenMax()).append("</connectionsOpenMax>\n");
|
||||
sb.append(" <connectionsDurationTotal>").append(connectorStats.getConnectionsDurationTotal()).append("</connectionsDurationTotal>\n");
|
||||
sb.append(" <connectionsDurationMean>").append(connectorStats.getConnectionsDurationMean()).append("</connectionsDurationMean>\n");
|
||||
sb.append(" <connectionsDurationMax>").append(connectorStats.getConnectionsDurationMax()).append("</connectionsDurationMax>\n");
|
||||
sb.append(" <connectionsDurationStdDev>").append(connectorStats.getConnectionsDurationStdDev()).append("</connectionsDurationStdDev>\n");
|
||||
sb.append(" <messagesIn>").append(connectorStats.getMessagesIn()).append("</messagesIn>\n");
|
||||
sb.append(" <messagesOut>").append(connectorStats.getMessagesIn()).append("</messagesOut>\n");
|
||||
sb.append(" <elapsedMs>").append(connectorStats.getStartedMillis()).append("</elapsedMs>\n");
|
||||
}
|
||||
sb.append(" </connector>\n");
|
||||
}
|
||||
sb.append(" </connections>\n");
|
||||
|
||||
sb.append(" <memory>\n");
|
||||
sb.append(" <heapMemoryUsage>").append(_memoryBean.getHeapMemoryUsage().getUsed()).append("</heapMemoryUsage>\n");
|
||||
sb.append(" <nonHeapMemoryUsage>").append(_memoryBean.getNonHeapMemoryUsage().getUsed()).append("</nonHeapMemoryUsage>\n");
|
||||
sb.append(" </memory>\n");
|
||||
|
||||
sb.append("</statistics>\n");
|
||||
|
||||
response.setContentType("text/xml");
|
||||
PrintWriter pout = response.getWriter();
|
||||
pout.write(sb.toString());
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param response
|
||||
* @throws IOException
|
||||
*/
|
||||
private void sendTextResponse(HttpServletResponse response) throws IOException
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(_statsHandler.toStatsHTML());
|
||||
|
||||
sb.append("<h2>Connections:</h2>\n");
|
||||
for (Connector connector : _connectors)
|
||||
{
|
||||
sb.append("<h3>").append(connector.getClass().getName()).append("@").append(connector.hashCode()).append("</h3>");
|
||||
sb.append("Protocols:");
|
||||
for (String protocol:connector.getProtocols())
|
||||
sb.append(protocol).append(" ");
|
||||
sb.append(" <br />\n");
|
||||
|
||||
ConnectorStatistics connectorStats = null;
|
||||
|
||||
if (connector instanceof AbstractConnector)
|
||||
connectorStats = ((AbstractConnector)connector).getBean(ConnectorStatistics.class);
|
||||
|
||||
if (connectorStats != null)
|
||||
{
|
||||
sb.append("Statistics gathering started ").append(connectorStats.getStartedMillis()).append("ms ago").append("<br />\n");
|
||||
sb.append("Total connections: ").append(connectorStats.getConnections()).append("<br />\n");
|
||||
sb.append("Current connections open: ").append(connectorStats.getConnectionsOpen()).append("<br />\n");;
|
||||
sb.append("Max concurrent connections open: ").append(connectorStats.getConnectionsOpenMax()).append("<br />\n");
|
||||
sb.append("Total connections duration: ").append(connectorStats.getConnectionsDurationTotal()).append("<br />\n");
|
||||
sb.append("Mean connection duration: ").append(connectorStats.getConnectionsDurationMean()).append("<br />\n");
|
||||
sb.append("Max connection duration: ").append(connectorStats.getConnectionsDurationMax()).append("<br />\n");
|
||||
sb.append("Connection duration standard deviation: ").append(connectorStats.getConnectionsDurationStdDev()).append("<br />\n");
|
||||
sb.append("Total messages in: ").append(connectorStats.getMessagesIn()).append("<br />\n");
|
||||
sb.append("Total messages out: ").append(connectorStats.getMessagesOut()).append("<br />\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.append("Statistics gathering off.\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sb.append("<h2>Memory:</h2>\n");
|
||||
sb.append("Heap memory usage: ").append(_memoryBean.getHeapMemoryUsage().getUsed()).append(" bytes").append("<br />\n");
|
||||
sb.append("Non-heap memory usage: ").append(_memoryBean.getNonHeapMemoryUsage().getUsed()).append(" bytes").append("<br />\n");
|
||||
|
||||
response.setContentType("text/html");
|
||||
PrintWriter pout = response.getWriter();
|
||||
pout.write(sb.toString());
|
||||
|
||||
}
|
||||
}
|
2
pom.xml
2
pom.xml
|
@ -414,11 +414,11 @@
|
|||
<module>tests</module>
|
||||
<module>aggregates/jetty-all</module>
|
||||
<module>jetty-distribution</module>
|
||||
<module>jetty-runner</module>
|
||||
|
||||
<!-- modules that need fixed and added back, or simply dropped and not maintained
|
||||
<module>tests</module>
|
||||
|
||||
<module>jetty-runner</module>
|
||||
<module>jetty-rhttp</module>
|
||||
<module>jetty-http-spi</module>
|
||||
-->
|
||||
|
|
Loading…
Reference in New Issue