Merge branch 'jetty-9.1-altstart' into jetty-9.1

This commit is contained in:
Joakim Erdfelt 2013-08-23 11:50:04 -07:00
commit 938a31463a
203 changed files with 3038 additions and 4121 deletions

View File

@ -0,0 +1,14 @@
#
# Jetty Annotation Scanning Module
#
# Annotations needs plus, and jndi features
DEPEND=plus
# Annotations needs jetty annotation jars
LIB=lib/jetty-annotations-${jetty.version}.jar
# Need annotation processing jars too
LIB=lib/annotations/*.jar
# Enable annotation scanning webapp configurations
etc/jetty-annotations.xml

View File

@ -1,144 +1,154 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.1.0-SNAPSHOT</version>
</parent>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-client</artifactId>
<name>Jetty :: Asynchronous HTTP Client</name>
<url>http://www.eclipse.org/jetty</url>
<properties>
<bundle-symbolic-name>${project.groupId}.client</bundle-symbolic-name>
<jetty.test.policy.loc>target/test-policy</jetty.test.policy.loc>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>manifest</goal>
</goals>
<configuration>
<instructions>
<Import-Package>javax.net.*,*</Import-Package>
</instructions>
</configuration>
</execution>
</executions>
</plugin>
<!--
Required for OSGI
-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<configuration>
<onlyAnalyze>org.eclipse.jetty.client.*</onlyAnalyze>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>generate-test-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-policy</artifactId>
<version>${jetty-test-policy-version}</version>
<type>jar</type>
<overWrite>true</overWrite>
<includes>**/*.keystore,**/*.pem</includes>
<outputDirectory>${jetty.test.policy.loc}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-client</artifactId>
<name>Jetty :: Asynchronous HTTP Client</name>
<url>http://www.eclipse.org/jetty</url>
<properties>
<bundle-symbolic-name>${project.groupId}.client</bundle-symbolic-name>
<jetty.test.policy.loc>target/test-policy</jetty.test.policy.loc>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>config</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>manifest</goal>
</goals>
<configuration>
<instructions>
<Import-Package>javax.net.*,*</Import-Package>
</instructions>
</configuration>
</execution>
</executions>
</plugin>
<!-- Required for OSGI -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<configuration>
<onlyAnalyze>org.eclipse.jetty.client.*</onlyAnalyze>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>generate-test-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-policy</artifactId>
<version>${jetty-test-policy-version}</version>
<type>jar</type>
<overWrite>true</overWrite>
<includes>**/*.keystore,**/*.pem</includes>
<outputDirectory>${jetty.test.policy.loc}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-io</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.spdy</groupId>
<artifactId>spdy-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-io</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.spdy</groupId>
<artifactId>spdy-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<!--
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-websocket</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>-->
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-security</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.ning</groupId>
<artifactId>async-http-client</artifactId>
<version>1.7.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<dependency>
<groupId>com.ning</groupId>
<artifactId>async-http-client</artifactId>
<version>1.7.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,6 @@
#
# Client Feature
#
# Client jars
LIB=lib/jetty-client-${jetty.version}.jar

View File

@ -0,0 +1,9 @@
#
# Deploy Feature
#
# Deploy jars
LIB=lib/jetty-deploy-${jetty.version}.jar
# Deploy configuration
etc/jetty-deploy.xml

View File

@ -297,8 +297,8 @@
</goals>
<configuration>
<includeGroupIds>org.eclipse.jetty</includeGroupIds>
<excludeGroupIds>org.eclipse.jetty.orbit,org.eclipse.jetty.spdy,org.eclipse.jetty.websocket</excludeGroupIds>
<excludeArtifactIds>jetty-all,jetty-start,jetty-monitor</excludeArtifactIds>
<excludeGroupIds>org.eclipse.jetty.orbit,org.eclipse.jetty.spdy,org.eclipse.jetty.websocket,org.eclipse.jetty.toolchain</excludeGroupIds>
<excludeArtifactIds>jetty-all,jetty-jsp,jetty-start,jetty-monitor</excludeArtifactIds>
<includeTypes>jar</includeTypes>
<outputDirectory>${assembly-directory}/lib</outputDirectory>
</configuration>
@ -612,6 +612,11 @@
<artifactId>jetty-proxy</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-overlay-deployer</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jaas</artifactId>

View File

@ -1,27 +0,0 @@
#===========================================================
# Configure JVM arguments.
# If JVM args are include in an ini file then --exec is needed
# to start a new JVM from start.jar with the extra args.
# If you wish to avoid an extra JVM running, place JVM args
# on the normal command line and do not use --exec
#
# IF USED, THIS MODULE WILL INVOKE AN EXTRA JVM INSTANCE!!
#-----------------------------------------------------------
--exec
-Xmx2000m
-Xmn512m
-XX:+UseConcMarkSweepGC
-XX:ParallelCMSThreads=2
-XX:+CMSClassUnloadingEnabled
-XX:+UseCMSCompactAtFullCollection
-XX:CMSInitiatingOccupancyFraction=80
# -verbose:gc
# -XX:+PrintGCDateStamps
# -XX:+PrintGCTimeStamps
# -XX:+PrintGCDetails
# -XX:+PrintTenuringDistribution
# -XX:+PrintCommandLineFlags
# -XX:+DisableExplicitGC
# -Dorg.apache.jasper.compiler.disablejsr199=true

View File

@ -1,17 +0,0 @@
#===========================================================
# NPN Next Protocol Negotiation
#
# The SPDY and HTTP/2.0 connectors require NPN. The jar for
# NPN cannot be downloaded from eclipse. So the --download
# option is used to install the NPN jar if it does not already
# exist
#
#-----------------------------------------------------------
DEFINE=npn
OPTION=npn
--exec
--download=http://repo1.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.5.v20130313/npn-boot-1.1.5.v20130313.jar:lib/npn/npn-boot-1.1.5.v20130313.jar
-Xbootclasspath/p:lib/npn/npn-boot-1.1.5.v20130313.jar

View File

@ -1,3 +0,0 @@
# Add libraries from lib/ext to the classpath
OPTION=ext

View File

@ -1,9 +0,0 @@
#===========================================================
# JMX Management
#-----------------------------------------------------------
jetty.jmxrmihost=localhost
jetty.jmxrmiport=1099
--exec
-Dcom.sun.management.jmxremote

View File

@ -1,3 +0,0 @@
# Add the resources directory to the classpath
OPTION=resources

View File

@ -1,21 +0,0 @@
#===========================================================
# Default Server Options
# Use the core server jars with websocket on the classpath
# Add the contents of the resources directory to the classpath
# Add jars discovered in lib/ext to the classpath
# Include the core jetty configuration file
#-----------------------------------------------------------
DEFINE=jetty
OPTION=jetty
threads.min=10
threads.max=200
threads.timeout=60000
#jetty.host=myhost.com
jetty.dump.start=false
jetty.dump.stop=false
#jetty.logs=/var/log/jetty
OPTION=Server
etc/jetty.xml

View File

@ -1,8 +0,0 @@
#===========================================================
# JMX Management
#-----------------------------------------------------------
OPTION=jmx
DEPEND=jetty
etc/jetty-jmx.xml

View File

@ -1,6 +0,0 @@
#===========================================================
# Java Server Pages
#-----------------------------------------------------------
OPTION=jsp
DEPEND=jetty

View File

@ -1,11 +0,0 @@
#===========================================================
# stderr/stdout logging.
# The following configuration will redirect stderr and stdout
# to file which is rolled over daily.
#-----------------------------------------------------------
DEPEND=jetty
jetty.log.retain=90
etc/jetty-logging.xml

View File

@ -1,14 +0,0 @@
#===========================================================
# Enable SetUID
# The default user and group is 'jetty' and if you are
# starting as root you must change the run privledged to true
#-----------------------------------------------------------
jetty.startServerAsPrivileged=false
jetty.username=jetty
jetty.groupname=jetty
jetty.umask=002
OPTION=setuid
etc/jetty-setuid.xml

View File

@ -1,18 +0,0 @@
#===========================================================
# SSL Context
# Create the keystore and trust store for use by
# HTTPS and SPDY
#-----------------------------------------------------------
jetty.keystore=etc/keystore
jetty.keystore.password=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4
jetty.keymanager.password=OBF:1u2u1wml1z7s1z7a1wnl1u2g
jetty.truststore=etc/keystore
jetty.truststore.password=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4
jetty.secure.port=8443
DEPEND=jetty
DEFINE=ssl
OPTION=ssl
etc/jetty-ssl.xml

View File

@ -1,6 +0,0 @@
#===========================================================
# WebSocket Support
#-----------------------------------------------------------
DEPEND=jetty
OPTION=websocket

View File

@ -1,12 +0,0 @@
#===========================================================
# HTTP Connector
#-----------------------------------------------------------
jetty.port=8080
http.timeout=30000
DEPEND=jetty
DEFINE=http
OPTION=http
etc/jetty-http.xml

View File

@ -1,15 +0,0 @@
#===========================================================
# HTTPS Connector
# Must be used with jetty-ssl.xml
#-----------------------------------------------------------
jetty.https.port=8443
EXCLUDE=spdy
DEFINE=https
OPTION=https
DEPEND=ssl
etc/jetty-https.xml

View File

@ -1,12 +0,0 @@
#===========================================================
# SPDY Connector
#-----------------------------------------------------------
jetty.spdy.port=8443
EXCLUDE=https
OPTION=spdy
DEPEND=npn,ssl
etc/jetty-spdy.xml

View File

@ -1,10 +0,0 @@
# ===========================================================
# Enable JAAS
# -----------------------------------------------------------
jaas.login.conf=etc/login.conf
OPTION=jaas
EXCLUDE=demo
etc/jetty-jaas.xml

View File

@ -1,6 +0,0 @@
# ===========================================================
# Enable JNDI
# -----------------------------------------------------------
OPTION=jndi
EXCLUDE=demo

View File

@ -1,6 +0,0 @@
# ===========================================================
# Enable additional webapp environment configurators
# -----------------------------------------------------------
OPTION=plus
etc/jetty-plus.xml

View File

@ -1,11 +0,0 @@
#===========================================================
# Request logger
# Will add a handler to log all HTTP requests to a standard
# request log format file.
#-----------------------------------------------------------
requestlog.retain=90
requestlog.append=true
requestlog.extended=true
etc/jetty-requestlog.xml

View File

@ -1,9 +0,0 @@
# ===========================================================
# Enable servlet 3.1 annotations
# -----------------------------------------------------------
OPTION=annotations
DEPEND=plus
etc/jetty-annotations.xml

View File

@ -1,9 +0,0 @@
#===========================================================
# WebSocket Annotations Support
#-----------------------------------------------------------
DEFINE=websocket-annotations
OPTION=websocket-annotations
DEPEND=websocket
etc/jetty-websockets.xml

View File

@ -1 +0,0 @@
etc/jetty-debug.xml

View File

@ -1 +0,0 @@
etc/jetty-ipaccess.xml

View File

@ -1,13 +0,0 @@
#===========================================================
# Low resource management
#-----------------------------------------------------------
lowresources.period=1050
lowresources.lowResourcesIdleTimeout=200
lowresources.monitorThreads=true
lowresources.maxConnections=0
lowresources.maxMemory=0
lowresources.maxLowResourcesTime=5000
etc/jetty-lowresources.xml

View File

@ -1,7 +0,0 @@
# ===========================================================
# Enable rewrite handler
# -----------------------------------------------------------
OPTION=rewrite
EXCLUDE=demo
etc/jetty-rewrite.xml

View File

@ -1 +0,0 @@
etc/jetty-stats.xml

View File

@ -1,8 +0,0 @@
#===========================================================
# Webapplication Deployer
#-----------------------------------------------------------
DEFINE=deploy
OPTION=deploy
DEPEND=jetty
etc/jetty-deploy.xml

View File

@ -1,4 +1,3 @@
# ===========================================================
# Enable the demonstration web applications
#
@ -6,22 +5,10 @@
# the start.d directory or rename it to not end with ".ini"
# ===========================================================
# The following options are explicitly configured for the demo
# in this file. Thus they cannot be used with the normal
# activation of them
MODULES=jaas,jndi,rewrite,client,annotations,websocket
jaas.login.conf=webapps.demo/test-jaas.d/login.conf
EXCLUDE=jaas,jndi,rewrite
OPTION=jaas,jndi,rewrite,client
etc/jetty-rewrite.xml
etc/jetty-jaas.xml
# Activate the demo options and configurations
OPTION=jndi.demo
etc/jetty-demo.xml
etc/test-realm.xml
MODULES=jndi.demo
DEPEND=ext,resources,http,plus,annotations,websocket-annotations,deploy

View File

@ -0,0 +1,220 @@
#===========================================================
# Jetty start.jar arguments
#
# The contents of this file, together with the start.ini
# fragments found in start.d directory are used to build
# the classpath and command line on a call to
# java -jar start.jar [arg...]
#
# Use the following command to see more options
# java -jar start.jar --help
#
# Each line in this file is prepended to the command line
# as arguments, which may be either:
# + A property like: name=value
# + A file of properties like: /etc/myjetty.properties
# + A classpath option like: OPTION=jmx
# + An XML configuration file like: etc/jetty-feature.xml
# + A start.jar option like: --dry-run
#
# If --exec or --exec-print are used, then this file may also
# contain lines with:
# + A JVM option like: -Xmx2000m
# + A System Property like: -Dcom.sun.management.jmxremote
#
#-----------------------------------------------------------
#
# NOTE: The lines in this file may be uncommented to activate
# features. Alternately, the lines may be copied to a ini file
# in the start.d directory to enabled configuration without
# editing this file. See start.d/900-demo.ini for an example.
#
# Future releases will switch start.d style configuration for
# all features.
#===========================================================
#===========================================================
# Configure JVM arguments.
# If JVM args are include in an ini file then --exec is needed
# to start a new JVM from start.jar with the extra args.
# If you wish to avoid an extra JVM running, place JVM args
# on the normal command line and do not use --exec
#-----------------------------------------------------------
# --exec
# -Xmx2000m
# -Xmn512m
# -XX:+UseConcMarkSweepGC
# -XX:ParallelCMSThreads=2
# -XX:+CMSClassUnloadingEnabled
# -XX:+UseCMSCompactAtFullCollection
# -XX:CMSInitiatingOccupancyFraction=80
# -verbose:gc
# -XX:+PrintGCDateStamps
# -XX:+PrintGCTimeStamps
# -XX:+PrintGCDetails
# -XX:+PrintTenuringDistribution
# -XX:+PrintCommandLineFlags
# -XX:+DisableExplicitGC
# -Dorg.apache.jasper.compiler.disablejsr199=true
#===========================================================
# Default Server Options
# Use the core server jars with websocket on the classpath
# Add the contents of the resources directory to the classpath
# Add jars discovered in lib/ext to the classpath
# Include the core jetty configuration file
#-----------------------------------------------------------
threads.min=10
threads.max=200
threads.timeout=60000
#jetty.host=myhost.com
jetty.dump.start=false
jetty.dump.stop=false
#===========================================================
# JMX Management
# To enable remote JMX access uncomment jmxremote and
# enable --exec
#-----------------------------------------------------------
MODULE=jmx
# jetty.jmxrmihost=localhost
# jetty.jmxrmiport=1099
# -Dcom.sun.management.jmxremote
#===========================================================
# Java Server Pages
#-----------------------------------------------------------
MODULE=jsp
#===========================================================
# Request logger
# Will add a handler to log all HTTP requests to a standard
# request log format file.
#-----------------------------------------------------------
# MODULE=requestlog
# requestlog.retain=90
# requestlog.append=true
# requestlog.extended=true
#===========================================================
# stderr/stdout logging.
# The following configuration will redirect stderr and stdout
# to file which is rolled over daily.
#-----------------------------------------------------------
# MODULE=logging
# jetty.log.retain=90
#===========================================================
# Enable SetUID
# The default user and group is 'jetty' and if you are
# starting as root you must change the run privledged to true
#-----------------------------------------------------------
# MODULE=setuid
# jetty.startServerAsPrivileged=false
# jetty.username=jetty
# jetty.groupname=jetty
# jetty.umask=002
#===========================================================
# HTTP Connector
#-----------------------------------------------------------
MODULE=http
jetty.port=8080
http.timeout=30000
#===========================================================
# SSL Context
# Create the keystore and trust store for use by
# HTTPS and SPDY
#-----------------------------------------------------------
# jetty.keystore=etc/keystore
# jetty.keystore.password=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4
# jetty.keymanager.password=OBF:1u2u1wml1z7s1z7a1wnl1u2g
# jetty.truststore=etc/keystore
# jetty.truststore.password=OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4
# jetty.secure.port=8443
#===========================================================
# HTTPS Connector
# Must be used with jetty-ssl.xml
#-----------------------------------------------------------
MODULE=https
# jetty.https.port=8443
#===========================================================
# NPN Next Protocol Negotiation
#
# The SPDY and HTTP/2.0 connectors require NPN. The jar for
# NPN cannot be downloaded from eclipse. So the --download
# option is used to install the NPN jar if it does not already
# exist
#
#-----------------------------------------------------------
# --exec
# --download=http://repo1.maven.org/maven2/org/mortbay/jetty/npn/npn-boot/1.1.5.v20130313/npn-boot-1.1.5.v20130313.jar:lib/npn/npn-boot-1.1.5.v20130313.jar
# -Xbootclasspath/p:lib/npn/npn-boot-1.1.5.v20130313.jar
#===========================================================
# SPDY Connector
# Requires SSL Context and NPN from above
#-----------------------------------------------------------
# MODULE=spdy
# jetty.spdy.port=8443
#===========================================================
# Webapplication Deployer
#-----------------------------------------------------------
MODULE=deploy
# ===========================================================
# Enable JAAS
# -----------------------------------------------------------
# MODULE=jaas
# jaas.login.conf=etc/login.conf
# ===========================================================
# Enable JNDI
# -----------------------------------------------------------
# MODULE=jndi
# ===========================================================
# Enable additional webapp environment configurators
# -----------------------------------------------------------
# MODULE=plus
# ===========================================================
# Enable servlet 3.1 annotations
# -----------------------------------------------------------
# MODULE=annotations
#===========================================================
# Other server features
#-----------------------------------------------------------
# MODULE=debug
# MODULE=ipaccess
# MODULE=stats
#===========================================================
# Low resource managment
#-----------------------------------------------------------
# MODULE=lowresources
# lowresources.period=1050
# lowresources.lowResourcesIdleTimeout=200
# lowresources.monitorThreads=true
# lowresources.maxConnections=0
# lowresources.maxMemory=0
# lowresources.maxLowResourcesTime=5000
MODULES=webapp

View File

@ -0,0 +1,9 @@
#
# JAAS Feature
#
# JAAS jars
LIB=lib/jetty-jaas-${jetty.version}.jar
# JAAS configuration
etc/jetty-jaas.xml

View File

@ -0,0 +1,9 @@
#
# JMX Feature
#
# JMX jars (as defined in start.config)
LIB=lib/jetty-jmx-${jetty.version}.jar
# JMX configuration
etc/jetty-jmx.xml

View File

@ -14,6 +14,23 @@
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>config</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>

View File

@ -0,0 +1,9 @@
#
# JNDI Support
#
DEPEND=server
LIB=lib/jetty-jndi-${jetty.version}.jar
LIB=lib/jndi/*.jar

View File

@ -10,6 +10,25 @@
<url>http://www.eclipse.org/jetty</url>
<packaging>jar</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>config</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>

View File

@ -0,0 +1,8 @@
#
# Jetty Servlet Module
#
DEPEND=servlet
LIB=lib/jsp/*.jar

View File

@ -0,0 +1,10 @@
#
# Jetty Monitor module
#
DEPEND=server
DEPEND=client
LIB=lib/jetty-monitor-${jetty.version}.jar
etc/jetty-monitor.xml

View File

@ -14,6 +14,23 @@
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>config</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>

View File

@ -0,0 +1,7 @@
#
# Jetty Nosql module
#
DEPEND=webapp
LIB=lib/jetty-nosql-${jetty.version}.jar

View File

@ -0,0 +1,10 @@
#
# Jetty Overlay module
#
DEPEND=deploy
LIB=lib/jetty-overlay-deployer-${jetty.version}.jar
# Plus requires configuration
etc/jetty-overlay.xml

View File

@ -0,0 +1,12 @@
#
# Jetty Proxy module
#
DEPEND=server
DEPEND=security
DEPEND=jndi
LIB=lib/jetty-plus-${jetty.version}.jar
# Plus requires configuration
etc/jetty-plus.xml

View File

@ -0,0 +1,11 @@
#
# Jetty Proxy module
#
DEPEND=server
DEPEND=client
LIB=lib/jetty-proxy-${jetty.version}.jar
# Proxy requires configuration
etc/jetty-proxy.xml

View File

@ -0,0 +1,10 @@
#
# Jetty Rewrite module
#
DEPEND=server
LIB=lib/jetty-rewrite-${jetty.version}.jar
# Annotations needs annotations configuration
etc/jetty-rewrite.xml

View File

@ -0,0 +1,7 @@
#
# Jetty Security Module
#
DEPEND=server
LIB=lib/jetty-security-${jetty.version}.jar

View File

@ -0,0 +1,6 @@
#
# Base Module
#
LIB=lib/jetty-util-${jetty.version}.jar
LIB=lib/jetty-io-${jetty.version}.jar

View File

@ -0,0 +1,7 @@
#
# Debug module
#
DEPEND=server
etc/jetty-debug.xml

View File

@ -0,0 +1,7 @@
#
# Jetty HTTP Server
#
DEPEND=server
etc/jetty-http.xml

View File

@ -0,0 +1,8 @@
#
# Jetty HTTP Server
#
DEPEND=server
etc/jetty-ssl.xml
etc/jetty-https.xml

View File

@ -0,0 +1,7 @@
#
# IPAccess module
#
DEPEND=server
etc/jetty-ipaccess.xml

View File

@ -0,0 +1,7 @@
#
# Low Resources module
#
DEPEND=server
etc/jetty-lowresources.xml

View File

@ -0,0 +1,7 @@
#
# Request Log module
#
DEPEND=server
etc/jetty-requestlog.xml

View File

@ -0,0 +1,15 @@
#
# Base server
#
DEPEND=base
DEPEND=xml
LIB=lib/servlet-api-3.1.jar
LIB=lib/jetty-schemas-3.1.jar
LIB=lib/jetty-http-${jetty.version}.jar
LIB=lib/jetty-continuation-${jetty.version}.jar
LIB=lib/jetty-server-${jetty.version}.jar
# Annotations needs annotations configuration
etc/jetty.xml

View File

@ -0,0 +1,7 @@
#
# Stats module
#
DEPEND=server
etc/jetty-stats.xml

View File

@ -0,0 +1,7 @@
#
# Stats module
#
DEPEND=server
etc/jetty-xinetd.xml

View File

@ -0,0 +1,8 @@
#
# Jetty XML Configuration
#
DEPEND=base
LIB=lib/jetty-xml-${jetty.version}.jar

View File

@ -53,6 +53,23 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>config</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>

View File

@ -0,0 +1,7 @@
#
# Jetty Servlet Module
#
DEPEND=server
LIB=lib/jetty-servlet-${jetty.version}.jar

View File

@ -0,0 +1,7 @@
#
# Jetty Servlets Module
#
DEPEND=servlet
LIB=lib/jetty-servlets-${jetty.version}.jar

View File

@ -0,0 +1,7 @@
DEPEND=server
LIB=lib/spdy/*.jar
etc/jetty-ssl.xml
etc/jetty-spdy.xml

View File

@ -53,47 +53,7 @@ public class BaseHome
public BaseHome(File homeDir, File baseDir)
{
this.homeDir = homeDir;
this.baseDir = baseDir==null?homeDir:baseDir;
}
public void initialize(ArrayList<String> arguments)
{
Pattern jetty_home=Pattern.compile("(-D)?jetty.home=(.*)");
Pattern jetty_base=Pattern.compile("(-D)?jetty.base=(.*)");
for (String arg : arguments)
{
Matcher home_match=jetty_home.matcher(arg);
if (home_match.matches())
setHomeDir(new File(home_match.group(2)));
Matcher base_match=jetty_base.matcher(arg);
if (base_match.matches())
setBaseDir(new File(base_match.group(2)));
}
}
public boolean isBaseDifferent()
{
return homeDir.compareTo(baseDir) != 0;
}
public void setBaseDir(File dir)
{
this.baseDir = dir;
try
{
System.setProperty("jetty.base",dir.getCanonicalPath());
}
catch(IOException e)
{
e.printStackTrace();
}
}
public File getBaseDir()
{
return baseDir;
this.baseDir = baseDir == null?homeDir:baseDir;
}
public String getBase()
@ -105,6 +65,23 @@ public class BaseHome
return baseDir.getAbsolutePath();
}
public File getBaseDir()
{
return baseDir;
}
/**
* Create a file reference to some content in <code>"${jetty.base}"</code>
*
* @param path
* the path to reference
* @return the file reference
*/
public File getBaseFile(String path)
{
return new File(baseDir,FS.separators(path));
}
/**
* Get a specific file reference.
* <p>
@ -144,17 +121,9 @@ public class BaseHome
return new File(rpath);
}
public void setHomeDir(File dir)
public String getHome()
{
this.homeDir = dir;
try
{
System.setProperty("jetty.home",dir.getCanonicalPath());
}
catch(IOException e)
{
e.printStackTrace();
}
return homeDir.getAbsolutePath();
}
public File getHomeDir()
@ -162,9 +131,29 @@ public class BaseHome
return homeDir;
}
public String getHome()
public void initialize(StartArgs args)
{
return homeDir.getAbsolutePath();
Pattern jetty_home = Pattern.compile("(-D)?jetty.home=(.*)");
Pattern jetty_base = Pattern.compile("(-D)?jetty.base=(.*)");
for (String arg : args.getCommandLine())
{
Matcher home_match = jetty_home.matcher(arg);
if (home_match.matches())
{
setHomeDir(new File(home_match.group(2)));
}
Matcher base_match = jetty_base.matcher(arg);
if (base_match.matches())
{
setBaseDir(new File(base_match.group(2)));
}
}
}
public boolean isBaseDifferent()
{
return homeDir.compareTo(baseDir) != 0;
}
/**
@ -200,26 +189,32 @@ public class BaseHome
File homePath = new File(homeDir,FS.separators(relPathToDirectory));
List<File> homeFiles = new ArrayList<>();
homeFiles.addAll(Arrays.asList(homePath.listFiles(filter)));
if (FS.canReadDirectory(homePath))
{
homeFiles.addAll(Arrays.asList(homePath.listFiles(filter)));
}
if (isBaseDifferent())
{
// merge
File basePath = new File(baseDir,FS.separators(relPathToDirectory));
File baseFiles[] = basePath.listFiles(filter);
List<File> ret = new ArrayList<>();
if (baseFiles!=null)
if (FS.canReadDirectory(basePath))
{
for (File base : baseFiles)
File baseFiles[] = basePath.listFiles(filter);
if (baseFiles != null)
{
String relpath = toRelativePath(baseDir,base);
File home = new File(homeDir,FS.separators(relpath));
if (home.exists())
for (File base : baseFiles)
{
homeFiles.remove(home);
String relpath = toRelativePath(baseDir,base);
File home = new File(homeDir,FS.separators(relpath));
if (home.exists())
{
homeFiles.remove(home);
}
ret.add(base);
}
ret.add(base);
}
}
@ -262,6 +257,32 @@ public class BaseHome
return ret;
}
public void setBaseDir(File dir)
{
try
{
this.baseDir = dir.getCanonicalFile();
System.setProperty("jetty.base",dir.getCanonicalPath());
}
catch (IOException e)
{
e.printStackTrace(System.err);
}
}
public void setHomeDir(File dir)
{
try
{
this.homeDir = dir.getCanonicalFile();
System.setProperty("jetty.home",dir.getCanonicalPath());
}
catch (IOException e)
{
e.printStackTrace(System.err);
}
}
private String toRelativePath(File dir, File path)
{
return dir.toURI().relativize(path.toURI()).toASCIIString();
@ -296,7 +317,7 @@ public class BaseHome
{
return path;
}
String value;
if (isBaseDifferent())

View File

@ -24,16 +24,31 @@ import java.io.PrintStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;
import java.util.Vector;
/**
* Class to handle CLASSPATH construction
*/
public class Classpath
public class Classpath implements Iterable<File>
{
private static class Loader extends URLClassLoader
{
Loader(URL[] urls, ClassLoader parent)
{
super(urls,parent);
}
private final Vector<File> _elements = new Vector<File>();
@Override
public String toString()
{
return "startJarLoader@" + Long.toHexString(hashCode());
}
}
private final List<File> elements = new ArrayList<File>();
public Classpath()
{
@ -44,69 +59,12 @@ public class Classpath
addClasspath(initial);
}
public File[] getElements()
{
return _elements.toArray(new File[_elements.size()]);
}
public int count()
{
return _elements.size();
}
public boolean addComponent(String component)
{
if ((component != null) && (component.length() > 0))
{
try
{
File f = new File(component);
if (f.exists())
{
File key = f.getCanonicalFile();
if (!_elements.contains(key))
{
_elements.add(key);
return true;
}
}
}
catch (IOException e)
{
}
}
return false;
}
public boolean addComponent(File component)
{
if (component != null)
{
try
{
if (component.exists())
{
File key = component.getCanonicalFile();
if (!_elements.contains(key))
{
_elements.add(key);
return true;
}
}
}
catch (IOException e)
{
}
}
return false;
}
public boolean addClasspath(String s)
{
boolean added = false;
if (s != null)
{
StringTokenizer t = new StringTokenizer(s, File.pathSeparator);
StringTokenizer t = new StringTokenizer(s,File.pathSeparator);
while (t.hasMoreTokens())
{
added |= addComponent(t.nextToken());
@ -115,46 +73,73 @@ public class Classpath
return added;
}
public boolean addComponent(File path)
{
if ((path == null) || (!path.exists()))
{
// not a valid component
return false;
}
try
{
File key = path.getCanonicalFile();
if (!elements.contains(key))
{
elements.add(key);
return true;
}
}
catch (IOException e)
{
StartLog.debug(e);
}
return false;
}
public boolean addComponent(String component)
{
if ((component == null) || (component.length() <= 0))
{
// nothing to add
return false;
}
return addComponent(new File(component));
}
public int count()
{
return elements.size();
}
public void dump(PrintStream out)
{
int i = 0;
for (File element : _elements)
for (File element : elements)
{
out.printf("%2d: %s\n", i++, element.getAbsolutePath());
out.printf("%2d: %s%n",i++,element.getAbsolutePath());
}
}
@Override
public String toString()
{
StringBuffer cp = new StringBuffer(1024);
int cnt = _elements.size();
if (cnt >= 1)
{
cp.append(((_elements.elementAt(0))).getPath());
}
for (int i = 1; i < cnt; i++)
{
cp.append(File.pathSeparatorChar);
cp.append(((_elements.elementAt(i))).getPath());
}
return cp.toString();
}
public ClassLoader getClassLoader()
{
int cnt = _elements.size();
int cnt = elements.size();
URL[] urls = new URL[cnt];
for (int i = 0; i < cnt; i++)
{
try
{
urls[i] = _elements.elementAt(i).toURI().toURL();
urls[i] = elements.get(i).toURI().toURL();
StartLog.debug("URLClassLoader.url[%d] = %s",i,urls[i]);
}
catch (MalformedURLException e)
{
StartLog.warn(e);
}
}
StartLog.debug("Loaded %d URLs into URLClassLoader",urls.length);
ClassLoader parent = Thread.currentThread().getContextClassLoader();
if (parent == null)
@ -165,46 +150,58 @@ public class Classpath
{
parent = ClassLoader.getSystemClassLoader();
}
return new Loader(urls, parent);
return new Loader(urls,parent);
}
private static class Loader extends URLClassLoader
public List<File> getElements()
{
Loader(URL[] urls, ClassLoader parent)
{
super(urls, parent);
}
@Override
public String toString()
{
return "startJarLoader@" + Long.toHexString(hashCode());
}
}
/**
* Overlay another classpath, copying its elements into place on this
* Classpath, while eliminating duplicate entries on the classpath.
*
* @param cpOther the other classpath to overlay
*/
public void overlay(Classpath cpOther)
{
for (File otherElement : cpOther._elements)
{
if (this._elements.contains(otherElement))
{
// Skip duplicate entries
continue;
}
this._elements.add(otherElement);
}
return elements;
}
public boolean isEmpty()
{
return (_elements == null) || (_elements.isEmpty());
return (elements == null) || (elements.isEmpty());
}
@Override
public Iterator<File> iterator()
{
return elements.iterator();
}
/**
* Overlay another classpath, copying its elements into place on this Classpath, while eliminating duplicate entries on the classpath.
*
* @param other
* the other classpath to overlay
*/
public void overlay(Classpath other)
{
for (File otherElement : other.elements)
{
if (this.elements.contains(otherElement))
{
// Skip duplicate entries
continue;
}
this.elements.add(otherElement);
}
}
@Override
public String toString()
{
StringBuffer cp = new StringBuffer(1024);
boolean needDelim = false;
for (File element : elements)
{
if (needDelim)
{
cp.append(File.pathSeparatorChar);
}
cp.append(element.getAbsolutePath());
needDelim = true;
}
return cp.toString();
}
}

View File

@ -18,16 +18,92 @@
package org.eclipse.jetty.start;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class CommandLineBuilder
{
public static File findExecutable(File root, String path)
{
String npath = path.replace('/',File.separatorChar);
File exe = new File(root,npath);
if (!exe.exists())
{
return null;
}
return exe;
}
public static String findJavaBin()
{
File javaHome = new File(System.getProperty("java.home"));
if (!javaHome.exists())
{
return null;
}
File javabin = findExecutable(javaHome,"bin/java");
if (javabin != null)
{
return javabin.getAbsolutePath();
}
javabin = findExecutable(javaHome,"bin/java.exe");
if (javabin != null)
{
return javabin.getAbsolutePath();
}
return "java";
}
/**
* Perform an optional quoting of the argument, being intelligent with spaces and quotes as needed. If a subString is set in quotes it won't the subString
* won't be escaped.
*
* @param arg
* @return
*/
public static String quote(String arg)
{
boolean needsQuoting = (arg.indexOf(' ') >= 0) || (arg.indexOf('"') >= 0);
if (!needsQuoting)
{
return arg;
}
StringBuilder buf = new StringBuilder();
// buf.append('"');
boolean escaped = false;
boolean quoted = false;
for (char c : arg.toCharArray())
{
if (!quoted && !escaped && ((c == '"') || (c == ' ')))
{
buf.append("\\");
}
// don't quote text in single quotes
if (!escaped && (c == '\''))
{
quoted = !quoted;
}
escaped = (c == '\\');
buf.append(c);
}
// buf.append('"');
return buf.toString();
}
private List<String> args;
public CommandLineBuilder()
{
args = new ArrayList<String>();
}
public CommandLineBuilder(String bin)
{
args = new ArrayList<String>();
this();
args.add(bin);
}
@ -42,7 +118,9 @@ public class CommandLineBuilder
public void addArg(String arg)
{
if (arg != null)
{
args.add(quote(arg));
}
}
/**
@ -65,7 +143,7 @@ public class CommandLineBuilder
*/
public void addEqualsArg(String name, String value)
{
if (value != null && value.length() > 0)
if ((value != null) && (value.length() > 0))
{
args.add(quote(name + "=" + value));
}
@ -86,7 +164,9 @@ public class CommandLineBuilder
public void addRawArg(String arg)
{
if (arg != null)
{
args.add(arg);
}
}
public List<String> getArgs()
@ -94,42 +174,6 @@ public class CommandLineBuilder
return args;
}
/**
* Perform an optional quoting of the argument, being intelligent with spaces and quotes as needed. If a
* subString is set in quotes it won't the subString won't be escaped.
*
* @param arg
* @return
*/
public static String quote(String arg)
{
boolean needsQuoting = arg.indexOf(' ') >= 0 || arg.indexOf('"') >= 0;
if (!needsQuoting)
{
return arg;
}
StringBuilder buf = new StringBuilder();
// buf.append('"');
boolean escaped = false;
boolean quoted = false;
for (char c : arg.toCharArray())
{
if (!quoted && !escaped && ((c == '"') || (c == ' ')))
{
buf.append("\\");
}
// don't quote text in single quotes
if (!escaped && c == '\'')
{
quoted = !quoted;
}
escaped = (c == '\\');
buf.append(c);
}
// buf.append('"');
return buf.toString();
}
@Override
public String toString()
{

View File

@ -1,990 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2013 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.start;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;
/**
* <p>
* It allows an application to be started with the command <code>"java -jar start.jar"</code>.
* </p>
*
* <p>
* The behaviour of Main is controlled by the <code>"org/eclipse/start/start.config"</code> file obtained as a resource or file. This can be overridden with the
* START system property. The format of each line in this file is:
* </p>
*
* <p>
* Each line contains entry in the format:
* </p>
*
* <pre>
* SUBJECT [ [!] CONDITION [AND|OR] ]*
* </pre>
*
* <p>
* where SUBJECT:
* </p>
* <ul>
* <li>ends with <code>".class"</code> is the Main class to run.</li>
* <li>ends with <code>".xml"</code> is a configuration file for the command line</li>
* <li>ends with <code>"/"</code> is a directory from which to add all jar and zip files.</li>
* <li>ends with <code>"/*"</code> is a directory from which to add all unconsidered jar and zip files.</li>
* <li>ends with <code>"/**"</code> is a directory from which to recursively add all unconsidered jar and zip files.</li>
* <li>Containing <code>=</code> are used to assign system properties.</li>
* <li>Containing <code>~=</code> are used to assign start properties.</li>
* <li>Containing <code>/=</code> are used to assign a canonical path.</li>
* <li>all other subjects are treated as files to be added to the classpath.</li>
* </ul>
*
* <p>
* property expansion:
* </p>
* <ul>
* <li><code>${name}</code> is expanded to a start property</li>
* <li><code>$(name)</code> is expanded to either a start property or a system property.</li>
* <li>The start property <code>${version}</code> is defined as the version of the start.jar</li>
* </ul>
*
* <p>
* Files starting with <code>"/"</code> are considered absolute, all others are relative to the home directory.
* </p>
*
* <p>
* CONDITION is one of:
* </p>
* <ul>
* <li><code>always</code></li>
* <li><code>never</code></li>
* <li><code>available classname</code> - true if class on classpath</li>
* <li><code>property name</code> - true if set as start property</li>
* <li><code>system name</code> - true if set as system property</li>
* <li><code>exists file</code> - true if file/dir exists</li>
* <li><code>java OPERATOR version</code> - java version compared to literal</li>
* <li><code>nargs OPERATOR number</code> - number of command line args compared to literal</li>
* <li>OPERATOR := one of <code>"&lt;"</code>,<code>"&gt;"</code>,<code>"&lt;="</code>,<code>"&gt;="</code>, <code>"=="</code>,<code>"!="</code></li>
* </ul>
*
* <p>
* CONDITIONS can be combined with <code>AND</code> <code>OR</code> or <code>!</code>, with <code>AND</code> being the assume operator for a list of CONDITIONS.
* </p>
*
* <p>
* Classpath operations are evaluated on the fly, so once a class or jar is added to the classpath, subsequent available conditions will see that class.
* </p>
*
* <p>
* The configuration file may be divided into sections with option names like: [ssl,default]
* </p>
*
* <p>
* Note: a special discovered section identifier <code>[=path_to_directory/*]</code> is allowed to auto-create section IDs, based on directory names found in
* the path specified in the "path_to_directory/" part of the identifier.
* </p>
*
* <p>
* Clauses after a section header will only be included if they match one of the tags in the options property. By default options are set to "default,*" or the
* OPTIONS property may be used to pass in a list of tags, eg. :
* </p>
*
* <pre>
* java -jar start.jar OPTIONS=jetty,jsp,ssl
* </pre>
*
* <p>
* The tag '*' is always appended to the options, so any section with the * tag is always applied.
* </p>
*
* <p>
* The property map maintained by this class is static and shared between all instances in the same classloader
* </p>
*/
public class Config
{
public static final String DEFAULT_SECTION = "";
static
{
String ver = System.getProperty("jetty.version",null);
if (ver == null)
{
Package pkg = Config.class.getPackage();
if (pkg != null && "Eclipse.org - Jetty".equals(pkg.getImplementationVendor()) && (pkg.getImplementationVersion() != null))
{
ver = pkg.getImplementationVersion();
}
}
if (ver == null)
{
ver = "Unknown";
}
__version = ver;
}
/**
* Natural language sorting for key names.
*/
private final Comparator<String> keySorter = new NaturalSort.Strings();
private static final String __version;
private static boolean DEBUG = false;
private static Config __instance;
private final BaseHome _homebase;
private final Map<String, String> _properties = new HashMap<String, String>();
private final Map<String, Classpath> _classpaths = new HashMap<String, Classpath>();
private final List<String> _xml = new ArrayList<String>();
private String _classname = null;
private int argCount = 0;
private final Set<String> _options = new TreeSet<String>(new Comparator<String>()
{
// Make sure "*" is always at the end of the list
public int compare(String o1, String o2)
{
if ("*".equals(o1))
{
return 1;
}
if ("*".equals(o2))
{
return -1;
}
return o1.compareTo(o2);
}
});
public Config()
{
__instance = this;
_homebase = new BaseHome();
setProperty("jetty.home",_homebase.getHome());
setProperty("jetty.base",_homebase.getBase());
}
public BaseHome getBaseHome()
{
return _homebase;
}
public Classpath defineOption(String option)
{
Classpath cp = _classpaths.get(option);
if (cp == null)
{
cp = new Classpath();
_classpaths.put(option,cp);
}
return cp;
}
private boolean addClasspathComponent(List<String> sections, String component)
{
for (String section : sections)
{
Classpath cp = defineOption(section);
boolean added = cp.addComponent(component);
if (!added)
{
// First failure means all failed.
return false;
}
}
return true;
}
private boolean addClasspathPath(List<String> sections, String path)
{
for (String section : sections)
{
Classpath cp = _classpaths.get(section);
if (!cp.addClasspath(path))
{
// First failure means all failed.
return false;
}
_classpaths.put(section,cp);
}
return true;
}
private void addJars(List<String> sections, File dir, boolean recurse) throws IOException
{
List<File> entries = new ArrayList<File>();
File[] files = dir.listFiles();
if (files == null)
{
// No files found, skip it.
return;
}
entries.addAll(Arrays.asList(files));
Collections.sort(entries,FilenameComparator.INSTANCE);
for (File entry : entries)
{
if (entry.isDirectory())
{
if (recurse)
addJars(sections,entry,recurse);
}
else
{
String name = entry.getName().toLowerCase(Locale.ENGLISH);
if (name.endsWith(".jar") || name.endsWith(".zip"))
{
String jar = entry.getCanonicalPath();
boolean added = addClasspathComponent(sections,jar);
debug((added?" CLASSPATH+=":" !") + jar);
}
}
}
}
public static boolean isDebug()
{
return DEBUG;
}
public static void debug(String msg)
{
if (DEBUG)
{
System.err.println(msg);
}
}
public static void debug(String format, Object... args)
{
if (DEBUG)
{
System.err.printf(format + "%n",args);
}
}
public static void debug(Throwable t)
{
if (DEBUG)
{
t.printStackTrace(System.err);
}
}
private String expand(String s)
{
int i1 = 0;
int i2 = 0;
while (s != null)
{
i1 = s.indexOf("$(",i2);
if (i1 < 0)
break;
i2 = s.indexOf(")",i1 + 2);
if (i2 < 0)
break;
String name = s.substring(i1 + 2,i2);
String property = getProperty(name);
s = s.substring(0,i1) + property + s.substring(i2 + 1);
}
i1 = 0;
i2 = 0;
while (s != null)
{
i1 = s.indexOf("${",i2);
if (i1 < 0)
break;
i2 = s.indexOf("}",i1 + 2);
if (i2 < 0)
break;
String name = s.substring(i1 + 2,i2);
String property = getProperty(name);
s = s.substring(0,i1) + property + s.substring(i2 + 1);
}
return s;
}
/**
* Get the default classpath.
*
* @return the default classpath
*/
public Classpath getClasspath()
{
return _classpaths.get(DEFAULT_SECTION);
}
/**
* Get the active classpath, as dictated by OPTIONS= entries.
*
* @return the Active classpath
* @see #getCombinedClasspath(Collection)
*/
public Classpath getActiveClasspath()
{
return getCombinedClasspath(_options);
}
/**
* Get the combined classpath representing the default classpath plus all named sections.
*
* NOTE: the default classpath will be prepended, and the '*' classpath will be appended.
*
* @param optionIds
* the list of section ids to fetch
* @return the {@link Classpath} representing combination all of the selected sectionIds, combined with the default section id, and '*' special id.
*/
public Classpath getCombinedClasspath(Collection<String> optionIds)
{
Classpath cp = new Classpath();
cp.overlay(_classpaths.get(DEFAULT_SECTION));
for (String optionId : optionIds)
{
Classpath otherCp = _classpaths.get(optionId);
if (otherCp == null)
{
throw new IllegalArgumentException("No such OPTION: " + optionId);
}
cp.overlay(otherCp);
}
cp.overlay(_classpaths.get("*"));
return cp;
}
public String getMainClassname()
{
return _classname;
}
public void clearProperties()
{
_properties.clear();
}
/* This method is static so it can be accessed by XmlConfiguration */
public static Properties getProperties()
{
Properties properties = new Properties();
// Add System Properties First
Enumeration<?> ensysprop = System.getProperties().propertyNames();
while (ensysprop.hasMoreElements())
{
String name = (String)ensysprop.nextElement();
properties.put(name,System.getProperty(name));
}
// Add Config Properties Next (overwriting any System Properties that exist)
for (String key : __instance._properties.keySet())
{
properties.put(key,__instance._properties.get(key));
}
return properties;
}
public String getProperty(String name)
{
if ("version".equalsIgnoreCase(name))
{
return __version;
}
// Search Config Properties First
if (_properties.containsKey(name))
{
return _properties.get(name);
}
// Return what exists in System.Properties otherwise.
return System.getProperty(name);
}
public String getProperty(String name, String defaultValue)
{
// Search Config Properties First
if (_properties.containsKey(name))
return _properties.get(name);
// Return what exists in System.Properties otherwise.
return System.getProperty(name,defaultValue);
}
/**
* Get the classpath for the named section
*
* @param sectionId
* @return the classpath for the specified section id
*/
public Classpath getSectionClasspath(String sectionId)
{
return _classpaths.get(sectionId);
}
/**
* Get the list of section Ids.
*
* @return the set of unique section ids
*/
public Set<String> getSectionIds()
{
Set<String> ids = new TreeSet<String>(keySorter);
ids.addAll(_classpaths.keySet());
return ids;
}
public List<String> getXmlConfigs()
{
return _xml;
}
private boolean isAvailable(List<String> options, String classname)
{
// Try default/parent class loader first.
try
{
Class.forName(classname);
return true;
}
catch (NoClassDefFoundError e)
{
debug(e);
}
catch (ClassNotFoundException e)
{
debug("ClassNotFoundException (parent class loader): " + classname);
}
// Try option classloaders instead
ClassLoader loader;
Classpath classpath;
for (String optionId : options)
{
classpath = _classpaths.get(optionId);
if (classpath == null)
{
// skip, no classpath
continue;
}
loader = classpath.getClassLoader();
try
{
loader.loadClass(classname);
return true;
}
catch (NoClassDefFoundError e)
{
debug(e);
}
catch (ClassNotFoundException e)
{
debug("ClassNotFoundException (section class loader: " + optionId + "): " + classname);
}
}
return false;
}
/**
* Parse the configuration
*
* @param buf
* @throws IOException
*/
public void parse(CharSequence buf) throws IOException
{
try (StringReader reader = new StringReader(buf.toString()))
{
parse(reader);
}
}
/**
* Parse the configuration
*
* @param stream
* the stream to read from
* @throws IOException
*/
public void parse(InputStream stream) throws IOException
{
try (InputStreamReader reader = new InputStreamReader(stream))
{
parse(reader);
}
}
/**
*/
public void parse(Reader reader) throws IOException
{
try (BufferedReader buf = new BufferedReader(reader))
{
List<String> options = new ArrayList<String>();
options.add(DEFAULT_SECTION);
_classpaths.put(DEFAULT_SECTION,new Classpath());
Version java_version = new Version(System.getProperty("java.version"));
Version ver = new Version();
String line = null;
while ((line = buf.readLine()) != null)
{
String trim = line.trim();
if (trim.length() == 0) // empty line
continue;
if (trim.startsWith("#")) // comment
continue;
// handle options
if (trim.startsWith("[") && trim.endsWith("]"))
{
String identifier = trim.substring(1,trim.length() - 1);
// Normal case: section identifier (possibly separated by commas)
options = Arrays.asList(identifier.split(","));
List<String> option_ids = new ArrayList<String>();
// Ensure section classpaths exist
for (String optionId : options)
{
if (optionId.charAt(0) == '=')
continue;
if (!_classpaths.containsKey(optionId))
_classpaths.put(optionId,new Classpath());
if (!option_ids.contains(optionId))
option_ids.add(optionId);
}
// Process Dynamic
for (String optionId : options)
{
if (optionId.charAt(0) != '=')
continue;
option_ids = processDynamicSectionIdentifier(optionId.substring(1),option_ids);
}
options = option_ids;
continue;
}
try
{
StringTokenizer st = new StringTokenizer(line);
String subject = st.nextToken();
boolean expression = true;
boolean not = false;
String condition = null;
// Evaluate all conditions
while (st.hasMoreTokens())
{
condition = st.nextToken();
if (condition.equalsIgnoreCase("!"))
{
not = true;
continue;
}
if (condition.equalsIgnoreCase("OR"))
{
if (expression)
break;
expression = true;
continue;
}
if (condition.equalsIgnoreCase("AND"))
{
if (!expression)
break;
continue;
}
boolean eval = true;
if (condition.equals("true") || condition.equals("always"))
{
eval = true;
}
else if (condition.equals("false") || condition.equals("never"))
{
eval = false;
}
else if (condition.equals("available"))
{
String class_to_check = st.nextToken();
eval = isAvailable(options,class_to_check);
}
else if (condition.equals("exists"))
{
try
{
eval = false;
File file = new File(expand(st.nextToken()));
eval = file.exists();
}
catch (Exception e)
{
debug(e);
}
}
else if (condition.equals("property"))
{
String property = getProperty(st.nextToken());
eval = property != null && property.length() > 0;
}
else if (condition.equals("system"))
{
String property = System.getProperty(st.nextToken());
eval = property != null && property.length() > 0;
}
else if (condition.equals("java"))
{
String operator = st.nextToken();
String version = st.nextToken();
ver.parse(version);
eval = (operator.equals("<") && java_version.compare(ver) < 0) || (operator.equals(">") && java_version.compare(ver) > 0)
|| (operator.equals("<=") && java_version.compare(ver) <= 0) || (operator.equals("=<") && java_version.compare(ver) <= 0)
|| (operator.equals("=>") && java_version.compare(ver) >= 0) || (operator.equals(">=") && java_version.compare(ver) >= 0)
|| (operator.equals("==") && java_version.compare(ver) == 0) || (operator.equals("!=") && java_version.compare(ver) != 0);
}
else if (condition.equals("nargs"))
{
String operator = st.nextToken();
int number = Integer.parseInt(st.nextToken());
eval = (operator.equals("<") && argCount < number) || (operator.equals(">") && argCount > number)
|| (operator.equals("<=") && argCount <= number) || (operator.equals("=<") && argCount <= number)
|| (operator.equals("=>") && argCount >= number) || (operator.equals(">=") && argCount >= number)
|| (operator.equals("==") && argCount == number) || (operator.equals("!=") && argCount != number);
}
else
{
System.err.println("ERROR: Unknown condition: " + condition);
eval = false;
}
expression &= not?!eval:eval;
not = false;
}
String file = expand(subject);
debug((expression?"T ":"F ") + line);
if (!expression)
continue;
// Setting of a start property
if (subject.indexOf("~=") > 0)
{
int i = file.indexOf("~=");
String property = file.substring(0,i);
String value = fixPath(file.substring(i + 2));
debug(" " + property + "~=" + value);
setProperty(property,value);
continue;
}
// Setting of start property with canonical path
if (subject.indexOf("/=") > 0)
{
int i = file.indexOf("/=");
String property = file.substring(0,i);
String value = fixPath(file.substring(i + 2));
String canonical = new File(value).getCanonicalPath();
debug(" " + property + "/=" + value + "==" + canonical);
setProperty(property,canonical);
continue;
}
// Setting of system property
if (subject.indexOf("=") > 0)
{
int i = file.indexOf("=");
String property = file.substring(0,i);
String value = fixPath(file.substring(i + 1));
debug(" " + property + "=" + value);
System.setProperty(property,value);
continue;
}
// Add all unconsidered JAR and ZIP files to classpath
if (subject.endsWith("/*"))
{
// directory of JAR files - only add jars and zips within the directory
File dir = new File(fixPath(file.substring(0,file.length() - 1)));
addJars(options,dir,false);
continue;
}
// Recursively add all unconsidered JAR and ZIP files to classpath
if (subject.endsWith("/**"))
{
// directory hierarchy of jar files - recursively add all jars and zips in the hierarchy
File dir = new File(fixPath(file.substring(0,file.length() - 2)));
addJars(options,dir,true);
continue;
}
// Add raw classpath directory to classpath
if (subject.endsWith("/"))
{
// class directory
File cd = new File(fixPath(file));
String d = cd.getCanonicalPath();
boolean added = addClasspathComponent(options,d);
debug((added?" CLASSPATH+=":" !") + d);
continue;
}
// Add XML configuration
if (subject.toLowerCase(Locale.ENGLISH).endsWith(".xml"))
{
// Config file
File f = new File(fixPath(file));
if (f.exists())
_xml.add(f.getCanonicalPath());
debug(" ARGS+=" + f);
continue;
}
// Set the main class to execute (overrides any previously set)
if (subject.toLowerCase(Locale.ENGLISH).endsWith(".class"))
{
// Class
String cn = expand(subject.substring(0,subject.length() - 6));
if (cn != null && cn.length() > 0)
{
debug(" CLASS=" + cn);
_classname = cn;
}
continue;
}
// Add raw classpath entry
if (subject.toLowerCase(Locale.ENGLISH).endsWith(".path"))
{
// classpath (jetty.class.path?) to add to runtime classpath
String cn = expand(subject.substring(0,subject.length() - 5));
if (cn != null && cn.length() > 0)
{
debug(" PATH=" + cn);
addClasspathPath(options,cn);
}
continue;
}
// single JAR file
File f = new File(fixPath(file));
if (f.exists())
{
String d = f.getCanonicalPath();
boolean added = addClasspathComponent(options,d);
if (!added)
{
added = addClasspathPath(options,expand(subject));
}
debug((added?" CLASSPATH+=":" !") + d);
}
}
catch (Exception e)
{
System.err.println("on line: '" + line + "'");
e.printStackTrace();
}
}
}
}
private List<String> processDynamicSectionIdentifier(String dynamicPathId, List<String> sections) throws IOException
{
String rawPath;
boolean deep;
if (dynamicPathId.endsWith("/*"))
{
deep = false;
rawPath = fixPath(dynamicPathId.substring(0,dynamicPathId.length() - 1));
}
else if (dynamicPathId.endsWith("/**"))
{
deep = true;
rawPath = fixPath(dynamicPathId.substring(0,dynamicPathId.length() - 2));
}
else
{
String msg = "Illegal dynamic path [" + dynamicPathId + "]";
throw new IOException(msg);
}
File parentDir = new File(expand(rawPath));
if (!parentDir.exists())
return sections;
debug("dynamic: " + parentDir);
File dirs[] = parentDir.listFiles(new FileFilter()
{
public boolean accept(File path)
{
return path.isDirectory();
}
});
List<String> dyn_sections = new ArrayList<String>();
List<String> super_sections = new ArrayList<String>();
if (sections != null)
super_sections.addAll(sections);
for (File dir : dirs)
{
String id = dir.getName();
if (!_classpaths.keySet().contains(id))
_classpaths.put(id,new Classpath());
dyn_sections.clear();
if (sections != null)
dyn_sections.addAll(sections);
dyn_sections.add(id);
super_sections.add(id);
debug("dynamic: " + dyn_sections);
addJars(dyn_sections,dir,deep);
}
return super_sections;
}
private String fixPath(String path)
{
return path.replace('/',File.separatorChar);
}
public void parse(URL url) throws IOException
{
InputStream stream = null;
InputStreamReader reader = null;
try
{
stream = url.openStream();
reader = new InputStreamReader(stream);
parse(reader);
}
finally
{
FS.close(reader);
FS.close(stream);
}
}
public void setArgCount(int argCount)
{
this.argCount = argCount;
}
public void setProperty(String name, String value)
{
if (name.equals("DEBUG"))
{
DEBUG = Boolean.parseBoolean(value);
if (DEBUG)
{
System.setProperty("org.eclipse.jetty.util.log.stderr.DEBUG","true");
System.setProperty("org.eclipse.jetty.start.DEBUG","true");
}
}
if (name.equals("OPTIONS"))
{
_options.clear();
String ids[] = value.split(",");
for (String id : ids)
addOption(id);
}
if (name.equals("jetty.base"))
{
File base = new File(value);
try
{
value = base.getCanonicalPath();
}
catch (Exception e)
{
e.printStackTrace();
}
}
_properties.put(name,value);
}
public void addOption(String option)
{
_options.add(option);
_properties.put("OPTIONS",join(_options,","));
}
public Set<String> getKnownOptions()
{
return _classpaths.keySet();
}
public Set<String> getOptions()
{
return _options;
}
public void removeOption(String option)
{
_options.remove(option);
_properties.put("OPTIONS",join(_options,","));
}
private String join(Collection<?> coll, String delim)
{
StringBuffer buf = new StringBuffer();
Iterator<?> i = coll.iterator();
boolean hasNext = i.hasNext();
while (hasNext)
{
buf.append(String.valueOf(i.next()));
hasNext = i.hasNext();
if (hasNext)
buf.append(delim);
}
return buf.toString();
}
}

View File

@ -38,6 +38,22 @@ public class FS
}
}
public static class FilenameRegexFilter implements FileFilter
{
private final Pattern pattern;
public FilenameRegexFilter(String regex)
{
pattern = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
}
@Override
public boolean accept(File path)
{
return path.isFile() && pattern.matcher(path.getName()).matches();
}
}
public static class FileNamesFilter implements FileFilter
{
private final String filenames[];
@ -65,22 +81,6 @@ public class FS
}
}
public static class FilenameRegexFilter implements FileFilter
{
private final Pattern pattern;
public FilenameRegexFilter(String regex)
{
pattern = Pattern.compile(regex,Pattern.CASE_INSENSITIVE);
}
@Override
public boolean accept(File path)
{
return path.isFile() && pattern.matcher(path.getName()).matches();
}
}
public static class IniFilter extends FilenameRegexFilter
{
public IniFilter()
@ -97,10 +97,22 @@ public class FS
}
}
public static boolean canReadDirectory(File path)
{
return (path.exists() && path.isDirectory() && path.canRead());
}
public static boolean canReadFile(File path)
{
return (path.exists() && path.isFile() && path.canRead());
}
public static void close(Closeable c)
{
if (c == null)
{
return;
}
try
{

View File

@ -1,70 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2013 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.start;
import java.io.File;
import java.text.CollationKey;
import java.text.Collator;
import java.util.Comparator;
/**
* Smart comparator for filenames, with natural language sorting, and files sorted before sub directories.
*/
public class FilenameComparator implements Comparator<File>
{
public static final FilenameComparator INSTANCE = new FilenameComparator();
private Collator collator = Collator.getInstance();
public int compare(File o1, File o2)
{
if (o1.isFile())
{
if (o2.isFile())
{
CollationKey key1 = toKey(o1);
CollationKey key2 = toKey(o2);
return key1.compareTo(key2);
}
else
{
// Push o2 directories below o1 files
return -1;
}
}
else
{
if (o2.isDirectory())
{
CollationKey key1 = toKey(o1);
CollationKey key2 = toKey(o2);
return key1.compareTo(key2);
}
else
{
// Push o2 files above o1 directories
return 1;
}
}
}
private CollationKey toKey(File f)
{
return collator.getCollationKey(f.getAbsolutePath());
}
}

View File

@ -50,7 +50,7 @@ public class JarVersion
return entry;
}
}
return null;
}
@ -58,11 +58,15 @@ public class JarVersion
{
Attributes attribs = manifest.getMainAttributes();
if (attribs == null)
{
return null;
}
String version = attribs.getValue("Bundle-Version");
if (version == null)
{
return null;
}
return stripV(version);
}
@ -71,11 +75,15 @@ public class JarVersion
{
Attributes attribs = manifest.getMainAttributes();
if (attribs == null)
{
return null;
}
String version = attribs.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
if (version == null)
{
return null;
}
return stripV(version);
}
@ -84,19 +92,23 @@ public class JarVersion
{
JarEntry pomProp = findEntry(jar,"META-INF/maven/.*/pom\\.properties$");
if (pomProp == null)
{
return null;
}
InputStream stream = null;
try
{
stream = jar.getInputStream(pomProp);
Properties props = new Properties();
props.load(stream);
String version = props.getProperty("version");
if (version == null)
{
return null;
}
return stripV(version);
}
@ -109,15 +121,19 @@ public class JarVersion
private static String getSubManifestImplVersion(Manifest manifest)
{
Map<String, Attributes> entries = manifest.getEntries();
for (Attributes attribs : entries.values())
{
if (attribs == null)
{
continue; // skip entry
}
String version = attribs.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
if (version == null)
{
continue; // empty, no value, skip it
}
return stripV(version);
}
@ -127,28 +143,36 @@ public class JarVersion
public static String getVersion(File file)
{
try(JarFile jar = new JarFile(file))
try (JarFile jar = new JarFile(file))
{
String version = null;
Manifest manifest = jar.getManifest();
version = getMainManifestImplVersion(manifest);
if (version != null)
{
return version;
}
version = getSubManifestImplVersion(manifest);
if (version != null)
{
return version;
}
version = getBundleVersion(manifest);
if (version != null)
{
return version;
}
version = getMavenVersion(jar);
if (version != null)
{
return version;
}
return "(not specified)";
}
catch (IOException e)
@ -160,7 +184,9 @@ public class JarVersion
private static String stripV(String version)
{
if (version.charAt(0) == 'v')
{
return version.substring(1);
}
return version;
}

File diff suppressed because it is too large Load Diff

View File

@ -18,9 +18,8 @@
package org.eclipse.jetty.start;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.CollationKey;
import java.text.Collator;
@ -35,7 +34,7 @@ import java.util.regex.Pattern;
/**
* Represents a Module metadata, as defined in Jetty.
*/
public class Module
public class Module extends TextFile
{
public static class DepthComparator implements Comparator<Module>
{
@ -57,104 +56,31 @@ public class Module
}
}
public static Module fromFile(File file) throws IOException
{
String name = file.getName();
// Strip .ini
name = Pattern.compile(".mod$",Pattern.CASE_INSENSITIVE).matcher(name).replaceFirst("");
// XML Pattern
Pattern xmlPattern = Pattern.compile(".xml$",Pattern.CASE_INSENSITIVE);
Set<String> parents = new HashSet<>();
List<String> xmls = new ArrayList<>();
List<String> libs = new ArrayList<>();
try (FileReader reader = new FileReader(file))
{
try (BufferedReader buf = new BufferedReader(reader))
{
String line;
while ((line = buf.readLine()) != null)
{
line = line.trim();
if (line.length() <= 0)
{
continue; // skip empty lines
}
if (line.charAt(0) == '#')
{
continue; // skip lines with comments
}
// has assignment
int idx = line.indexOf('=');
if (idx >= 0)
{
String key = line.substring(0,idx);
String value = line.substring(idx + 1);
boolean handled = false;
switch (key.toUpperCase(Locale.ENGLISH))
{
case "DEPEND":
parents.add(value);
handled = true;
break;
case "LIB":
libs.add(value);
handled = true;
break;
}
if (handled)
{
continue; // no further processing of line needed
}
}
// Is it an XML line?
if (xmlPattern.matcher(line).find())
{
xmls.add(line);
continue; // legit xml
}
throw new IllegalArgumentException("Unrecognized Module Metadata line [" + line + "] in Module file [" + file + "]");
}
}
}
return new Module(name,parents,xmls,libs);
}
/** The name of this Module */
private final String name;
private String name;
/** List of Modules, by name, that this Module depends on */
private final Set<String> parentNames;
private Set<String> parentNames;
/** The Edges to parent modules */
private final Set<Module> parentEdges;
private Set<Module> parentEdges;
/** The Edges to child modules */
private final Set<Module> childEdges;
private Set<Module> childEdges;
/** The depth of the module in the tree */
private int depth = 0;
/** List of xml configurations for this Module */
private final List<String> xmls;
private List<String> xmls;
/** List of library options for this Module */
private final List<String> libs;
private List<String> libs;
/** Is this Module enabled via start.jar command line, start.ini, or start.d/*.ini ? */
private boolean enabled = false;
public Module(String name, Set<String> parentNames, List<String> xmls, List<String> libs)
public Module(File file) throws FileNotFoundException, IOException
{
this.name = name;
this.parentNames = parentNames;
this.xmls = xmls;
this.libs = libs;
super(file);
// initialize edge collections, will be filled out by Modules#buildGraph() later */
this.parentEdges = new HashSet<>();
this.childEdges = new HashSet<>();
String name = file.getName();
// Strip .ini
name = Pattern.compile(".mod$",Pattern.CASE_INSENSITIVE).matcher(name).replaceFirst("");
}
public void addChildEdge(Module child)
@ -167,6 +93,36 @@ public class Module
this.parentEdges.add(parent);
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
Module other = (Module)obj;
if (name == null)
{
if (other.name != null)
{
return false;
}
}
else if (!name.equals(other.name))
{
return false;
}
return true;
}
public Set<Module> getChildEdges()
{
return childEdges;
@ -202,38 +158,78 @@ public class Module
return xmls;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = (prime * result) + ((name == null)?0:name.hashCode());
return result;
}
@Override
public void init()
{
String name = getFile().getName();
// Strip .ini
this.name = Pattern.compile(".mod$",Pattern.CASE_INSENSITIVE).matcher(name).replaceFirst("");
this.parentNames = new HashSet<>();
this.parentEdges = new HashSet<>();
this.childEdges = new HashSet<>();
this.xmls = new ArrayList<>();
this.libs = new ArrayList<>();
}
public boolean isEnabled()
{
return enabled;
}
@Override
public int hashCode()
public void process(String line)
{
final int prime = 31;
int result = 1;
result = prime * result + ((name == null)?0:name.hashCode());
return result;
}
boolean handled = false;
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Module other = (Module)obj;
if (name == null)
if (line == null)
{
if (other.name != null)
return false;
}
else if (!name.equals(other.name))
return false;
return true;
// has assignment
int idx = line.indexOf('=');
if (idx >= 0)
{
String key = line.substring(0,idx);
String value = line.substring(idx + 1);
switch (key.toUpperCase(Locale.ENGLISH))
{
case "DEPEND":
parentNames.add(value);
handled = true;
break;
case "LIB":
libs.add(value);
handled = true;
break;
}
}
if (handled)
{
return; // no further processing of line needed
}
// Is it an XML line?
if (FS.isXml(line))
{
xmls.add(line);
return;
}
throw new IllegalArgumentException("Unrecognized Module Metadata line [" + line + "] in Module file [" + getFile() + "]");
}
public void setDepth(int depth)
@ -246,6 +242,7 @@ public class Module
this.enabled = enabled;
}
@Override
public String toString()
{
StringBuilder str = new StringBuilder();

View File

@ -29,6 +29,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
/**
* Access for all modules declared, as well as what is enabled.
@ -37,11 +38,6 @@ public class Modules implements Iterable<Module>
{
private Map<String, Module> modules = new HashMap<>();
public void register(Module module)
{
modules.put(module.getName(),module);
}
private void bfsCalculateDepth(final Module module, final int depthNow)
{
int depth = depthNow + 1;
@ -64,8 +60,6 @@ public class Modules implements Iterable<Module>
*/
public void buildGraph()
{
// TODO: Validate / Enforce Directed Acyclic Graph
// Connect edges
for (Module module : modules.values())
{
@ -80,6 +74,15 @@ public class Modules implements Iterable<Module>
}
}
// Verify there is no cyclic references
Stack<String> refs = new Stack<>();
for (Module module : modules.values())
{
refs.push(module.getName());
assertNoCycle(module,refs);
refs.pop();
}
// Calculate depth of all modules for sorting later
for (Module module : modules.values())
{
@ -90,11 +93,56 @@ public class Modules implements Iterable<Module>
}
}
private void assertNoCycle(Module module, Stack<String> refs)
{
for (Module parent : module.getParentEdges())
{
if (refs.contains(parent.getName()))
{
// Cycle detected.
StringBuilder err = new StringBuilder();
err.append("A cyclic reference in the modules has been detected: ");
for (int i = 0; i < refs.size(); i++)
{
if (i > 0)
{
err.append(" -> ");
}
err.append(refs.get(i));
}
err.append(" -> ").append(parent.getName());
throw new IllegalStateException(err.toString());
}
refs.push(parent.getName());
assertNoCycle(parent,refs);
refs.pop();
}
}
public Integer count()
{
return modules.size();
}
public void dump()
{
List<Module> ordered = new ArrayList<>();
ordered.addAll(modules.values());
Collections.sort(ordered,Collections.reverseOrder(new Module.DepthComparator()));
for (Module module : ordered)
{
System.out.printf("Module: %s%n",module.getName());
System.out.printf(" depth: %d%n",module.getDepth());
System.out.printf(" parents: [%s]%n",join(module.getParentNames(),','));
for (String xml : module.getXmls())
{
System.out.printf(" xml: %s%n",xml);
}
}
}
public void enable(String name)
{
Module module = modules.get(name);
@ -116,40 +164,6 @@ public class Modules implements Iterable<Module>
}
}
public void dump()
{
List<Module> ordered = new ArrayList<>();
ordered.addAll(modules.values());
Collections.sort(ordered,Collections.reverseOrder(new Module.DepthComparator()));
for (Module module : ordered)
{
System.out.printf("Module: %s%n",module.getName());
System.out.printf(" depth: %d%n",module.getDepth());
System.out.printf(" parents: [%s]%n",join(module.getParentNames(),','));
for (String xml : module.getXmls())
{
System.out.printf(" xml: %s%n",xml);
}
}
}
private String join(Collection<?> objs, char delim)
{
StringBuilder str = new StringBuilder();
boolean needDelim = false;
for (Object obj : objs)
{
if (needDelim)
{
str.append(delim);
}
str.append(obj);
needDelim = true;
}
return str.toString();
}
public Module get(String name)
{
Module module = modules.get(name);
@ -166,27 +180,20 @@ public class Modules implements Iterable<Module>
return modules.values().iterator();
}
/**
* Resolve the execution order of the enabled modules, and all dependant modules, based on depth first transitive reduction.
*
* @return the list of active modules (plus dependant modules), in execution order.
*/
public List<Module> resolveEnabled()
private String join(Collection<?> objs, char delim)
{
Set<Module> active = new HashSet<Module>();
for (Module module : modules.values())
StringBuilder str = new StringBuilder();
boolean needDelim = false;
for (Object obj : objs)
{
if (module.isEnabled())
if (needDelim)
{
findParents(module,active);
str.append(delim);
}
str.append(obj);
needDelim = true;
}
List<Module> ordered = new ArrayList<>();
ordered.addAll(active);
Collections.sort(ordered,new Module.DepthComparator());
return ordered;
return str.toString();
}
// TODO: Resolve LIB names to actual java.io.File references via HomeBase
@ -225,11 +232,39 @@ public class Modules implements Iterable<Module>
return xmls;
}
public void register(Module module)
{
modules.put(module.getName(),module);
}
public void registerAll(BaseHome basehome) throws IOException
{
for (File file : basehome.listFiles("modules",new FS.FilenameRegexFilter("^.*\\.mod$")))
{
register(Module.fromFile(file));
register(new Module(file));
}
}
/**
* Resolve the execution order of the enabled modules, and all dependant modules, based on depth first transitive reduction.
*
* @return the list of active modules (plus dependant modules), in execution order.
*/
public List<Module> resolveEnabled()
{
Set<Module> active = new HashSet<Module>();
for (Module module : modules.values())
{
if (module.isEnabled())
{
findParents(module,active);
}
}
List<Module> ordered = new ArrayList<>();
ordered.addAll(active);
Collections.sort(ordered,new Module.DepthComparator());
return ordered;
}
}

