jetty下载神马的就不写了。
首先,jetty启动脚本jetty.sh
1. 设置JETTY_HOME
##################################################
# Try to determine JETTY_HOME if not set
##################################################
if [ -z "$JETTY_HOME" ]
then
JETTY_SH=$0
case "$JETTY_SH" in
/*) ;;
./*) ;;
*) JETTY_SH=./$JETTY_SH ;;
esac
JETTY_HOME=${JETTY_SH%/*/*}
if [ ! -f "${JETTY_SH%/*/*}/$JETTY_INSTALL_TRACE_FILE" ]
then
JETTY_HOME=
fi
fi
...
2. 寻找配置文件
##################################################
# Try to find this script's configuration file,
# but only if no configurations were given on the
# command line.
##################################################
if [ -z "$JETTY_CONF" ]
then
if [ -f /etc/jetty.conf ]
then
JETTY_CONF=/etc/jetty.conf
elif [ -f "$JETTY_HOME/etc/jetty.conf" ]
then
JETTY_CONF=$JETTY_HOME/etc/jetty.conf
fi
fi
3. 寻找并设置java和jetty相关的信息
...
##################################################
# Setup JAVA if unset
##################################################
if [ -z "$JAVA" ]
then
JAVA=$(which java)
fi
if [ -z "$JAVA" ]
then
echo "Cannot find a Java JDK. Please set either set JAVA or put java (>=1.5) in your PATH." 2>&2
exit 1
fi
...
4. 拼装执行命令行
JETTY_START=$JETTY_HOME/start.jar
[ ! -f "$JETTY_START" ] && JETTY_START=$JETTY_HOME/lib/start.jar
START_INI=$(dirname $JETTY_START)/start.ini
[ -r "$START_INI" ] || START_INI=""
RUN_ARGS=(${JAVA_OPTIONS[@]} -jar "$JETTY_START" $JETTY_ARGS "${CONFIGS[@]}")
RUN_CMD=("$JAVA" ${RUN_ARGS[@]})
5. 执行
case "$ACTION" in
start)
...
if [ "$JETTY_USER" ]
then
touch "$JETTY_PID"
chown "$JETTY_USER" "$JETTY_PID"
# FIXME: Broken solution: wordsplitting, pathname expansion, arbitrary command execution, etc.
su - "$JETTY_USER" -c "
${RUN_CMD[*]} --daemon &
disown \$!
echo \$! > '$JETTY_PID'"
else
"${RUN_CMD[@]}" &
disown $!
echo $! > "$JETTY_PID"
fi
echo "STARTED Jetty `date`"
...
start.jar
1. 根据配置,寻找org.eclipse.jetty.start.MainManifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: jesse
Build-Jdk: 1.6.0_19
Main-Class: org.eclipse.jetty.start.Main
Implementation-Vendor: Eclipse.org - Jetty
Implementation-Version: 7.2.0.v20101020
url: http://www.eclipse.org/jetty
2.执行main方法
(1). 解析参数:parseCommandLine
(2). 读取配置文件.start.config
// Load potential Config (start.config)
List<String> configuredXmls = loadConfig(xmls);
private InputStream [More ...] getConfigStream() throws FileNotFoundException
{
String config=_startConfig;
if (config==null || config.length()==0)
config=System.getProperty("START","org/eclipse/jetty/start/start.config");
Config.debug("config=" + config);
// Look up config as resource first.
InputStream cfgstream = getClass().getClassLoader().getResourceAsStream(config);
// resource not found, try filesystem next
if (cfgstream == null)
cfgstream = new FileInputStream(config);
return cfgstream;
}
(3). 初始化classloader
// Get Desired Classpath based on user provided Active Options.
Classpath classpath = _config.getActiveClasspath();
System.setProperty("java.class.path",classpath.toString());
lassLoader cl = classpath.getClassLoader();
...
// Set current context class loader to what is selected.
Thread.currentThread().setContextClassLoader(cl);
(4). 初始化安全manager
// Initialize the Security
initSecurity(cl);
(5). 执行配置文件中指定的mainClass:org.eclipse.jetty.xml.XmlConfiguration.class
// Get main class as defined in start.config
String classname = _config.getMainClassname();
// Check for override of start class (via "jetty.server" property)
String mainClass = System.getProperty("jetty.server");
if (mainClass != null)
classname = mainClass;
// Check for override of start class (via "main.class" property)
mainClass = System.getProperty("main.class");
if (mainClass != null)
classname = mainClass;
Config.debug("main.class=" + classname);
invokeMain(cl,classname,configuredXmls);
start.config的解析
文件的开头是对内容中格式的解释,对比下面内容就可以理解
如果lib文件或目录存在,则遍历目录将jar and zip文件expanded to a start property
# add a property defined library directory
${lib}/** exists ${lib}
设置jetty.home到system properties
# Try different settings of jetty.home until the start.jar is found.
jetty.home=. ! exists $(jetty.home)/start.jar
jetty.home=.. ! exists $(jetty.home)/start.jar
jetty.home=jetty-distribution/src/main/resources ! exists $(jetty.home)/start.jar
jetty.home=../jetty-distribution/src/main/resources ! exists $(jetty.home)/start.jar
jetty.home=. ! exists $(jetty.home)/start.jar
jetty.home/=$(jetty.home) exists $(jetty.home)/start.jar
设置main class
# The main class to run
org.eclipse.jetty.xml.XmlConfiguration.class
${start.class}.class property start.class
设置默认配置文件
# The default configuration files
$(jetty.home)/etc/jetty.xml nargs == 0
./jetty-server/src/main/config/etc/jetty.xml nargs == 0 AND ! exists $(jetty.home)/etc/jetty.xml
设置module特有的特性,如果启动的OPTIONS中All/resources/default中的任一个,就执行相关设置
# Add a resources directory if it is there
[All,resources,default]
$(jetty.home)/resources/
XmlConfiguration
1. 通过AccessController.doPrivileged赋予run内部的代码特权,避开checkPermission,详细解释见:http://www.jar114.com/jdk5/zh_CN/api/java/security/AccessController.html public static void main(final String[] args) throws Exception
{
final AtomicReference<Throwable> exception = new AtomicReference<Throwable>();
AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
...
}
});
Throwable th = exception.get();
...
}
2. 读取start.jar中带过来的配置
public Object run()
{
try
{
Properties properties = null;
// Look for properties from start.jar
try
{
Class<?> config = XmlConfiguration.class.getClassLoader().loadClass("org.eclipse.jetty.start.Config");
properties = (Properties)config.getMethod("getProperties").invoke(null);
Log.debug("org.eclipse.jetty.start.Config properties = {}",properties);
}
3. 加载properties或者解析xml
// For all arguments, load properties or parse XMLs
XmlConfiguration last = null;
Object[] obj = new Object[args.length];
for (int i = 0; i < args.length; i++)
{
if (args[i].toLowerCase().endsWith(".properties"))
{
properties.load(Resource.newResource(args[i]).getInputStream());
}
else
{
XmlConfiguration configuration = new XmlConfiguration(Resource.newResource(args[i]).getURL());
... }
}
4. 执行lifecycle,go
/ For all objects created by XmlConfigurations, start them if they are lifecycles.
for (int i = 0; i < args.length; i++)
{
if (obj[i] instanceof LifeCycle)
{
LifeCycle lc = (LifeCycle)obj[i];
if (!lc.isRunning())
lc.start();
}
}
jetty.xml
在上面的第三步中解析xml里面会处理jetty.xml(具体jetty.xml文件位置看上文)
下面是一份简单的jetty.xml的配置
<Configure id="Server" class="org.eclipse.jetty.server.Server">:相当于
<Set name="ThreadPool">:设置Server对象中的_threadPool属性
<New class="org.eclipse.jetty.util.thread.QueuedThreadPool">:新建一个pool
<Set name="minThreads">10</Set>:设置pool的属性
<Call name="addConnector">:调用service的addConnector方法
<Arg>:指定方法参数
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<Set name="ThreadPool">
<!-- Default queued blocking threadpool -->
<New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
<Set name="minThreads">10</Set>
<Set name="maxThreads">200</Set>
</New>
</Set>
<Call name="addConnector">
<Arg>
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
<Set name="host"><Property name="jetty.host" /></Set>
<Set name="port"><Property name="jetty.port" default="8080"/>7001</Set>
<Set name="maxIdleTime">300000</Set>
<Set name="Acceptors">2</Set>
<Set name="statsOn">false</Set>
<Set name="confidentialPort">8443</Set>
<Set name="lowResourcesConnections">20000</Set>
<Set name="lowResourcesMaxIdleTime">5000</Set>
</New>
</Arg>
</Call>
<Set name="handler">
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
<Set name="handlers">
<Array type="org.eclipse.jetty.server.Handler">
<Item>
<New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
</Item>
<Item>
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
</Item>
</Array>
</Set>
</New>
</Set>
<Set name="stopAtShutdown">true</Set>
<Set name="sendServerVersion">true</Set>
<Set name="sendDateHeader">true</Set>
<Set name="gracefulShutdown">1000</Set>
</Configure>