View File

@ -27,20 +27,7 @@ import java.util.Comparator;
* Natural Language Sorting
*/
public class NaturalSort
{
public static class Strings implements Comparator<String>
{
private final Collator collator = Collator.getInstance();
@Override
public int compare(String o1, String o2)
{
CollationKey key1 = collator.getCollationKey(o1);
CollationKey key2 = collator.getCollationKey(o2);
return key1.compareTo(key2);
}
}
{
public static class Files implements Comparator<File>
{
private final Collator collator = Collator.getInstance();
@ -53,4 +40,17 @@ public class NaturalSort
return key1.compareTo(key2);
}
}
public static class Strings implements Comparator<String>
{
private final Collator collator = Collator.getInstance();
@Override
public int compare(String o1, String o2)
{
CollationKey key1 = collator.getCollationKey(o1);
CollationKey key2 = collator.getCollationKey(o2);
return key1.compareTo(key2);
}
}
}

View File

@ -0,0 +1,588 @@
//
// ========================================================================
// Copyright (c) 1995-2013 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.start;
import static org.eclipse.jetty.start.UsageException.*;
import java.io.File;
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
/**
* The Arguments required to start Jetty.
*/
public class StartArgs
{
public static final String VERSION;
static
{
String ver = System.getProperty("jetty.version",null);
if (ver == null)
{
Package pkg = StartArgs.class.getPackage();
if ((pkg != null) && "Eclipse.org - Jetty".equals(pkg.getImplementationVendor()) && (pkg.getImplementationVersion() != null))
{
ver = pkg.getImplementationVersion();
}
}
if (ver == null)
{
ver = "TEST";
}
VERSION = ver;
}
// TODO: might make sense to declare this in modules/base.mod
private static final String SERVER_MAIN = "org.eclipse.jetty.xml.XmlConfiguration";
private List<String> commandLine = new ArrayList<>();
private List<String> enabledModules = new ArrayList<>();
private List<String> downloads = new ArrayList<>();
private Classpath classpath;
private List<String> xmlRefs = new ArrayList<>();
private List<File> xmls = new ArrayList<>();
private Properties properties = new Properties();
private Set<String> systemPropertyKeys = new HashSet<>();
private List<String> jvmArgs = new ArrayList<>();
private Modules allModules;
// Should the server be run?
private boolean run = true;
private boolean help = false;
private boolean stopCommand = false;
private boolean listModules = false;
private boolean listClasspath = false;
private boolean listConfig = false;
private boolean version = false;
private boolean dryRun = false;
private boolean exec = false;
public StartArgs(String[] commandLineArgs)
{
commandLine.addAll(Arrays.asList(commandLineArgs));
classpath = new Classpath();
}
public void addSystemProperty(String key, String value)
{
this.systemPropertyKeys.add(key);
System.setProperty(key,value);
}
private void addUniqueXmlFile(String xmlRef, File xmlfile) throws IOException
{
if (!FS.canReadFile(xmlfile))
{
throw new IOException("Cannot read file: " + xmlRef);
}
xmlfile = xmlfile.getCanonicalFile();
if (!xmls.contains(xmlfile))
{
xmls.add(xmlfile);
}
}
/**
* Ensure that the System Properties are set (if defined as a System property, or start.config property, or start.ini property)
*
* @param key
* the key to be sure of
*/
private void ensureSystemPropertySet(String key)
{
if (systemPropertyKeys.contains(key))
{
return; // done
}
if (properties.containsKey(key))
{
String val = properties.getProperty(key,null);
if (val == null)
{
return; // no value to set
}
// setup system property
systemPropertyKeys.add(key);
System.setProperty(key,val);
}
}
/**
* Build up the Classpath and XML file references based on enabled Module list.
*
* @param baseHome
* @param activeModules
* @throws IOException
*/
public void expandModules(BaseHome baseHome, List<Module> activeModules) throws IOException
{
for (Module module : activeModules)
{
// Find and Expand Libraries
for (String rawlibref : module.getLibs())
{
String libref = rawlibref.replace("${jetty.version}",VERSION);
libref = FS.separators(libref);
if (libref.contains("*"))
{
// Glob Reference
int idx = libref.lastIndexOf(File.separatorChar);
String relativePath = "/";
String filenameRef = libref;
if (idx >= 0)
{
relativePath = libref.substring(0,idx);
filenameRef = libref.substring(idx + 1);
}
StringBuilder regex = new StringBuilder();
regex.append('^');
for (char c : filenameRef.toCharArray())
{
switch (c)
{
case '*':
regex.append(".*");
break;
case '.':
regex.append("\\.");
break;
default:
regex.append(c);
}
}
regex.append('$');
FileFilter filter = new FS.FilenameRegexFilter(regex.toString());
for (File libfile : baseHome.listFiles(relativePath,filter))
{
classpath.addComponent(libfile);
}
}
else
{
// Straight Reference
File libfile = baseHome.getFile(libref);
classpath.addComponent(libfile);
}
}
// Find and Expand XML files
for (String xmlRef : module.getXmls())
{
// Straight Reference
File xmlfile = baseHome.getFile(xmlRef);
addUniqueXmlFile(xmlRef,xmlfile);
}
}
}
public Modules getAllModules()
{
return allModules;
}
public Classpath getClasspath()
{
return classpath;
}
public List<String> getCommandLine()
{
return this.commandLine;
}
public List<String> getDownloads()
{
return downloads;
}
public List<String> getEnabledModules()
{
return this.enabledModules;
}
public CommandLineBuilder getMainArgs(BaseHome baseHome, boolean addJavaInit) throws IOException
{
CommandLineBuilder cmd = new CommandLineBuilder();
if (addJavaInit)
{
cmd.addArg(CommandLineBuilder.findJavaBin());
for (String x : jvmArgs)
{
cmd.addArg(x);
}
cmd.addRawArg("-Djetty.home=" + baseHome.getHome());
cmd.addRawArg("-Djetty.base=" + baseHome.getBase());
// Special Stop/Shutdown properties
ensureSystemPropertySet("STOP.PORT");
ensureSystemPropertySet("STOP.KEY");
// System Properties
for (String propKey : systemPropertyKeys)
{
String value = System.getProperty(propKey);
cmd.addEqualsArg("-D" + propKey,value);
}
cmd.addArg("-cp");
cmd.addRawArg(classpath.toString());
cmd.addRawArg(getMainClassname());
}
// Check if we need to pass properties as a file
if (properties.size() > 0)
{
File prop_file = File.createTempFile("start",".properties");
if (!dryRun)
{
prop_file.deleteOnExit();
}
try (FileOutputStream out = new FileOutputStream(prop_file))
{
properties.store(out,"start.jar properties");
}
cmd.addArg(prop_file.getAbsolutePath());
}
for (File xml : xmls)
{
cmd.addRawArg(xml.getAbsolutePath());
}
return cmd;
}
public String getMainClassname()
{
String mainclass = System.getProperty("jetty.server",SERVER_MAIN);
return System.getProperty("main.class",mainclass);
}
public Properties getProperties()
{
return properties;
}
private String getValue(String arg)
{
int idx = arg.indexOf('=');
if (idx == (-1))
{
throw new UsageException(ERR_BAD_ARG,"Argument is missing a required value: %s",arg);
}
String value = arg.substring(idx + 1).trim();
if (value.length() <= 0)
{
throw new UsageException(ERR_BAD_ARG,"Argument is missing a required value: %s",arg);
}
return value;
}
public List<File> getXmlFiles()
{
return xmls;
}
public boolean hasJvmArgs()
{
return jvmArgs.size() > 0;
}
public boolean hasSystemProperties()
{
return systemPropertyKeys.size() > 0;
}
public boolean isDryRun()
{
return dryRun;
}
public boolean isExec()
{
return exec;
}
public boolean isHelp()
{
return help;
}
public boolean isListClasspath()
{
return listClasspath;
}
public boolean isListConfig()
{
return listConfig;
}
public boolean isListModules()
{
return listModules;
}
public boolean isRun()
{
return run;
}
public boolean isStopCommand()
{
return stopCommand;
}
public boolean isVersion()
{
return version;
}
public void parse(String arg)
{
if ("--help".equals(arg) || "-?".equals(arg))
{
help = true;
run = false;
return;
}
if ("--debug".equals(arg))
{
// valid, but handled in StartLog instead
return;
}
if ("--stop".equals(arg))
{
stopCommand = true;
run = false;
//
// int port = Integer.parseInt(_config.getProperty("STOP.PORT","-1"));
// String key = _config.getProperty("STOP.KEY",null);
// int timeout = Integer.parseInt(_config.getProperty("STOP.WAIT","0"));
// stop(port,key,timeout);
//
return;
}
if (arg.startsWith("--download="))
{
downloads.add(getValue(arg));
return;
}
if ("--list-classpath".equals(arg) || "--version".equals(arg) || "-v".equals(arg) || "--info".equals(arg))
{
listClasspath = true;
run = false;
return;
}
if ("--list-config".equals(arg))
{
listConfig = true;
run = false;
return;
}
if ("--list-modules".equals(arg))
{
listModules = true;
run = false;
return;
}
if ("--dry-run".equals(arg) || "--exec-print".equals(arg))
{
dryRun = true;
run = false;
return;
}
if ("--exec".equals(arg))
{
exec = true;
return;
}
if (arg.startsWith("--enable="))
{
String moduleName = getValue(arg);
// TODO:
run = false;
return;
}
if (arg.startsWith("--disable="))
{
String moduleName = getValue(arg);
// TODO:
run = false;
return;
}
if (arg.startsWith("MODULE="))
{
enabledModules.add(getValue(arg));
return;
}
if (arg.startsWith("MODULES="))
{
for (String moduleName : getValue(arg).split(","))
{
if (moduleName == null)
{
continue; // skip
}
enabledModules.add(moduleName.trim());
}
return;
}
// Start property (syntax similar to System property)
if (arg.startsWith("-D"))
{
String[] assign = arg.substring(2).split("=",2);
systemPropertyKeys.add(assign[0]);
switch (assign.length)
{
case 2:
System.setProperty(assign[0],assign[1]);
break;
case 1:
System.setProperty(assign[0],"");
break;
default:
break;
}
return;
}
// Anything else with a "-" is considered a JVM argument
if (arg.startsWith("-"))
{
// Only add non-duplicates
if (!jvmArgs.contains(arg))
{
jvmArgs.add(arg);
}
return;
}
// Is this a raw property declaration?
int idx = arg.indexOf('=');
if (idx >= 0)
{
String key = arg.substring(0,idx);
String value = arg.substring(idx + 1);
properties.setProperty(key,value);
return;
}
// Is this an xml file?
if (FS.isXml(arg))
{
// only add non-duplicates
if (!xmlRefs.contains(arg))
{
xmlRefs.add(arg);
}
return;
}
// Anything else is unrecognized
throw new UsageException(ERR_BAD_ARG,"Unrecognized argument: %s",arg);
}
public void parse(TextFile file)
{
for (String line : file)
{
parse(line);
}
}
public void parseCommandLine()
{
for (String line : commandLine)
{
parse(line);
}
}
public void resolveExtraXmls(BaseHome baseHome) throws IOException
{
// Find and Expand XML files
for (String xmlRef : xmlRefs)
{
// Straight Reference
File xmlfile = baseHome.getFile(xmlRef);
if (!xmlfile.exists())
{
xmlfile = baseHome.getFile("etc/" + xmlRef);
}
addUniqueXmlFile(xmlRef,xmlfile);
}
}
public void setAllModules(Modules allModules)
{
this.allModules = allModules;
}
@Override
public String toString()
{
StringBuilder builder = new StringBuilder();
builder.append("StartArgs [commandLine=");
builder.append(commandLine);
builder.append(", enabledModules=");
builder.append(enabledModules);
builder.append(", xmlRefs=");
builder.append(xmlRefs);
builder.append(", properties=");
builder.append(properties);
builder.append(", jvmArgs=");
builder.append(jvmArgs);
builder.append("]");
return builder.toString();
}
}

View File

@ -18,111 +18,35 @@
package org.eclipse.jetty.start;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
/**
* Simple Start .INI handler
*/
public class StartIni implements Iterable<String>
public class StartIni extends TextFile
{
public static interface IncludeListener
{
public List<StartIni> onIniInclude(String path) throws IOException;
}
private final File file;
private final List<String> lines= new ArrayList<>();
public StartIni(File file) throws FileNotFoundException, IOException
{
this.file = file;
try (FileReader reader = new FileReader(file))
{
try (BufferedReader buf = new BufferedReader(reader))
{
String line;
while ((line = buf.readLine()) != null)
process(line.trim());
}
}
super(file);
}
public StartIni(ArrayList<String> arguments)
@Override
public void addUniqueLine(String line)
{
file=null;
for (String line: arguments)
process(line);
}
private void process(String line)
{
if (line.length() == 0)
return;
if (line.charAt(0) == '#')
return;
// Smart Handling, split into multiple OPTIONS lines (for dup check reasons)
if (line.startsWith("OPTIONS="))
if (line.startsWith("MODULES="))
{
int idx = line.indexOf('=');
String value = line.substring(idx + 1);
for (String part : value.split(","))
{
addUniqueLine("OPTION=" + part);
super.addUniqueLine("MODULE=" + part);
}
}
else
{
// Add line as-is
addUniqueLine(line);
super.addUniqueLine(line);
}
}
private void addUniqueLine(String line)
{
if (lines.contains(line))
{
// skip
return;
}
lines.add(line);
}
public File getFile()
{
return file;
}
public List<String> getLineMatches(Pattern pattern)
{
List<String> ret = new ArrayList<>();
for (String line : lines)
{
if (pattern.matcher(line).matches())
{
ret.add(line);
}
}
return ret;
}
public List<String> getLines()
{
return lines;
}
@Override
public Iterator<String> iterator()
{
return lines.iterator();
}
}

View File

@ -0,0 +1,139 @@
//
// ========================================================================
// Copyright (c) 1995-2013 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.start;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Centralized Place for logging.
* <p>
* Because startup cannot rely on Jetty's Logging, an alternative logging is established.
* <p>
* Optional behavior is to create a ${jetty.base}/logs/start.log with whatever output the startup process produces.
*/
public class StartLog
{
private final static StartLog INSTANCE = new StartLog();
public static void debug(String format, Object... args)
{
if (INSTANCE.debug)
{
System.out.printf(format + "%n",args);
}
}
public static void debug(Throwable t)
{
if (INSTANCE.debug)
{
t.printStackTrace(System.out);
}
}
public static StartLog getInstance()
{
return INSTANCE;
}
public static void warn(String format, Object... args)
{
System.err.printf(format + "%n",args);
}
public static void warn(Throwable t)
{
t.printStackTrace(System.err);
}
private boolean debug = false;
public void initialize(BaseHome baseHome, StartArgs args) throws IOException
{
// Debug with boolean
Pattern debugBoolPat = Pattern.compile("(-D)?debug=(.*)");
// Log file name
Pattern logFilePat = Pattern.compile("(-D)?start-log-file=(.*)");
// TODO: support backward compatible --daemon argument ??
Matcher matcher;
for (String arg : args.getCommandLine())
{
if ("--debug".equals(arg))
{
debug = true;
continue;
}
matcher = debugBoolPat.matcher(arg);
if (matcher.matches())
{
debug = Boolean.parseBoolean(matcher.group(2));
continue;
}
matcher = logFilePat.matcher(arg);
if (matcher.matches())
{
String filename = matcher.group(2);
File logfile = baseHome.getBaseFile(filename);
initLogFile(logfile);
}
}
}
public void initLogFile(File logfile) throws IOException
{
if (logfile != null)
{
File logDir = logfile.getParentFile();
if (!logDir.exists() || !logDir.canWrite())
{
String err = String.format("Cannot write %s to directory %s [directory doesn't exist or is read-only]",logfile.getName(),
logDir.getAbsolutePath());
throw new UsageException(UsageException.ERR_LOGGING,new IOException(err));
}
File startLog = logfile;
if (!startLog.exists() && !startLog.createNewFile())
{
// Output about error is lost in majority of cases.
throw new UsageException(UsageException.ERR_LOGGING,new IOException("Unable to create: " + startLog.getAbsolutePath()));
}
if (!startLog.canWrite())
{
// Output about error is lost in majority of cases.
throw new UsageException(UsageException.ERR_LOGGING,new IOException("Unable to write to: " + startLog.getAbsolutePath()));
}
PrintStream logger = new PrintStream(new FileOutputStream(startLog,false));
System.setOut(logger);
System.setErr(logger);
System.out.println("Establishing " + logfile + " on " + new Date());
}
}
}

View File

@ -0,0 +1,116 @@
//
// ========================================================================
// Copyright (c) 1995-2013 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.start;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
/**
* Simple common abstraction for Text files, that consist of a series of lines.
* <p>
* Ignoring lines that are empty, deemed to be comments, or are duplicates of prior lines.
*/
public class TextFile implements Iterable<String>
{
private final File file;
private final List<String> lines = new ArrayList<>();
public TextFile(File file) throws FileNotFoundException, IOException
{
this.file = file;
init();
try (FileReader reader = new FileReader(file))
{
try (BufferedReader buf = new BufferedReader(reader))
{
String line;
while ((line = buf.readLine()) != null)
{
if (line.length() == 0)
{
continue;
}
if (line.charAt(0) == '#')
{
continue;
}
process(line.trim());
}
}
}
}
public void addUniqueLine(String line)
{
if (lines.contains(line))
{
// skip
return;
}
lines.add(line);
}
public File getFile()
{
return file;
}
public List<String> getLineMatches(Pattern pattern)
{
List<String> ret = new ArrayList<>();
for (String line : lines)
{
if (pattern.matcher(line).matches())
{
ret.add(line);
}
}
return ret;
}
public List<String> getLines()
{
return lines;
}
public void init()
{
}
@Override
public Iterator<String> iterator()
{
return lines.iterator();
}
public void process(String line)
{
addUniqueLine(line);
}
}

View File

@ -0,0 +1,50 @@
//
// ========================================================================
// Copyright (c) 1995-2013 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.start;
/**
* A Usage Error has occured. Print the usage and exit with the appropriate exit code.
*/
@SuppressWarnings("serial")
public class UsageException extends RuntimeException
{
public static final int ERR_LOGGING = -1;
public static final int ERR_INVOKE_MAIN = -2;
public static final int ERR_NOT_STOPPED = -4;
public static final int ERR_UNKNOWN = -5;
public static final int ERR_BAD_ARG = -6;
private int exitCode;
public UsageException(int exitCode, String format, Object... objs)
{
super(String.format(format,objs));
this.exitCode = exitCode;
}
public UsageException(int exitCode, Throwable cause)
{
super(cause);
this.exitCode = exitCode;
}
public int getExitCode()
{
return exitCode;
}
}

View File

@ -19,30 +19,79 @@
package org.eclipse.jetty.start;
/**
* Utility class for parsing and comparing version strings.
* JDK 1.1 compatible.
* Utility class for parsing and comparing version strings. JDK 1.1 compatible.
*
*/
public class Version {
public class Version
{
int _version = 0;
int _revision = 0;
int _subrevision = 0;
String _suffix = "";
public Version() {
public Version()
{
}
public Version(String version_string) {
public Version(String version_string)
{
parse(version_string);
}
// java.lang.Comparable is Java 1.2! Cannot use it
/**
* parses version string in the form version[.revision[.subrevision[extension]]]
* into this instance.
* Compares with other version. Does not take extension into account, as there is no reliable way to order them.
*
* @return -1 if this is older version that other, 0 if its same version, 1 if it's newer version than other
*/
public void parse(String version_string) {
public int compare(Version other)
{
if (other == null)
{
throw new NullPointerException("other version is null");
}
if (this._version < other._version)
{
return -1;
}
if (this._version > other._version)
{
return 1;
}
if (this._revision < other._revision)
{
return -1;
}
if (this._revision > other._revision)
{
return 1;
}
if (this._subrevision < other._subrevision)
{
return -1;
}
if (this._subrevision > other._subrevision)
{
return 1;
}
return 0;
}
/**
* Check whether this verion is in range of versions specified
*/
public boolean isInRange(Version low, Version high)
{
return ((compare(low) >= 0) && (compare(high) <= 0));
}
/**
* parses version string in the form version[.revision[.subrevision[extension]]] into this instance.
*/
public void parse(String version_string)
{
_version = 0;
_revision = 0;
_subrevision = 0;
@ -50,33 +99,41 @@ public class Version {
int pos = 0;
int startpos = 0;
int endpos = version_string.length();
while ( (pos < endpos) && Character.isDigit(version_string.charAt(pos))) {
while ((pos < endpos) && Character.isDigit(version_string.charAt(pos)))
{
pos++;
}
_version = Integer.parseInt(version_string.substring(startpos,pos));
if ((pos < endpos) && version_string.charAt(pos)=='.') {
if ((pos < endpos) && (version_string.charAt(pos) == '.'))
{
startpos = ++pos;
while ( (pos < endpos) && Character.isDigit(version_string.charAt(pos))) {
while ((pos < endpos) && Character.isDigit(version_string.charAt(pos)))
{
pos++;
}
_revision = Integer.parseInt(version_string.substring(startpos,pos));
}
if ((pos < endpos) && version_string.charAt(pos)=='.') {
if ((pos < endpos) && (version_string.charAt(pos) == '.'))
{
startpos = ++pos;
while ( (pos < endpos) && Character.isDigit(version_string.charAt(pos))) {
while ((pos < endpos) && Character.isDigit(version_string.charAt(pos)))
{
pos++;
}
_subrevision = Integer.parseInt(version_string.substring(startpos,pos));
}
if (pos < endpos) {
if (pos < endpos)
{
_suffix = version_string.substring(pos);
}
}
/**
* @return string representation of this version
*/
public String toString() {
@Override
public String toString()
{
StringBuffer sb = new StringBuffer(10);
sb.append(_version);
sb.append('.');
@ -86,30 +143,4 @@ public class Version {
sb.append(_suffix);
return sb.toString();
}
// java.lang.Comparable is Java 1.2! Cannot use it
/**
* Compares with other version. Does not take extension into account,
* as there is no reliable way to order them.
* @return -1 if this is older version that other,
* 0 if its same version,
* 1 if it's newer version than other
*/
public int compare(Version other) {
if (other == null) throw new NullPointerException("other version is null");
if (this._version < other._version) return -1;
if (this._version > other._version) return 1;
if (this._revision < other._revision) return -1;
if (this._revision > other._revision) return 1;
if (this._subrevision < other._subrevision) return -1;
if (this._subrevision > other._subrevision) return 1;
return 0;
}
/**
* Check whether this verion is in range of versions specified
*/
public boolean isInRange(Version low, Version high) {
return (compare(low)>=0 && compare(high)<=0);
}
}

View File

@ -1,179 +0,0 @@
# This file controls what file are to be put on classpath or command line.
#
# Format is as follows:
#
# Each line contains entry in the format:
#
# SUBJECT [ [!] CONDITION [AND|OR] ]*
#
# where SUBJECT:
# ends with ".class" is the Main class to run.
# ends with ".xml" is a configuration file for the command line
# ends with "/" is a directory from which to add all jar and zip files.
# ends with "/*" is a directory from which to add all unconsidered jar and zip files.
# ends with "/**" is a directory from which to recursively add all unconsidered jar and zip files.
# Containing = are used to assign system properties.
# Containing ~= are used to assign start properties.
# Containing /= are used to assign a canonical path.
# all other subjects are treated as files to be added to the classpath.
#
# ${name} is expanded to a start property
# $(name) is expanded to either a start property or a system property.
# The start property ${version} is defined as the version of the start.jar
#
# Files starting with "/" are considered absolute, all others are relative to
# the home directory.
#
# CONDITION is one of:
# always
# never
# available classname # true if class on classpath
# property name # true if set as start property
# system name # true if set as system property
# exists file # true if file/dir exists
# java OPERATOR version # java version compared to literal
# nargs OPERATOR number # number of command line args compared to literal
# OPERATOR := one of "<",">","<=",">=","==","!="
#
# CONTITIONS can be combined with AND OR or !, with AND being the assume
# operator for a list of CONDITIONS.
#
# Classpath operations are evaluated on the fly, so once a class or jar is
# added to the classpath, subsequent available conditions will see that class.
#
# The configuration file may be divided into sections with option names like:
# [ssl,default]
#
# Clauses after a section header will only be included if they match one of the tags in the
# options property. By default options are set to "default,*" or the OPTIONS property may
# be used to pass in a list of tags, eg. :
#
# java -jar start.jar OPTIONS=jetty,jsp,ssl
#
# The tag '*' is always appended to the options, so any section with the * tag is always
# applied.
#
# add a property defined classpath
${path}.path property path
# add a property defined library directory
${lib}/** exists ${lib}
# 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
# Set the jetty.base property
jetty.base=$(jetty.base) system jetty.base
# The main class to run
org.eclipse.jetty.xml.XmlConfiguration.class
${start.class}.class property start.class
# The default configuration files
$(jetty.base)/etc/jetty.xml nargs == 0 AND property jetty.base
$(jetty.home)/etc/jetty.xml nargs == 0
./jetty-server/src/main/config/etc/jetty.xml nargs == 0 AND ! exists $(jetty.home)/etc/jetty.xml
# Default OPTIONS if not specified on the command line
OPTIONS~=default,* ! property OPTIONS
# Add a resources directory if it is there
[All,resources,default]
$(jetty.base)/resources/ property jetty.base
$(jetty.home)/resources/
# Add jetty modules
[*]
$(jetty.home)/lib/jetty-util-$(version).jar ! available org.eclipse.jetty.util.StringUtil
$(jetty.home)/lib/jetty-io-$(version).jar ! available org.eclipse.jetty.io.Buffer
[Server,All,xml,default]
$(jetty.home)/lib/jetty-xml-$(version).jar ! available org.eclipse.jetty.xml.XmlParser
[Server,All,server,default]
$(jetty.home)/lib/servlet-api-3.1.jar ! available javax.servlet.ServletContext
$(jetty.home)/lib/jetty-schemas-3.1.jar
$(jetty.home)/lib/jetty-http-$(version).jar ! available org.eclipse.jetty.http.HttpParser
$(jetty.home)/lib/jetty-continuation-$(version).jar ! available org.eclipse.jetty.continuation.Continuation
$(jetty.home)/lib/jetty-server-$(version).jar ! available org.eclipse.jetty.server.Server
[Server,All,security,default]
$(jetty.home)/lib/jetty-security-$(version).jar ! available org.eclipse.jetty.security.LoginService
[Server,All,servlet,default]
$(jetty.home)/lib/servlet-api-3.0.jar ! available javax.servlet.ServletContext
$(jetty.home)/lib/jetty-servlet-$(version).jar ! available org.eclipse.jetty.servlet.ServletHandler
[servlets]
$(jetty.home)/lib/jetty-servlets-$(version).jar ! available org.eclipse.jetty.servlets.MultiPartFilter
[Server,All,webapp,default]
$(jetty.home)/lib/jetty-webapp-$(version).jar ! available org.eclipse.jetty.webapp.WebAppContext
[Server,All,deploy,default]
$(jetty.home)/lib/jetty-deploy-$(version).jar ! available org.eclipse.jetty.deploy.ContextDeployer
[All,rewrite]
$(jetty.home)/lib/jetty-rewrite-$(version).jar ! available org.eclipse.jetty.rewrite.handler.RewriteHandler
[All,jmx]
$(jetty.home)/lib/jetty-jmx-$(version).jar ! available org.eclipse.jetty.jmx.MBeanContainer
[All,ajp]
$(jetty.home)/lib/jetty-ajp-$(version).jar ! available org.eclipse.jetty.ajp.Ajp13Connection
[All,plus,jndi]
$(jetty.home)/lib/jetty-jndi-${version}.jar ! available org.eclipse.jetty.jndi.ContextFactory
$(jetty.home)/lib/jetty-plus-${version}.jar ! available org.eclipse.jetty.plus.jndi.NamingEntry
$(jetty.home)/lib/jndi/** exists $(jetty.home)/lib/jndi
[All,jaas]
$(jetty.home)/lib/jetty-jaas-${version}.jar ! available org.eclipse.jetty.jaas.JAASLoginService
[All,annotations]
$(jetty.home)/lib/jetty-annotations-$(version).jar ! available org.eclipse.jetty.annotations.AnnotationParser
$(jetty.home)/lib/annotations/** exists $(jetty.home)/lib/annotations
[All,setuid]
$(jetty.home)/lib/jetty-setuid-$(version).jar ! available org.eclipse.jetty.setuid.SetUID
$(jetty.home)/lib/setuid/**
[All,policy]
$(jetty.home)/lib/jetty-policy-$(version).jar ! available org.eclipse.jetty.policy.JettyPolicy
[All,client]
$(jetty.home)/lib/jetty-http-$(version).jar ! available org.eclipse.jetty.http.HttpParser
$(jetty.home)/lib/jetty-client-$(version).jar ! available org.eclipse.jetty.client.HttpClient
[All,proxy]
$(jetty.home)/lib/jetty-proxy-$(version).jar ! available org.eclipse.jetty.proxy.ConnectHandler
$(jetty.home)/lib/jetty-http-$(version).jar ! available org.eclipse.jetty.http.HttpParser
$(jetty.home)/lib/jetty-client-$(version).jar ! available org.eclipse.jetty.client.HttpClient
[All,websocket]
$(jetty.home)/lib/websocket/**
[All,overlay,overlays]
$(jetty.home)/lib/jetty-overlay-deployer-$(version).jar ! available org.eclipse.jetty.overlay.OverlayedAppProvider
# Add ext if it exists
[Server,All,default,ext]
$(jetty.base)/lib/ext/** property jetty.base
$(jetty.home)/lib/ext/**
# Add all other sub-directories in /lib/ as options in a dynamic way
[All,=$(jetty.base)/lib/**]
[All,=$(jetty.home)/lib/**]
# Set property jetty.base and jetty.log as jetty.home if not set
jetty.base=${jetty.home} ! property jetty.base
jetty.logs=${jetty.base}/logs ! property jetty.logs

View File

@ -1,648 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2013 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.start;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class ConfigTest
{
private void assertEquals(String msg, Classpath expected, Classpath actual)
{
Assert.assertNotNull(msg + " : expected classpath should not be null",expected);
Assert.assertNotNull(msg + " : actual classpath should not be null",actual);
Assert.assertTrue(msg + " : expected should have an entry",expected.count() >= 1);
Assert.assertTrue(msg + " : actual should have an entry",actual.count() >= 1);
if (expected.count() != actual.count())
{
expected.dump(System.err);
actual.dump(System.err);
Assert.assertEquals(msg + " : count",expected.count(),actual.count());
}
List<File> actualEntries = Arrays.asList(actual.getElements());
List<File> expectedEntries = Arrays.asList(expected.getElements());
int len = expectedEntries.size();
for (int i = 0; i < len; i++)
{
File expectedFile = expectedEntries.get(i);
File actualFile = actualEntries.get(i);
if (!expectedFile.equals(actualFile))
{
expected.dump(System.err);
actual.dump(System.err);
Assert.assertEquals(msg + ": entry [" + i + "]",expectedEntries.get(i),actualEntries.get(i));
}
}
}
private void assertEquals(String msg, Collection<String> expected, Collection<String> actual)
{
Assert.assertTrue(msg + " : expected should have an entry",expected.size() >= 1);
Assert.assertEquals(msg + " : size",expected.size(),actual.size());
for (String expectedVal : expected)
{
Assert.assertTrue(msg + " : should contain <" + expectedVal + ">",actual.contains(expectedVal));
}
}
private String getJettyEtcFile(String name)
{
File etc = new File(getTestableJettyHome(),"etc");
return new File(etc,name).getAbsolutePath();
}
private File getJettyHomeDir()
{
return new File(getTestResourcesDir(),"jetty.home");
}
private String getTestableJettyHome()
{
return getJettyHomeDir().getAbsolutePath();
}
private File getTestResourcesDir()
{
File src = new File(System.getProperty("user.dir"),"src");
File test = new File(src,"test");
return new File(test,"resources");
}
@Before
public void reset()
{
}
/*
* Test for SUBJECT "/=" for assign canonical path
*/
@Test
public void testSubjectAssignCanonicalPath() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("test.resources.dir/=src/test/resources\n");
Config cfg = new Config();
cfg.parse(buf);
Assert.assertEquals(getTestResourcesDir().getCanonicalPath(),cfg.getProperty("test.resources.dir"));
}
/*
* Test for SUBJECT "~=" for assigning Start Properties
*/
@Test
public void testSubjectAssignStartProperty() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("test.jetty.start.text~=foo\n");
buf.append("test.jetty.start.quote~=Eatagramovabits\n");
Config options = new Config();
options.parse(buf);
Assert.assertEquals("foo",options.getProperty("test.jetty.start.text"));
Assert.assertEquals("Eatagramovabits",options.getProperty("test.jetty.start.quote"));
}
/*
* Test for SUBJECT "=" for assigning System Properties
*/
@Test
public void testSubjectAssignSystemProperty() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("test.jetty.start.text=foo\n");
buf.append("test.jetty.start.quote=Eatagramovabits\n");
Config options = new Config();
options.parse(buf);
Assert.assertEquals("foo",System.getProperty("test.jetty.start.text"));
Assert.assertEquals("Eatagramovabits",System.getProperty("test.jetty.start.quote"));
}
/*
* Test for SUBJECT ending with "/**", all jar and zip components in dir (deep, recursive)
*/
@Test
public void testSubjectComponentDirDeep() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("$(jetty.home)/lib/**\n");
String jettyHome = getTestableJettyHome();
Config options = new Config();
options.setProperty("jetty.home",jettyHome);
options.parse(buf);
Classpath actual = options.getClasspath();
Classpath expected = new Classpath();
File lib = new File(getJettyHomeDir(),"lib");
expected.addComponent(new File(lib,"core.jar"));
expected.addComponent(new File(lib,"example.jar"));
expected.addComponent(new File(lib,"http.jar"));
expected.addComponent(new File(lib,"io.jar"));
expected.addComponent(new File(lib,"JSR.ZIP"));
expected.addComponent(new File(lib,"LOGGING.JAR"));
expected.addComponent(new File(lib,"server.jar"));
expected.addComponent(new File(lib,"spec.zip"));
expected.addComponent(new File(lib,"util.jar"));
expected.addComponent(new File(lib,"xml.jar"));
File ext = new File(lib,"ext");
expected.addComponent(new File(ext,"custom-impl.jar"));
File foo = new File(lib,"foo");
File bar = new File(foo,"bar");
expected.addComponent(new File(bar,"foobar.jar"));
assertEquals("Components (Deep)",expected,actual);
}
/*
* Test for SUBJECT ending with "/*", all jar and zip components in dir (shallow, no recursion)
*/
@Test
public void testSubjectComponentDirShallow() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("# Example of any shallow components in /lib/\n");
buf.append("$(jetty.home)/lib/*\n");
String jettyHome = getTestableJettyHome();
Config options = new Config();
options.setProperty("jetty.home",jettyHome);
options.parse(buf);
Classpath actual = options.getClasspath();
Classpath expected = new Classpath();
File lib = new File(getJettyHomeDir(),"lib");
expected.addComponent(new File(lib,"core.jar"));
expected.addComponent(new File(lib,"example.jar"));
expected.addComponent(new File(lib,"http.jar"));
expected.addComponent(new File(lib,"io.jar"));
expected.addComponent(new File(lib,"JSR.ZIP"));
expected.addComponent(new File(lib,"LOGGING.JAR"));
expected.addComponent(new File(lib,"server.jar"));
expected.addComponent(new File(lib,"spec.zip"));
expected.addComponent(new File(lib,"util.jar"));
expected.addComponent(new File(lib,"xml.jar"));
assertEquals("Components (Shallow)",expected,actual);
}
/*
* Test for SUBJECT ending with ".class", a Main Class
*/
@Test
public void testSubjectMainClass() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("org.eclipse.jetty.xml.XmlConfiguration.class");
Config options = new Config();
options.parse(buf);
Assert.assertEquals("org.eclipse.jetty.xml.XmlConfiguration",options.getMainClassname());
}
/*
* Test for SUBJECT ending with ".class", a Main Class
*/
@Test
public void testSubjectMainClassConditionalPropertySet() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("org.eclipse.jetty.xml.XmlConfiguration.class\n");
buf.append("${start.class}.class property start.class");
Config options = new Config();
options.setProperty("start.class","net.company.server.Start");
options.parse(buf);
Assert.assertEquals("net.company.server.Start",options.getMainClassname());
}
/*
* Test for SUBJECT ending with ".class", a Main Class
*/
@Test
public void testSubjectMainClassConditionalPropertyUnset() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("org.eclipse.jetty.xml.XmlConfiguration.class\n");
buf.append("${start.class}.class property start.class");
Config options = new Config();
// The "start.class" property is unset.
options.parse(buf);
Assert.assertEquals("org.eclipse.jetty.xml.XmlConfiguration",options.getMainClassname());
}
/*
* Test for SUBJECT ending with "/", a simple Classpath Entry
*/
@Test
public void testSubjectSimpleComponent() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("$(jetty.home)/resources/\n");
String jettyHome = getTestableJettyHome();
Config options = new Config();
options.setProperty("jetty.home",jettyHome);
options.parse(buf);
Classpath actual = options.getClasspath();
Classpath expected = new Classpath();
expected.addComponent(new File(getJettyHomeDir(),"resources"));
assertEquals("Simple Component",expected,actual);
}
/*
* Test for SUBJECT ending with "/", a simple Classpath Entry
*/
@Test
public void testSubjectSimpleComponentMultiple() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("$(jetty.home)/resources/\n");
buf.append("$(jetty.home)/etc/\n");
String jettyHome = getTestableJettyHome();
Config options = new Config();
options.setProperty("jetty.home",jettyHome);
options.parse(buf);
Classpath actual = options.getClasspath();
Classpath expected = new Classpath();
expected.addComponent(new File(getJettyHomeDir(),"resources"));
expected.addComponent(new File(getJettyHomeDir(),"etc"));
assertEquals("Simple Component",expected,actual);
}
/*
* Test for SUBJECT ending with "/", a simple Classpath Entry
*/
@Test
public void testSubjectSimpleComponentNotExists() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("$(jetty.home)/resources/\n");
buf.append("$(jetty.home)/foo/\n");
String jettyHome = getTestableJettyHome();
Config options = new Config();
options.setProperty("jetty.home",jettyHome);
options.parse(buf);
Classpath actual = options.getClasspath();
Classpath expected = new Classpath();
expected.addComponent(new File(getJettyHomeDir(),"resources"));
assertEquals("Simple Component",expected,actual);
}
/*
* Test for SUBJECT ending with ".xml", an XML Configuration File
*/
@Test
public void testSubjectXmlConfigAlt() throws IOException
{
StringBuffer buf = new StringBuffer();
// Doesn't exist
buf.append("$(jetty.home)/etc/jetty.xml nargs == 0\n");
// test-alt does exist.
buf.append("./src/test/resources/test-alt.xml nargs == 0 AND ! exists $(jetty.home)/etc/jetty.xml");
String jettyHome = getTestableJettyHome();
Config options = new Config();
options.setProperty("jetty.home",jettyHome);
options.parse(buf);
List<String> actual = options.getXmlConfigs();
String expected = new File("src/test/resources/test-alt.xml").getAbsolutePath();
Assert.assertEquals("XmlConfig.size",1,actual.size());
Assert.assertEquals(expected,actual.get(0));
}
/*
* Test for SUBJECT ending with ".xml", an XML Configuration File
*/
@Test
public void testSubjectXmlConfigDefault() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("$(jetty.home)/etc/test-jetty.xml nargs == 0\n");
buf.append("./jetty-server/src/main/config/etc/test-jetty.xml nargs == 0 AND ! exists $(jetty.home)/etc/test-jetty.xml");
String jettyHome = getTestableJettyHome();
Config options = new Config();
options.setProperty("jetty.home",jettyHome);
options.parse(buf);
List<String> actual = options.getXmlConfigs();
String expected = getJettyEtcFile("test-jetty.xml");
Assert.assertEquals("XmlConfig.size",1,actual.size());
Assert.assertEquals(expected,actual.get(0));
}
/*
* Test for SUBJECT ending with ".xml", an XML Configuration File.
*/
@Test
public void testSubjectXmlConfigMultiple() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("$(jetty.home)/etc/test-jetty.xml nargs == 0\n");
buf.append("$(jetty.home)/etc/test-jetty-ssl.xml nargs == 0\n");
buf.append("$(jetty.home)/etc/test-jetty-security.xml nargs == 0\n");
String jettyHome = getTestableJettyHome();
Config options = new Config();
options.setProperty("jetty.home",jettyHome);
options.parse(buf);
List<String> actual = options.getXmlConfigs();
List<String> expected = new ArrayList<String>();
expected.add(getJettyEtcFile("test-jetty.xml"));
expected.add(getJettyEtcFile("test-jetty-ssl.xml"));
expected.add(getJettyEtcFile("test-jetty-security.xml"));
assertEquals("Multiple XML Configs",expected,actual);
}
/*
* Test Section Handling
*/
@Test
public void testSectionClasspathSingle() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("[All]\n");
buf.append("$(jetty.home)/lib/core-test.jar\n");
buf.append("$(jetty.home)/lib/util.jar\n");
String jettyHome = getTestableJettyHome();
Config options = new Config();
options.setProperty("jetty.home",jettyHome);
options.parse(buf);
Classpath defaultClasspath = options.getClasspath();
Assert.assertNotNull("Default Classpath should not be null",defaultClasspath);
Classpath foocp = options.getSectionClasspath("Foo");
Assert.assertNull("Foo Classpath should not exist",foocp);
Classpath allcp = options.getSectionClasspath("All");
Assert.assertNotNull("Classpath section 'All' should exist",allcp);
File lib = new File(getJettyHomeDir(),"lib");
Classpath expected = new Classpath();
expected.addComponent(new File(lib,"core-test.jar"));
expected.addComponent(new File(lib,"util.jar"));
assertEquals("Single Classpath Section",expected,allcp);
}
/*
* Test Section Handling
*/
@Test
public void testSectionClasspathAvailable() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("[All]\n");
buf.append("$(jetty.home)/lib/core.jar ! available org.eclipse.jetty.dummy.Handler\n");
buf.append("$(jetty.home)/lib/util.jar ! available org.eclipse.jetty.dummy.StringUtils\n");
String jettyHome = getTestableJettyHome();
Config options = new Config();
options.setProperty("jetty.home",jettyHome);
options.parse(buf);
Classpath defaultClasspath = options.getClasspath();
Assert.assertNotNull("Default Classpath should not be null",defaultClasspath);
Classpath foocp = options.getSectionClasspath("Foo");
Assert.assertNull("Foo Classpath should not exist",foocp);
Classpath allcp = options.getSectionClasspath("All");
Assert.assertNotNull("Classpath section 'All' should exist",allcp);
File lib = new File(getJettyHomeDir(),"lib");
Classpath expected = new Classpath();
expected.addComponent(new File(lib,"core.jar"));
expected.addComponent(new File(lib,"util.jar"));
assertEquals("Single Classpath Section",expected,allcp);
}
/*
* Test Section Handling, with multiple defined sections.
*/
@Test
public void testSectionClasspathMultiples() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("# default\n");
buf.append("$(jetty.home)/lib/spec.zip\n");
buf.append("\n");
buf.append("[*]\n");
buf.append("$(jetty.home)/lib/io.jar\n");
buf.append("$(jetty.home)/lib/util.jar\n");
buf.append("\n");
buf.append("[All,server,default]\n");
buf.append("$(jetty.home)/lib/core.jar\n");
buf.append("$(jetty.home)/lib/server.jar\n");
buf.append("$(jetty.home)/lib/http.jar\n");
buf.append("\n");
buf.append("[All,xml,default]\n");
buf.append("$(jetty.home)/lib/xml.jar\n");
buf.append("\n");
buf.append("[All,logging]\n");
buf.append("$(jetty.home)/lib/LOGGING.JAR\n");
String jettyHome = getTestableJettyHome();
Config cfg = new Config();
cfg.setProperty("jetty.home",jettyHome);
cfg.parse(buf);
Classpath defaultClasspath = cfg.getClasspath();
Assert.assertNotNull("Default Classpath should not be null",defaultClasspath);
Classpath foocp = cfg.getSectionClasspath("Foo");
Assert.assertNull("Foo Classpath should not exist",foocp);
// Test if entire section list can be fetched
Set<String> sections = cfg.getSectionIds();
Set<String> expected = new HashSet<String>();
expected.add(Config.DEFAULT_SECTION);
expected.add("*");
expected.add("All");
expected.add("server");
expected.add("default");
expected.add("xml");
expected.add("logging");
assertEquals("Multiple Section IDs",expected,sections);
// Test fetch of specific section by name works
Classpath cpAll = cfg.getSectionClasspath("All");
Assert.assertNotNull("Classpath section 'All' should exist",cpAll);
File lib = new File(getJettyHomeDir(),"lib");
Classpath expectedAll = new Classpath();
expectedAll.addComponent(new File(lib,"core.jar"));
expectedAll.addComponent(new File(lib,"server.jar"));
expectedAll.addComponent(new File(lib,"http.jar"));
expectedAll.addComponent(new File(lib,"xml.jar"));
expectedAll.addComponent(new File(lib,"LOGGING.JAR"));
assertEquals("Classpath 'All' Section",expectedAll,cpAll);
// Test combined classpath fetch of multiple sections works
List<String> activated = new ArrayList<String>();
activated.add("server");
activated.add("logging");
Classpath cpCombined = cfg.getCombinedClasspath(activated);
Classpath expectedCombined = new Classpath();
// from default
expectedCombined.addComponent(new File(lib,"spec.zip"));
// from 'server'
expectedCombined.addComponent(new File(lib,"core.jar"));
expectedCombined.addComponent(new File(lib,"server.jar"));
expectedCombined.addComponent(new File(lib,"http.jar"));
// from 'logging'
expectedCombined.addComponent(new File(lib,"LOGGING.JAR"));
// from '*'
expectedCombined.addComponent(new File(lib,"io.jar"));
expectedCombined.addComponent(new File(lib,"util.jar"));
assertEquals("Classpath combined 'server,logging'",expectedCombined,cpCombined);
}
@Test
public void testDynamicSection() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("[All,default,=$(jetty.home)/lib/*]\n");
String jettyHome = getTestableJettyHome();
Config options = new Config();
options.setProperty("jetty.home",jettyHome);
options.parse(buf);
Classpath defaultClasspath = options.getClasspath();
Assert.assertNotNull("Default Classpath should not be null",defaultClasspath);
Classpath foocp = options.getSectionClasspath("foo");
Assert.assertNotNull("Foo Classpath should not exist",foocp);
Classpath allcp = options.getSectionClasspath("All");
Assert.assertNotNull("Classpath section 'All' should exist",allcp);
Classpath extcp = options.getSectionClasspath("ext");
Assert.assertNotNull("Classpath section 'ext' should exist", extcp);
Assert.assertEquals("Deep Classpath Section",0,foocp.count());
File lib = new File(getJettyHomeDir(),"lib");
File ext = new File(lib, "ext");
Classpath expected = new Classpath();
expected.addComponent(new File(ext,"custom-impl.jar"));
assertEquals("Single Classpath Section",expected,extcp);
}
@Test
public void testDeepDynamicSection() throws IOException
{
StringBuffer buf = new StringBuffer();
buf.append("[All,default,=$(jetty.home)/lib/**]\n");
String jettyHome = getTestableJettyHome();
Config options = new Config();
options.setProperty("jetty.home",jettyHome);
options.parse(buf);
Classpath defaultClasspath = options.getClasspath();
Assert.assertNotNull("Default Classpath should not be null",defaultClasspath);
Classpath foocp = options.getSectionClasspath("foo");
Assert.assertNotNull("Foo Classpath should not exist",foocp);
Classpath allcp = options.getSectionClasspath("All");
Assert.assertNotNull("Classpath section 'All' should exist",allcp);
Classpath extcp = options.getSectionClasspath("ext");
Assert.assertNotNull("Classpath section 'ext' should exist", extcp);
File lib = new File(getJettyHomeDir(),"lib");
Classpath expected = new Classpath();
File foo = new File(lib, "foo");
File bar = new File(foo, "bar");
expected.addComponent(new File(bar,"foobar.jar"));
assertEquals("Deep Classpath Section",expected,foocp);
File ext = new File(lib, "ext");
expected = new Classpath();
expected.addComponent(new File(ext,"custom-impl.jar"));
assertEquals("Single Classpath Section",expected,extcp);
}
}

View File

@ -0,0 +1,115 @@
//
// ========================================================================
// Copyright (c) 1995-2013 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.start;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.junit.Assert;
public class ConfigurationAssert
{
/**
* Given a provided StartArgs, assert that the configuration it has determined is valid based on values in a assert text file.
*
* @param baseHome
* the BaseHome used. Access it via {@link Main#getBaseHome()}
* @param args
* the StartArgs that has been processed via {@link Main#processCommandLine(String[])}
* @param filename
* the filename of the assertion values
* @throws IOException
*/
public static void assertConfiguration(BaseHome baseHome, StartArgs args, String filename) throws FileNotFoundException, IOException
{
File file = MavenTestingUtils.getTestResourceFile(filename);
TextFile textFile = new TextFile(file);
// Validate XMLs (order is important)
List<String> expectedXmls = new ArrayList<>();
for (String line : textFile)
{
if (line.startsWith("XML|"))
{
expectedXmls.add(getValue(line));
}
}
List<String> actualXmls = new ArrayList<>();
for (File xml : args.getXmlFiles())
{
actualXmls.add(baseHome.toShortForm(xml));
}
assertThat("XML Resolution Order " + actualXmls,actualXmls,contains(expectedXmls.toArray()));
// Validate LIBs (order is not important)
Set<String> expectedLibs = new HashSet<>();
for (String line : textFile)
{
if (line.startsWith("LIB|"))
{
expectedLibs.add(getValue(line));
}
}
Set<String> actualLibs = new HashSet<>();
for (File path : args.getClasspath())
{
actualLibs.add(baseHome.toShortForm(path));
}
assertThat("Libs " + actualLibs,actualLibs,containsInAnyOrder(expectedLibs.toArray()));
// Validate PROPERTIES (order is not important)
Set<String> expectedProperties = new HashSet<>();
for (String line : textFile)
{
if (line.startsWith("PROP|"))
{
expectedProperties.add(getValue(line));
}
}
Set<String> actualProperties = new HashSet<>();
@SuppressWarnings("unchecked")
Enumeration<String> nameEnum = (Enumeration<String>)args.getProperties().propertyNames();
while (nameEnum.hasMoreElements())
{
String name = nameEnum.nextElement();
String value = args.getProperties().getProperty(name);
actualProperties.add(name + "=" + value);
}
assertThat("Properties " + actualProperties,actualProperties,containsInAnyOrder(expectedProperties.toArray()));
}
private static String getValue(String arg)
{
int idx = arg.indexOf('|');
Assert.assertThat("Expecting '|' sign in [" + arg + "]",idx,greaterThanOrEqualTo(0));
String value = arg.substring(idx + 1).trim();
Assert.assertThat("Expecting Value after '|' in [" + arg + "]",value.length(),greaterThan(0));
return value;
}
}

View File

@ -18,111 +18,85 @@
package org.eclipse.jetty.start;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.junit.Before;
import org.junit.Test;
/* ------------------------------------------------------------ */
/**
*/
public class MainTest
{
/* ------------------------------------------------------------ */
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception
{
File testJettyHome = MavenTestingUtils.getTestResourceDir("jetty.home");
File testJettyHome = MavenTestingUtils.getTestResourceDir("usecases/home");
System.setProperty("jetty.home",testJettyHome.getAbsolutePath());
}
@Test
public void testProcessCommandLine() throws Exception
public void testBasicProcessing() throws Exception
{
Main main = new Main();
List<String> xmls = main.processCommandLine(new String[] {});
System.err.println(xmls);
// Order is important here
List<String> expectedXmls = new ArrayList<String>();
expectedXmls.add("etc/jetty.xml"); // from start.ini
expectedXmls.add("etc/jetty-deploy.xml"); // from start.ini
expectedXmls.add("etc/jetty-webapps.xml"); // from start.ini
expectedXmls.add("etc/jetty-contexts.xml"); // from start.ini
expectedXmls.add("etc/jetty-jmx.xml"); // from start.d/10-jmx.ini
expectedXmls.add("etc/jetty-testrealm.xml"); // from start.d/90-testrealm.ini
StartArgs args = main.processCommandLine(new String[]
{ "jetty.port=9090" });
BaseHome baseHome = main.getBaseHome();
System.err.println(args);
assertThat("XML Resolution Order " + xmls,xmls,contains(expectedXmls.toArray()));
// Order is irrelevant here
Set<String> options = main.getConfig().getOptions();
Set<String> expectedOptions = new HashSet<>();
// from start.ini
expectedOptions.add("Server");
expectedOptions.add("jsp");
expectedOptions.add("resources");
expectedOptions.add("websocket");
expectedOptions.add("ext");
expectedOptions.add("newOption");
// from start.d/10-jmx.ini
expectedOptions.add("jmx");
// from start.d/20-websocket.ini
expectedOptions.add("websocket");
// no options from start.d/90-testrealm.ini
assertThat("Options " + options,options,containsInAnyOrder(expectedOptions.toArray()));
ConfigurationAssert.assertConfiguration(baseHome,args,"assert-home.txt");
}
@Test
public void testBuildCommandLine() throws IOException, NoSuchFieldException, IllegalAccessException
public void testWithCommandLine() throws Exception
{
List<String> jvmArgs = new ArrayList<String>();
jvmArgs.add("--exec");
jvmArgs.add("-Xms1024m");
jvmArgs.add("-Xmx1024m");
List<String> cmdLineArgs = new ArrayList<>();
List<String> xmls = new ArrayList<String>();
xmls.add("jetty.xml");
xmls.add("jetty-jmx.xml");
xmls.add("jetty-logging.xml");
// JVM args
cmdLineArgs.add("--exec");
cmdLineArgs.add("-Xms1024m");
cmdLineArgs.add("-Xmx1024m");
// Arbitrary XMLs
cmdLineArgs.add("jetty.xml");
cmdLineArgs.add("jetty-jmx.xml");
cmdLineArgs.add("jetty-logging.xml");
Main main = new Main();
main.addJvmArgs(jvmArgs);
Classpath classpath = nastyWayToCreateAClasspathObject("/jetty/home with spaces/");
CommandLineBuilder cmd = main.buildCommandLine(classpath,xmls);
assertThat("CommandLineBuilder shouldn't be null",cmd,notNullValue());
StartArgs args = main.processCommandLine(cmdLineArgs.toArray(new String[6]));
BaseHome baseHome = main.getBaseHome();
System.err.println(args);
List<String> commandArgs = cmd.getArgs();
assertThat("commandArgs elements",commandArgs.size(),equalTo(12));
assertThat("args does not contain -cp",commandArgs,hasItems("-cp"));
assertThat("Classpath should be correctly quoted and match expected value",commandArgs,
hasItems("/jetty/home with spaces/somejar.jar:/jetty/home with spaces/someotherjar.jar"));
assertThat("args does not contain --exec",commandArgs,hasItems("--exec"));
assertThat("CommandLine should contain jvmArgs",commandArgs,hasItems("-Xms1024m"));
assertThat("CommandLine should contain jvmArgs",commandArgs,hasItems("-Xmx1024m"));
assertThat("CommandLine should contain xmls",commandArgs,hasItems("jetty.xml"));
assertThat("CommandLine should contain xmls",commandArgs,hasItems("jetty-jmx.xml"));
assertThat("CommandLine should contain xmls",commandArgs,hasItems("jetty-logging.xml"));
ConfigurationAssert.assertConfiguration(baseHome,args,"assert-home-with-jvm.txt");
}
String commandLine = cmd.toString();
assertThat("cmd.toString() should be properly escaped",commandLine,containsString("-cp /jetty/home\\ with\\ "
+ "spaces/somejar.jar:/jetty/home\\ with\\ spaces/someotherjar.jar"));
assertThat("cmd.toString() doesn't contain xml config files",commandLine,containsString(" jetty.xml jetty-jmx.xml jetty-logging.xml"));
public void testJettyHomeWithSpaces()
{
// main.addJvmArgs(jvmArgs);
//
// Classpath classpath = nastyWayToCreateAClasspathObject("/jetty/home with spaces/");
// CommandLineBuilder cmd = main.buildCommandLine(classpath,xmls);
// assertThat("CommandLineBuilder shouldn't be null",cmd,notNullValue());
//
// List<String> commandArgs = cmd.getArgs();
// assertThat("commandArgs elements",commandArgs.size(),equalTo(12));
// assertThat("args does not contain -cp",commandArgs,hasItems("-cp"));
// assertThat("Classpath should be correctly quoted and match expected value",commandArgs,
// hasItems("/jetty/home with spaces/somejar.jar:/jetty/home with spaces/someotherjar.jar"));
// assertThat("args does not contain --exec",commandArgs,hasItems("--exec"));
// assertThat("CommandLine should contain jvmArgs",commandArgs,hasItems("-Xms1024m"));
// assertThat("CommandLine should contain jvmArgs",commandArgs,hasItems("-Xmx1024m"));
// assertThat("CommandLine should contain xmls",commandArgs,hasItems("jetty.xml"));
// assertThat("CommandLine should contain xmls",commandArgs,hasItems("jetty-jmx.xml"));
// assertThat("CommandLine should contain xmls",commandArgs,hasItems("jetty-logging.xml"));
//
// String commandLine = cmd.toString();
// assertThat("cmd.toString() should be properly escaped",commandLine,containsString("-cp /jetty/home\\ with\\ "
// + "spaces/somejar.jar:/jetty/home\\ with\\ spaces/someotherjar.jar"));
// assertThat("cmd.toString() doesn't contain xml config files",commandLine,containsString(" jetty.xml jetty-jmx.xml jetty-logging.xml"));
}
private Classpath nastyWayToCreateAClasspathObject(String jettyHome) throws NoSuchFieldException, IllegalAccessException

View File

@ -32,7 +32,7 @@ public class ModuleTest
private Module loadTestHomeModule(String moduleFileName) throws IOException
{
File file = MavenTestingUtils.getTestResourceFile("usecases/home/modules/" + moduleFileName);
return Module.fromFile(file);
return new Module(file);
}
@Test
@ -44,7 +44,7 @@ public class ModuleTest
Assert.assertThat("Module Parents Size",Module.getParentNames().size(),is(2));
Assert.assertThat("Module Parents",Module.getParentNames(),containsInAnyOrder("annotations","server"));
Assert.assertThat("Module Xmls Size",Module.getXmls().size(),is(1));
Assert.assertThat("Module Xmls",Module.getXmls(),contains("etc/jetty-websocket.xml"));
Assert.assertThat("Module Xmls",Module.getXmls(),contains("etc/jetty-websockets.xml"));
Assert.assertThat("Module Options Size",Module.getLibs().size(),is(1));
Assert.assertThat("Module Options",Module.getLibs(),contains("lib/websockets/*.jar"));
}

View File

@ -39,7 +39,7 @@ public class ModulesTest
Modules modules = new Modules();
modules.registerAll(basehome);
Assert.assertThat("Module count",modules.count(),is(11));
Assert.assertThat("Module count",modules.count(),is(26));
}
@Test
@ -63,6 +63,7 @@ public class ModulesTest
// Assert names are correct, and in the right order
List<String> expectedNames = new ArrayList<>();
expectedNames.add("base");
expectedNames.add("xml");
expectedNames.add("server");
expectedNames.add("http");
@ -78,6 +79,7 @@ public class ModulesTest
List<String> expectedLibs = new ArrayList<>();
expectedLibs.add("lib/jetty-util-${jetty.version}.jar");
expectedLibs.add("lib/jetty-io-${jetty.version}.jar");
expectedLibs.add("lib/jetty-xml-${jetty.version}.jar");
expectedLibs.add("lib/servlet-api-3.1.jar");
expectedLibs.add("lib/jetty-schemas-3.1.jar");
expectedLibs.add("lib/jetty-http-${jetty.version}.jar");
@ -118,8 +120,11 @@ public class ModulesTest
// Assert names are correct, and in the right order
List<String> expectedNames = new ArrayList<>();
expectedNames.add("base");
expectedNames.add("xml");
expectedNames.add("server");
expectedNames.add("http");
expectedNames.add("jndi");
expectedNames.add("security");
expectedNames.add("plus");
expectedNames.add("annotations");
expectedNames.add("websocket");
@ -136,12 +141,16 @@ public class ModulesTest
List<String> expectedLibs = new ArrayList<>();
expectedLibs.add("lib/jetty-util-${jetty.version}.jar");
expectedLibs.add("lib/jetty-io-${jetty.version}.jar");
expectedLibs.add("lib/jetty-xml-${jetty.version}.jar");
expectedLibs.add("lib/servlet-api-3.1.jar");
expectedLibs.add("lib/jetty-schemas-3.1.jar");
expectedLibs.add("lib/jetty-http-${jetty.version}.jar");
expectedLibs.add("lib/jetty-continuation-${jetty.version}.jar");
expectedLibs.add("lib/jetty-server-${jetty.version}.jar");
expectedLibs.add("lib/jetty-plus-${jetty.version}.xml");
expectedLibs.add("lib/jetty-jndi-${jetty.version}.jar");
expectedLibs.add("lib/jndi/*.jar");
expectedLibs.add("lib/jetty-security-${jetty.version}.jar");
expectedLibs.add("lib/jetty-plus-${jetty.version}.jar");
expectedLibs.add("lib/jetty-annotations-${jetty.version}.jar");
expectedLibs.add("lib/annotations/*.jar");
expectedLibs.add("lib/websockets/*.jar");
@ -155,7 +164,7 @@ public class ModulesTest
expectedXmls.add("etc/jetty-http.xml");
expectedXmls.add("etc/jetty-plus.xml");
expectedXmls.add("etc/jetty-annotations.xml");
expectedXmls.add("etc/jetty-websocket.xml");
expectedXmls.add("etc/jetty-websockets.xml");
List<String> actualXmls = modules.normalizeXmls(active);
Assert.assertThat("Resolved XMLs: " + actualXmls,actualXmls,contains(expectedXmls.toArray()));

View File

@ -18,6 +18,10 @@
package org.eclipse.jetty.start;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Properties;
@ -25,6 +29,7 @@ public class PropertyDump
{
public static void main(String[] args)
{
// As System Properties
Properties props = System.getProperties();
Enumeration<?> names = props.propertyNames();
while (names.hasMoreElements())
@ -36,6 +41,35 @@ public class PropertyDump
System.out.printf("%s=%s%n",name,props.getProperty(name));
}
}
// As File Argument
for (String arg : args)
{
if (arg.endsWith(".properties"))
{
Properties aprops = new Properties();
File propFile = new File(arg);
System.out.printf("[load file %s]%n",propFile.getName());
try (FileReader reader = new FileReader(propFile))
{
aprops.load(reader);
Enumeration<?> anames = aprops.propertyNames();
while (anames.hasMoreElements())
{
String name = (String)anames.nextElement();
if (name.startsWith("test."))
{
System.out.printf("%s=%s%n",name,aprops.getProperty(name));
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
System.exit(0);
}
}

View File

@ -32,10 +32,8 @@ import java.util.List;
import org.eclipse.jetty.toolchain.test.IO;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.toolchain.test.OS;
import org.eclipse.jetty.toolchain.test.TestingDir;
import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
@ -94,18 +92,17 @@ public class PropertyPassingTest
@Test
public void testAsJvmArg() throws IOException, InterruptedException
{
File testCfg = MavenTestingUtils.getTestResourceFile("property-dump-start.config");
File bogusXml = MavenTestingUtils.getTestResourceFile("bogus.xml");
// Setup command line
List<String> commands = new ArrayList<>();
commands.add(getJavaBin());
commands.add("-Dmain.class=" + PropertyDump.class.getName());
commands.add("-cp");
commands.add(getClassPath());
// addDebug(commands);
commands.add("-Dtest.foo=bar"); // TESTING THIS
commands.add(getStartJarBin());
commands.add("--config=" + testCfg.getAbsolutePath());
commands.add(bogusXml.getAbsolutePath());
// Run command, collect output
@ -116,21 +113,19 @@ public class PropertyPassingTest
}
@Test
@Ignore("not working yet")
public void testAsCommandLineArg() throws IOException, InterruptedException
{
File testCfg = MavenTestingUtils.getTestResourceFile("property-dump-start.config");
File bogusXml = MavenTestingUtils.getTestResourceFile("bogus.xml");
// Setup command line
List<String> commands = new ArrayList<>();
commands.add(getJavaBin());
commands.add("-Dmain.class=" + PropertyDump.class.getName());
commands.add("-cp");
commands.add(getClassPath());
// addDebug(commands);
commands.add(getStartJarBin());
commands.add("test.foo=bar"); // TESTING THIS
commands.add("--config=" + testCfg.getAbsolutePath());
commands.add(bogusXml.getAbsolutePath());
// Run command, collect output
@ -143,18 +138,17 @@ public class PropertyPassingTest
@Test
public void testAsDashDCommandLineArg() throws IOException, InterruptedException
{
File testCfg = MavenTestingUtils.getTestResourceFile("property-dump-start.config");
File bogusXml = MavenTestingUtils.getTestResourceFile("bogus.xml");
// Setup command line
List<String> commands = new ArrayList<>();
commands.add(getJavaBin());
commands.add("-Dmain.class=" + PropertyDump.class.getName());
commands.add("-cp");
commands.add(getClassPath());
// addDebug(commands);
commands.add(getStartJarBin());
commands.add("-Dtest.foo=bar"); // TESTING THIS
commands.add("--config=" + testCfg.getAbsolutePath());
commands.add(bogusXml.getAbsolutePath());
// Run command, collect output
@ -198,7 +192,8 @@ public class PropertyPassingTest
ConsoleCapture stdErrPump = new ConsoleCapture("STDERR",pid.getErrorStream()).start();
int exitCode = pid.waitFor();
if(exitCode != 0) {
if (exitCode != 0)
{
System.out.printf("STDERR: [" + stdErrPump.getConsoleOutput() + "]%n");
System.out.printf("STDOUT: [" + stdOutPump.getConsoleOutput() + "]%n");
Assert.assertThat("Exit code",exitCode,is(0));
@ -213,35 +208,6 @@ public class PropertyPassingTest
private String getJavaBin()
{
File javaHome = new File(System.getProperty("java.home"));
if (!javaHome.exists())
{
return null;
}
File javabin = findExecutable(javaHome,"bin/java");
if (javabin != null)
{
return javabin.getAbsolutePath();
}
javabin = findExecutable(javaHome,"bin/java.exe");
if (javabin != null)
{
return javabin.getAbsolutePath();
}
return "java";
}
private File findExecutable(File root, String path)
{
String npath = OS.separators(path);
File exe = new File(root,npath);
if (!exe.exists())
{
return null;
}
return exe;
return CommandLineBuilder.findJavaBin();
}
}

View File

@ -0,0 +1,34 @@
# The XMLs we expect (order is important)
XML|${jetty.home}/etc/jetty-jmx.xml
XML|${jetty.home}/etc/jetty.xml
XML|${jetty.home}/etc/jetty-http.xml
XML|${jetty.home}/etc/jetty-plus.xml
XML|${jetty.home}/etc/jetty-annotations.xml
XML|${jetty.home}/etc/jetty-websockets.xml
XML|${jetty.home}/etc/jetty-logging.xml
# The LIBs we expect (order is irrelevant)
LIB|${jetty.home}/lib/annotations/javax.annotation-api-1.2.jar
LIB|${jetty.home}/lib/annotations/org.objectweb.asm-TEST.jar
LIB|${jetty.home}/lib/jetty-annotations-TEST.jar
LIB|${jetty.home}/lib/jetty-continuation-TEST.jar
LIB|${jetty.home}/lib/jetty-http-TEST.jar
LIB|${jetty.home}/lib/jetty-io-TEST.jar
LIB|${jetty.home}/lib/jetty-jmx-TEST.jar
LIB|${jetty.home}/lib/jetty-jndi-TEST.jar
LIB|${jetty.home}/lib/jetty-plus-TEST.jar
LIB|${jetty.home}/lib/jetty-schemas-3.1.jar
LIB|${jetty.home}/lib/jetty-security-TEST.jar
LIB|${jetty.home}/lib/jetty-server-TEST.jar
LIB|${jetty.home}/lib/jetty-util-TEST.jar
LIB|${jetty.home}/lib/jetty-xml-TEST.jar
LIB|${jetty.home}/lib/jndi/javax.activation-1.1.jar
LIB|${jetty.home}/lib/jndi/javax.transaction-api-1.2.jar
LIB|${jetty.home}/lib/servlet-api-3.1.jar
# The Properties we expect (order is irrelevant)
# PROP|jetty.port=9090
# JVM Args
JVM|-Xms1024m
JVM|-Xms1024m

View File

@ -0,0 +1,29 @@
# The XMLs we expect (order is important)
XML|${jetty.home}/etc/jetty-jmx.xml
XML|${jetty.home}/etc/jetty.xml
XML|${jetty.home}/etc/jetty-http.xml
XML|${jetty.home}/etc/jetty-plus.xml
XML|${jetty.home}/etc/jetty-annotations.xml
XML|${jetty.home}/etc/jetty-websockets.xml
# The LIBs we expect (order is irrelevant)
LIB|${jetty.home}/lib/annotations/javax.annotation-api-1.2.jar
LIB|${jetty.home}/lib/annotations/org.objectweb.asm-TEST.jar
LIB|${jetty.home}/lib/jetty-annotations-TEST.jar
LIB|${jetty.home}/lib/jetty-continuation-TEST.jar
LIB|${jetty.home}/lib/jetty-http-TEST.jar
LIB|${jetty.home}/lib/jetty-io-TEST.jar
LIB|${jetty.home}/lib/jetty-jmx-TEST.jar
LIB|${jetty.home}/lib/jetty-jndi-TEST.jar
LIB|${jetty.home}/lib/jetty-plus-TEST.jar
LIB|${jetty.home}/lib/jetty-schemas-3.1.jar
LIB|${jetty.home}/lib/jetty-security-TEST.jar
LIB|${jetty.home}/lib/jetty-server-TEST.jar
LIB|${jetty.home}/lib/jetty-util-TEST.jar
LIB|${jetty.home}/lib/jetty-xml-TEST.jar
LIB|${jetty.home}/lib/jndi/javax.activation-1.1.jar
LIB|${jetty.home}/lib/jndi/javax.transaction-api-1.2.jar
LIB|${jetty.home}/lib/servlet-api-3.1.jar
# The Properties we expect (order is irrelevant)
PROP|jetty.port=9090

View File

@ -1,8 +0,0 @@
org.eclipse.jetty.start.PropertyDump.class
[*]
$(basedir)/src/test/resources
[default]
$(basedir)/src/test/resources

View File

@ -1 +0,0 @@
<!-- nothing in here, just used to test the start.config logic in ConfigTest.java -->

Some files were not shown because too many files have changed in this diff Show More