aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@gmail.com>2013-10-01 16:51:37 +0200
committerSimon Brandhof <simon.brandhof@gmail.com>2013-10-01 16:51:57 +0200
commitaf19a257160eae52f2f5a08cfb979625a9cf5cff (patch)
tree3aa8ecd06fd0f57619c98b4bbc133dab8b96aeef
parent3a9dfb1fd7e4c854da5eab3d041e70b27e9c709c (diff)
downloadsonarqube-af19a257160eae52f2f5a08cfb979625a9cf5cff.tar.gz
sonarqube-af19a257160eae52f2f5a08cfb979625a9cf5cff.zip
SONAR-4675 Replace Jetty web server by Tomcat 7
-rw-r--r--plugins/sonar-core-plugin/pom.xml5
-rw-r--r--plugins/sonar-cpd-plugin/pom.xml5
-rw-r--r--plugins/sonar-dbcleaner-plugin/pom.xml5
-rw-r--r--plugins/sonar-maven-batch-plugin/pom.xml5
-rw-r--r--pom.xml89
-rw-r--r--sonar-application/pom.xml94
-rw-r--r--sonar-application/src/main/assembly/conf/logback-access.xml25
-rw-r--r--sonar-application/src/main/assembly/conf/logback.xml25
-rw-r--r--sonar-application/src/main/assembly/conf/sonar.properties59
-rw-r--r--sonar-application/src/main/assembly/conf/wrapper.conf4
-rw-r--r--sonar-application/src/main/java/org/sonar/application/Connectors.java69
-rw-r--r--sonar-application/src/main/java/org/sonar/application/EmbeddedTomcat.java112
-rw-r--r--sonar-application/src/main/java/org/sonar/application/Env.java69
-rw-r--r--sonar-application/src/main/java/org/sonar/application/JettyEmbedder.java196
-rw-r--r--sonar-application/src/main/java/org/sonar/application/Logging.java50
-rw-r--r--sonar-application/src/main/java/org/sonar/application/NullJarScanner.java35
-rw-r--r--sonar-application/src/main/java/org/sonar/application/Props.java84
-rw-r--r--sonar-application/src/main/java/org/sonar/application/StartServer.java62
-rw-r--r--sonar-application/src/main/java/org/sonar/application/Webapp.java39
-rw-r--r--sonar-application/src/main/java/org/sonar/application/package-info.java23
-rw-r--r--sonar-application/src/main/resources/org/sonar/application/webdefault.xml347
-rw-r--r--sonar-application/src/test/fake-app/conf/logback-access.xml17
-rw-r--r--sonar-application/src/test/fake-app/conf/sonar.properties2
-rw-r--r--sonar-application/src/test/fake-app/web/META-INF/context.xml2
-rw-r--r--sonar-application/src/test/fake-app/web/WEB-INF/web.xml11
-rw-r--r--sonar-application/src/test/fake-app/web/index.html1
-rw-r--r--sonar-application/src/test/java/org/sonar/application/ConnectorsTest.java102
-rw-r--r--sonar-application/src/test/java/org/sonar/application/EnvTest.java80
-rw-r--r--sonar-application/src/test/java/org/sonar/application/JettyEmbedderTest.java52
-rw-r--r--sonar-application/src/test/java/org/sonar/application/LoggingTest.java68
-rw-r--r--sonar-application/src/test/java/org/sonar/application/NullJarScannerTest.java43
-rw-r--r--sonar-application/src/test/java/org/sonar/application/PropsTest.java98
-rw-r--r--sonar-application/src/test/java/org/sonar/application/StartServerTest.java150
-rw-r--r--sonar-application/src/test/resources/org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath/foo.xml0
-rw-r--r--sonar-application/src/test/resources/org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath/plugin1.jar0
-rw-r--r--sonar-application/src/test/resources/org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath/plugin2.jar0
-rw-r--r--sonar-application/src/test/resources/org/sonar/application/LoggingTest/logback-access.xml1
-rw-r--r--sonar-application/src/test/resources/org/sonar/application/PropsTest/sonar.properties2
-rw-r--r--sonar-batch/pom.xml9
-rw-r--r--sonar-core/pom.xml5
-rw-r--r--sonar-plugin-api/pom.xml10
-rwxr-xr-xsonar-server/h2-start.sh2
-rw-r--r--sonar-server/pom.xml46
-rw-r--r--sonar-server/src/dev/web.xml4
-rw-r--r--sonar-server/src/dev/webdefault.xml507
-rw-r--r--sonar-server/src/main/java/org/sonar/server/startup/GenerateBootstrapIndex.java2
-rw-r--r--sonar-server/src/main/webapp/META-INF/context.xml7
-rw-r--r--sonar-server/src/main/webapp/WEB-INF/web.xml30
-rw-r--r--sonar-server/src/test/java/org/sonar/server/startup/GenerateBootstrapIndexTest.java1
-rw-r--r--sonar-ws-client/pom.xml4
50 files changed, 1351 insertions, 1307 deletions
diff --git a/plugins/sonar-core-plugin/pom.xml b/plugins/sonar-core-plugin/pom.xml
index e60b525073b..62e52bb27b5 100644
--- a/plugins/sonar-core-plugin/pom.xml
+++ b/plugins/sonar-core-plugin/pom.xml
@@ -14,6 +14,11 @@
<dependencies>
<dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-plugin-api</artifactId>
<scope>provided</scope>
diff --git a/plugins/sonar-cpd-plugin/pom.xml b/plugins/sonar-cpd-plugin/pom.xml
index 515bac9c499..aa0cc61f45f 100644
--- a/plugins/sonar-cpd-plugin/pom.xml
+++ b/plugins/sonar-cpd-plugin/pom.xml
@@ -21,6 +21,11 @@
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
+ </dependency>
<dependency>
<groupId>org.codehaus.sonar</groupId>
diff --git a/plugins/sonar-dbcleaner-plugin/pom.xml b/plugins/sonar-dbcleaner-plugin/pom.xml
index 5a8aa31481e..18525c8a320 100644
--- a/plugins/sonar-dbcleaner-plugin/pom.xml
+++ b/plugins/sonar-dbcleaner-plugin/pom.xml
@@ -16,6 +16,11 @@
<dependencies>
<dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-plugin-api</artifactId>
<scope>provided</scope>
diff --git a/plugins/sonar-maven-batch-plugin/pom.xml b/plugins/sonar-maven-batch-plugin/pom.xml
index c2406654a14..ac25b80072a 100644
--- a/plugins/sonar-maven-batch-plugin/pom.xml
+++ b/plugins/sonar-maven-batch-plugin/pom.xml
@@ -19,6 +19,11 @@
<dependencies>
<dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-batch</artifactId>
<version>${project.version}</version>
diff --git a/pom.xml b/pom.xml
index f7f37af0a1e..0e56cb71531 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,7 +7,7 @@
<packaging>pom</packaging>
<version>4.0-SNAPSHOT</version>
<name>SonarQube</name>
- <url>http://www.sonarsource.org/</url>
+ <url>http://www.sonarqube.org/</url>
<description>Open source platform for continuous inspection of code quality</description>
<modules>
@@ -76,6 +76,9 @@
<sonarGwt.version>3.3.1</sonarGwt.version>
<h2.version>1.3.172</h2.version>
<jetty.version>8.1.12.v20130726</jetty.version>
+ <logback.version>1.0.13</logback.version>
+ <slf4j.version>1.7.5</slf4j.version>
+ <tomcat.version>7.0.42</tomcat.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.min.version>3.0.5</maven.min.version>
<maven.api.version>2.2.0</maven.api.version>
@@ -658,6 +661,12 @@
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>10.0.1</version>
+ <exclusions>
+ <exclusion>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
@@ -788,27 +797,37 @@
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
- <version>1.6.2</version>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jul-to-slf4j</artifactId>
+ <version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
- <version>1.6.2</version>
+ <version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
- <version>1.6.2</version>
+ <version>${slf4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-access</artifactId>
+ <version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
- <version>0.9.30</version>
+ <version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
- <version>0.9.30</version>
+ <version>${logback.version}</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
@@ -920,6 +939,14 @@
<groupId>classworlds</groupId>
<artifactId>classworlds</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </exclusion>
+ <exclusion>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-core</artifactId>
+ </exclusion>
</exclusions>
</dependency>
<dependency>
@@ -959,9 +986,9 @@
<version>3.0.1</version>
</dependency>
<dependency>
- <groupId>org.mortbay.jetty</groupId>
- <artifactId>servlet-api</artifactId>
- <version>3.0.20100224</version>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <version>3.0.1</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
@@ -969,21 +996,6 @@
<version>${jetty.version}</version>
</dependency>
<dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-webapp</artifactId>
- <version>${jetty.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-util</artifactId>
- <version>${jetty.version}</version>
- </dependency>
- <dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-servlets</artifactId>
- <version>${jetty.version}</version>
- </dependency>
- <dependency>
<groupId>org.skyscreamer</groupId>
<artifactId>jsonassert</artifactId>
<version>1.2.0</version>
@@ -1065,6 +1077,35 @@
<artifactId>sonar-runner-api</artifactId>
<version>2.3</version>
</dependency>
+
+ <!-- tomcat -->
+ <dependency>
+ <groupId>org.apache.tomcat.embed</groupId>
+ <artifactId>tomcat-embed-core</artifactId>
+ <version>${tomcat.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat.embed</groupId>
+ <artifactId>tomcat-embed-jasper</artifactId>
+ <version>${tomcat.version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>org.eclipse.jdt.core.compiler</groupId>
+ <artifactId>ecj</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat.embed</groupId>
+ <artifactId>tomcat-embed-logging-juli</artifactId>
+ <version>${tomcat.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat.embed</groupId>
+ <artifactId>tomcat-embed-logging-juli</artifactId>
+ <version>${tomcat.version}</version>
+ </dependency>
+
</dependencies>
</dependencyManagement>
diff --git a/sonar-application/pom.xml b/sonar-application/pom.xml
index 5a9e17e4cd8..66290c24389 100644
--- a/sonar-application/pom.xml
+++ b/sonar-application/pom.xml
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<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/xsd/maven-4.0.0.xsd">
+<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
@@ -16,37 +17,62 @@
<dependencies>
<dependency>
- <groupId>org.codehaus.sonar</groupId>
- <artifactId>sonar-server</artifactId>
- <version>${project.version}</version>
- <type>war</type>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
</dependency>
<dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-server</artifactId>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
</dependency>
<dependency>
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-webapp</artifactId>
+ <groupId>org.slf4j</groupId>
+ <artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
+ <groupId>org.slf4j</groupId>
+ <artifactId>jul-to-slf4j</artifactId>
</dependency>
<dependency>
- <groupId>commons-lang</groupId>
- <artifactId>commons-lang</artifactId>
- <scope>test</scope>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-access</artifactId>
</dependency>
<dependency>
- <groupId>org.codehaus.sonar</groupId>
- <artifactId>sonar-testing-harness</artifactId>
- <scope>test</scope>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-classic</artifactId>
</dependency>
<dependency>
- <groupId>org.mortbay.jetty</groupId>
- <artifactId>servlet-api</artifactId>
- <scope>test</scope>
+ <groupId>ch.qos.logback</groupId>
+ <artifactId>logback-core</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat.embed</groupId>
+ <artifactId>tomcat-embed-core</artifactId>
+ </dependency>
+ <dependency>
+ <!-- TODO remove this unused dependency, but how to disable Jasper in embedded tomcat ? -->
+ <groupId>org.apache.tomcat.embed</groupId>
+ <artifactId>tomcat-embed-jasper</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.tomcat.embed</groupId>
+ <artifactId>tomcat-embed-logging-juli</artifactId>
+ </dependency>
+ <!--
+ TODO
+ <dependency>
+ <groupId>org.apache.tomcat</groupId>
+ <artifactId>tomcat-dbcp</artifactId>
+ <version>${tomcat.version}</version>
+ </dependency>
+ -->
+
+
+ <dependency>
+ <groupId>org.codehaus.sonar</groupId>
+ <artifactId>sonar-server</artifactId>
+ <version>${project.version}</version>
+ <type>war</type>
</dependency>
<dependency>
<groupId>mysql</groupId>
@@ -161,7 +187,6 @@
<type>sonar-plugin</type>
<scope>runtime</scope>
</dependency>
-
<dependency>
<groupId>org.sonatype.jsw-binaries</groupId>
<artifactId>jsw-binaries</artifactId>
@@ -170,11 +195,34 @@
<scope>provided</scope>
</dependency>
<dependency>
+ <!-- do not upgrade because of licensing change -->
<groupId>tanukisoft</groupId>
<artifactId>wrapper</artifactId>
<version>3.2.3</version>
<scope>runtime</scope>
</dependency>
+
+ <!-- unit tests -->
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.easytesting</groupId>
+ <artifactId>fest-assert</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-all</artifactId>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.github.kevinsawicki</groupId>
+ <artifactId>http-request</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
@@ -204,8 +252,8 @@
<phase>package</phase>
<configuration>
<target>
- <checksum file="${project.build.directory}/sonar-${project.version}.zip" algorithm="md5" />
- <checksum file="${project.build.directory}/sonar-${project.version}.zip" algorithm="sha" />
+ <checksum file="${project.build.directory}/sonar-${project.version}.zip" algorithm="md5"/>
+ <checksum file="${project.build.directory}/sonar-${project.version}.zip" algorithm="sha"/>
</target>
</configuration>
<goals>
diff --git a/sonar-application/src/main/assembly/conf/logback-access.xml b/sonar-application/src/main/assembly/conf/logback-access.xml
new file mode 100644
index 00000000000..8e2f63b3cd9
--- /dev/null
+++ b/sonar-application/src/main/assembly/conf/logback-access.xml
@@ -0,0 +1,25 @@
+<!--
+
+ See http://logback.qos.ch/access.html#configuration
+
+-->
+<configuration debug="false">
+ <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/>
+
+ <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+ <file>${SONAR_HOME}/logs/access.log</file>
+ <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+ <param name="FileNamePattern" value="${SONAR_HOME}/logs/access.%i.log"/>
+ <param name="MinIndex" value="1"/>
+ <param name="MaxIndex" value="3"/>
+ </rollingPolicy>
+ <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+ <param name="MaxFileSize" value="5MB"/>
+ </triggeringPolicy>
+ <encoder>
+ <pattern>combined</pattern>
+ </encoder>
+ </appender>
+
+ <appender-ref ref="FILE" />
+</configuration>
diff --git a/sonar-application/src/main/assembly/conf/logback.xml b/sonar-application/src/main/assembly/conf/logback.xml
index 5859163242d..570c7169247 100644
--- a/sonar-application/src/main/assembly/conf/logback.xml
+++ b/sonar-application/src/main/assembly/conf/logback.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<configuration debug="false">
+ <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/>
<appender name="SONAR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${SONAR_HOME}/logs/sonar.log</File>
@@ -13,24 +14,7 @@
<param name="MaxFileSize" value="5MB"/>
</triggeringPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
- <pattern>
- %d{yyyy.MM.dd HH:mm:ss} %-5level %logger{20} %X %msg%n
- </pattern>
- </encoder>
- </appender>
-
- <!-- appender used to profile Sonar Server -->
- <appender name="PROFILING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
- <File>${SONAR_HOME}/logs/profiling.log</File>
- <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
- <param name="FileNamePattern" value="${SONAR_HOME}/logs/profiling.%i.log"/>
- <param name="MinIndex" value="1"/>
- <param name="MaxIndex" value="3"/>
- </rollingPolicy>
- <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
- <param name="MaxFileSize" value="5MB"/>
- </triggeringPolicy>
- <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+ <!-- Use %d{yyyy.MM.dd HH:mm:ss.SSS} to display milliseconds -->
<pattern>
%d{yyyy.MM.dd HH:mm:ss} %-5level %logger{20} %X %msg%n
</pattern>
@@ -47,11 +31,10 @@
<logger name="rails" additivity="false">
<level value="DEBUG"/>
- <appender-ref ref="PROFILING_FILE"/>
</logger>
Example of command-line to get the HTTP requests with execution time greater than 10s :
- grep 'rails Completed in [0-9]\{5,\}ms' < profiling.log
+ grep 'rails Completed in [0-9]\{5,\}ms' < sonar.log
-->
<logger name="org.hibernate.cache.ReadWriteCache">
@@ -96,4 +79,4 @@
<appender-ref ref="SONAR_FILE"/>
</root>
-</configuration> \ No newline at end of file
+</configuration>
diff --git a/sonar-application/src/main/assembly/conf/sonar.properties b/sonar-application/src/main/assembly/conf/sonar.properties
index 28ce4528bbb..3b4fc79cd0e 100644
--- a/sonar-application/src/main/assembly/conf/sonar.properties
+++ b/sonar-application/src/main/assembly/conf/sonar.properties
@@ -1,4 +1,3 @@
-#--------------------------------------------------------
# This file must contain only ISO 8859-1 characters
# see http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Properties.html#load(java.io.InputStream)
#
@@ -8,34 +7,45 @@
#
#
# See also the file conf/wrapper.conf for JVM advanced settings
-#---------------------------------------------------------
-#---------------------------------------------------------
-# WEB SETTINGS - STANDALONE MODE ONLY
-# These settings are ignored when the war file is deployed to a JEE server.
-#---------------------------------------------------------
-# Listen host/port and context path (for example / or /sonar). Default values are 0.0.0.0:9000/.
+
+#--------------------------------------------------------------------------------------------------
+# WEB SERVER
+
+# Binding address
#sonar.web.host=0.0.0.0
+
+# TCP port for incoming HTTP connections
#sonar.web.port=9000
+
+# Web context must start with slash (/)
#sonar.web.context=/
-# Log HTTP requests. Deactivated by default.
-#sonar.web.jettyRequestLogs= ../../logs/jetty-yyyy_mm_dd.request.log
-#sonar.web.jetty.threads.min=5
-#sonar.web.jetty.threads.max=50
+# The maximum number of connections that the server will accept and process at any given time.
+# When this number has been reached, the server will not accept any more connections until
+# the number of connections falls below this value. The operating system may still accept connections
+# based on the sonar.web.connections.acceptCount property. The default value is 50.
+#sonar.web.connections.maxThreads=50
+
+# The minimum number of threads always kept running. If not specified, the default of 5 is used.
+#sonar.web.connections.minThreads=5
+
+# The maximum queue length for incoming connection requests when all possible request processing
+# threads are in use. Any requests received when the queue is full will be refused.
+# The default value is 25.
+#sonar.web.connections.acceptCount=25
-#-----------------------------------------------------------------------
+
+
+#--------------------------------------------------------------------------------------------------
# DATABASE
#
-# IMPORTANT: the embedded database H2 is used by default.
-# It is recommended for tests only. Please use an external database
-# for production environment (MySQL, Oracle, Postgresql, SQLServer)
-#
-#-----------------------------------------------------------------------
+# IMPORTANT: the embedded H2 database is used by default. It is recommended for tests only.
+# Please use a production-ready database. Supported databases are MySQL, Oracle, PostgreSQL
+# and Microsoft SQLServer.
-#----- Credentials
-# Permissions to create tables and indexes must be granted to JDBC user.
+# Permissions to create tables, indices and triggers must be granted to JDBC user.
# The schema must be created first.
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar
@@ -100,12 +110,12 @@ sonar.jdbc.minEvictableIdleTimeMillis=600000
sonar.jdbc.timeBetweenEvictionRunsMillis=30000
-#---------------------------------------------------------
+
+#--------------------------------------------------------------------------------------------------
# UPDATE CENTER
-#---------------------------------------------------------
# The Update Center requires an internet connection to request http://update.sonarsource.org
-# It is activated by default:
+# It is enabled by default.
#sonar.updatecenter.activate=true
# HTTP proxy (default none)
@@ -123,9 +133,10 @@ sonar.jdbc.timeBetweenEvictionRunsMillis=30000
#http.proxyUser=
#http.proxyPassword=
-#---------------------------------------------------------
+
+
+#--------------------------------------------------------------------------------------------------
# NOTIFICATIONS
-#---------------------------------------------------------
# Delay (in seconds) between processing of notification queue
sonar.notifications.delay=60
diff --git a/sonar-application/src/main/assembly/conf/wrapper.conf b/sonar-application/src/main/assembly/conf/wrapper.conf
index 30f68945ede..b12d3701bc7 100644
--- a/sonar-application/src/main/assembly/conf/wrapper.conf
+++ b/sonar-application/src/main/assembly/conf/wrapper.conf
@@ -32,7 +32,7 @@ wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
# Java Classpath (include wrapper.jar) Add class path elements as
# needed starting from 1
wrapper.java.classpath.1=../../lib/*.jar
-wrapper.java.classpath.2=../../
+wrapper.java.classpath.2=../../conf
wrapper.java.classpath.3=../../extensions/jdbc-driver/mysql/*.jar
wrapper.java.classpath.4=../../extensions/jdbc-driver/oracle/*.jar
wrapper.java.classpath.5=../../extensions/jdbc-driver/postgresql/*.jar
@@ -70,7 +70,7 @@ wrapper.console.loglevel=INFO
wrapper.logfile=../../logs/sonar.log
# Format of output for the log file. (See docs for formats)
-wrapper.logfile.format=LPTM
+wrapper.logfile.format=TLM
# Log Level for log file output. (See docs for log levels)
wrapper.logfile.loglevel=INFO
diff --git a/sonar-application/src/main/java/org/sonar/application/Connectors.java b/sonar-application/src/main/java/org/sonar/application/Connectors.java
new file mode 100644
index 00000000000..f6c8965d166
--- /dev/null
+++ b/sonar-application/src/main/java/org/sonar/application/Connectors.java
@@ -0,0 +1,69 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.application;
+
+import org.apache.catalina.connector.Connector;
+import org.apache.catalina.startup.Tomcat;
+
+class Connectors {
+
+ static final String PROPERTY_SHUTDOWN_TOKEN = "sonar.web.shutdown.token";
+ static final String PROPERTY_SHUTDOWN_PORT = "sonar.web.shutdown.port";
+ static final String PROPERTY_MIN_THREADS = "sonar.web.connections.minThreads";
+ static final String PROPERTY_MAX_THREADS = "sonar.web.connections.maxThreads";
+ static final String PROPERTY_ACCEPT_COUNT = "sonar.web.connections.acceptCount";
+
+ static void configure(Tomcat tomcat, Props props) {
+ tomcat.getServer().setAddress(props.of("sonar.web.host", "0.0.0.0"));
+ configureShutdown(tomcat, props);
+
+ Connector connector = new Connector("HTTP/1.1");
+
+ // TODO manage redirects from other ports ?
+
+ connector.setPort(props.intOf("sonar.web.port", 9000));
+ configurePool(props, connector);
+ configureCompression(connector);
+ tomcat.setConnector(connector);
+ tomcat.getService().addConnector(connector);
+ }
+
+ private static void configureShutdown(Tomcat tomcat, Props props) {
+ String shutdownToken = props.of(PROPERTY_SHUTDOWN_TOKEN);
+ Integer shutdownPort = props.intOf(PROPERTY_SHUTDOWN_PORT);
+ if (shutdownToken != null && !"".equals(shutdownToken) && shutdownPort != null) {
+ tomcat.getServer().setPort(shutdownPort);
+ tomcat.getServer().setShutdown(shutdownToken);
+ }
+ }
+
+ private static void configurePool(Props props, Connector connector) {
+ connector.setProperty("acceptorThreadCount", String.valueOf(2));
+ connector.setProperty("minSpareThreads", String.valueOf(props.intOf(PROPERTY_MIN_THREADS, 5)));
+ connector.setProperty("maxThreads", String.valueOf(props.intOf(PROPERTY_MAX_THREADS, 50)));
+ connector.setProperty("acceptCount", String.valueOf(props.intOf(PROPERTY_ACCEPT_COUNT, 25)));
+ }
+
+ private static void configureCompression(Connector connector) {
+ connector.setProperty("compression", "on");
+ connector.setProperty("compressionMinSize", "1024");
+ connector.setProperty("compressableMimeType", "text/html,text/xml,text/plain,text/css,application/json,application/javascript");
+ }
+}
diff --git a/sonar-application/src/main/java/org/sonar/application/EmbeddedTomcat.java b/sonar-application/src/main/java/org/sonar/application/EmbeddedTomcat.java
new file mode 100644
index 00000000000..79d9cef2a56
--- /dev/null
+++ b/sonar-application/src/main/java/org/sonar/application/EmbeddedTomcat.java
@@ -0,0 +1,112 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.application;
+
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.startup.Tomcat;
+import org.apache.commons.io.FileUtils;
+
+import java.io.File;
+
+class EmbeddedTomcat {
+
+ public static final String TEMP_RELATIVE_PATH = "temp/tomcat";
+
+ private final Env env;
+ private Tomcat tomcat = null;
+ private Thread hook = null;
+ private boolean stopping = false;
+
+ EmbeddedTomcat(Env env) {
+ this.env = env;
+ }
+
+ void start() throws Exception {
+ if (tomcat != null || hook != null) {
+ throw new IllegalStateException("Tomcat is already started");
+ }
+
+ tomcat = new Tomcat();
+
+ // Initialize directories
+ String basedir = env.freshDir(TEMP_RELATIVE_PATH).getCanonicalPath();
+ tomcat.setBaseDir(basedir);
+ tomcat.getHost().setAppBase(basedir);
+ tomcat.getHost().setAutoDeploy(false);
+ tomcat.getHost().setCreateDirs(false);
+ tomcat.getHost().setDeployOnStartup(true);
+
+ Props props = Props.create(env);
+ Logging.configure(tomcat, env);
+ Connectors.configure(tomcat, props);
+ Webapp.configure(tomcat, env, props);
+
+ tomcat.start();
+ addShutdownHook();
+ tomcat.getServer().await();
+
+ // Shutdown command received
+ stop();
+ }
+
+ private void addShutdownHook() {
+ hook = new Thread() {
+ @Override
+ public void run() {
+ EmbeddedTomcat.this.doStop();
+ }
+ };
+ Runtime.getRuntime().addShutdownHook(hook);
+ }
+
+
+ void stop() {
+ removeShutdownHook();
+ doStop();
+ }
+
+ private synchronized void doStop() {
+ try {
+ if (tomcat != null && !stopping) {
+ stopping = true;
+ tomcat.stop();
+ tomcat.destroy();
+ }
+ tomcat = null;
+ stopping = false;
+ File tempDir = env.file(TEMP_RELATIVE_PATH);
+ FileUtils.deleteQuietly(tempDir);
+
+ } catch (LifecycleException e) {
+ throw new IllegalStateException("Fail to stop web server", e);
+ }
+ }
+
+ private void removeShutdownHook() {
+ if (hook != null && !hook.isAlive()) {
+ Runtime.getRuntime().removeShutdownHook(hook);
+ hook = null;
+ }
+ }
+
+ int port() {
+ return tomcat.getService().findConnectors()[0].getLocalPort();
+ }
+}
diff --git a/sonar-application/src/main/java/org/sonar/application/Env.java b/sonar-application/src/main/java/org/sonar/application/Env.java
new file mode 100644
index 00000000000..53f25a9b8d7
--- /dev/null
+++ b/sonar-application/src/main/java/org/sonar/application/Env.java
@@ -0,0 +1,69 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.application;
+
+import org.apache.commons.io.FileUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+class Env {
+
+ private final File confFile;
+
+ Env(File confFile) {
+ this.confFile = confFile;
+ }
+
+ Env() throws URISyntaxException {
+ this(new File(Env.class.getResource("/sonar.properties").toURI()));
+ }
+
+ File rootDir() {
+ return confFile.getParentFile().getParentFile();
+ }
+
+ File file(String relativePath) {
+ return new File(rootDir(), relativePath);
+ }
+
+ File freshDir(String relativePath) {
+ File dir = new File(rootDir(), relativePath);
+ FileUtils.deleteQuietly(dir);
+ dir.mkdirs();
+ return dir;
+ }
+
+ /**
+ * This check is required in order to provide more meaningful message than JRuby - see SONAR-2715
+ */
+ void verifyWritableTempDir() {
+ File file = null;
+ try {
+ file = File.createTempFile("sonarqube-check", "tmp");
+ } catch (IOException e) {
+ throw new IllegalStateException("Unable to create file in temporary directory, please check existence " +
+ "and permissions of: " + FileUtils.getTempDirectory(), e);
+ } finally {
+ FileUtils.deleteQuietly(file);
+ }
+ }
+}
diff --git a/sonar-application/src/main/java/org/sonar/application/JettyEmbedder.java b/sonar-application/src/main/java/org/sonar/application/JettyEmbedder.java
deleted file mode 100644
index 975db243f04..00000000000
--- a/sonar-application/src/main/java/org/sonar/application/JettyEmbedder.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.application;
-
-import org.apache.commons.io.FileUtils;
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.NCSARequestLog;
-import org.eclipse.jetty.server.Server;
-import org.eclipse.jetty.server.handler.HandlerCollection;
-import org.eclipse.jetty.server.handler.RequestLogHandler;
-import org.eclipse.jetty.server.handler.ShutdownHandler;
-import org.eclipse.jetty.server.nio.SelectChannelConnector;
-import org.eclipse.jetty.util.thread.QueuedThreadPool;
-import org.eclipse.jetty.webapp.WebAppContext;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.Properties;
-
-public class JettyEmbedder {
-
- private final Server server;
- private final String host;
- private final int port;
- private final String contextPath;
- private final Properties configuration;
-
- public JettyEmbedder(String host, int port, String contextPath, Properties configuration) throws Exception {
- this.host = host.trim();
- this.port = port;
- this.contextPath = contextPath;
- this.configuration = configuration;
- server = new Server();
- configureProgrammatically();
- }
-
- /**
- * for tests
- */
- JettyEmbedder(String host, int port) throws Exception {
- this(host, port, null, new Properties());
- }
-
- public void start() throws Exception {
- server.start();
-
- Runtime.getRuntime().addShutdownHook(new Thread() {
- @Override
- public void run() {
- try {
- server.stop();
- } catch (Exception e) {
- System.err.println("Can not stop the Jetty server");
- e.printStackTrace();
- }
- }
- });
- }
-
- private Server configureProgrammatically() throws URISyntaxException {
- configureServer();
-
- List<Handler> handlers = new ArrayList<Handler>();
-
- String shutdownCookie = System.getProperty("sonar.shutdownToken");
- if (shutdownCookie != null && !"".equals(shutdownCookie)) {
- System.out.println("Registering shutdown handler");
- ShutdownHandler shutdownHandler = new ShutdownHandler(server, shutdownCookie);
- shutdownHandler.setExitJvm(true);
- handlers.add(shutdownHandler);
- }
-
- WebAppContext context = new WebAppContext(getPath("/web"), contextPath);
- // Set up the path to the custom webdefault.xml (SONAR-3962).
- context.setDefaultsDescriptor("/org/sonar/application/webdefault.xml");
- handlers.add(context);
-
- String filenamePattern = configuration.getProperty("sonar.web.jettyRequestLogs");
- if (filenamePattern != null) {
- handlers.add(configureRequestLogHandler(filenamePattern));
- }
-
- HandlerCollection handler = new HandlerCollection();
- handler.setHandlers(handlers.toArray(new Handler[handlers.size()]));
- server.setHandler(handler);
-
- return server;
- }
-
- private RequestLogHandler configureRequestLogHandler(String filenamePattern) {
- RequestLogHandler requestLogHandler = new RequestLogHandler();
- NCSARequestLog requestLog = new NCSARequestLog(filenamePattern);
- requestLog.setRetainDays(7);
- requestLog.setAppend(true);
- requestLog.setExtended(true);
- requestLog.setLogTimeZone("GMT");
- requestLogHandler.setRequestLog(requestLog);
- return requestLogHandler;
- }
-
- private void configureServer() {
- QueuedThreadPool threadPool = new QueuedThreadPool();
- threadPool.setMinThreads(getIntProperty("sonar.web.jetty.threads.min", 5));
- threadPool.setMaxThreads(getIntProperty("sonar.web.jetty.threads.max", 50));
- server.setThreadPool(threadPool);
- SelectChannelConnector connector = new SelectChannelConnector();
- connector.setHost(host);
- connector.setPort(port);
- connector.setStatsOn(false);
- connector.setAcceptors(2);
- connector.setConfidentialPort(8443);
- server.addConnector(connector);
- server.setStopAtShutdown(true);
- server.setSendServerVersion(false);
- server.setSendDateHeader(true);
- server.setGracefulShutdown(1000);
- }
-
- private int getIntProperty(String name, int defaultValue) {
- String value = configuration.getProperty(name);
- if (null == value) {
- return defaultValue;
- }
-
- return Integer.parseInt(value);
- }
-
- final String getPluginsClasspath(String pluginsPathFromClassloader) throws URISyntaxException, IOException {
- URL resource = getClass().getResource(pluginsPathFromClassloader);
- if (resource == null) {
- return null;
- }
-
- List<String> paths = new ArrayList<String>();
-
- File pluginsDir = new File(resource.toURI());
- paths.add(pluginsDir.getCanonicalPath() + System.getProperty("file.separator"));
-
- Collection<File> files = FileUtils.listFiles(pluginsDir, new String[] {"jar"}, false);
- for (File file : files) {
- paths.add(file.getCanonicalPath());
- }
-
- return join(paths, ",");
- }
-
- private String join(List<String> paths, String separator) {
- StringBuilder sb = new StringBuilder();
- for (String path : paths) {
- if (sb.length() > 0) {
- sb.append(separator);
- }
- sb.append(path);
- }
- return sb.toString();
- }
-
- private String getPath(String resourcePath) throws URISyntaxException {
- URL resource = getClass().getResource(resourcePath);
- if (resource != null) {
- return resource.toURI().toString();
- }
- return null;
- }
-
- Server getServer() {
- return server;
- }
-
- @Override
- public String toString() {
- return new StringBuilder().append("http://").append(host).append(":").append(port).append(contextPath).toString();
- }
-}
diff --git a/sonar-application/src/main/java/org/sonar/application/Logging.java b/sonar-application/src/main/java/org/sonar/application/Logging.java
new file mode 100644
index 00000000000..29d8d097698
--- /dev/null
+++ b/sonar-application/src/main/java/org/sonar/application/Logging.java
@@ -0,0 +1,50 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.application;
+
+import ch.qos.logback.access.tomcat.LogbackValve;
+import org.apache.catalina.startup.Tomcat;
+import org.slf4j.bridge.SLF4JBridgeHandler;
+
+import java.io.File;
+import java.util.logging.LogManager;
+
+class Logging {
+
+ static final String CONF_PATH = "conf/logback-access.xml";
+
+ static void init() {
+ // Configure java.util.logging, used by Tomcat, in order to forward to slf4j
+ LogManager.getLogManager().reset();
+ SLF4JBridgeHandler.install();
+ }
+
+ static void configure(Tomcat tomcat, Env env) {
+ tomcat.setSilent(false);
+ LogbackValve valve = new LogbackValve();
+ valve.setQuiet(true);
+ File confFile = env.file(CONF_PATH);
+ if (!confFile.exists()) {
+ throw new IllegalStateException("File is missing: " + confFile.getAbsolutePath());
+ }
+ valve.setFilename(confFile.getAbsolutePath());
+ tomcat.getHost().getPipeline().addValve(valve);
+ }
+}
diff --git a/sonar-application/src/main/java/org/sonar/application/NullJarScanner.java b/sonar-application/src/main/java/org/sonar/application/NullJarScanner.java
new file mode 100644
index 00000000000..c6c82e2104d
--- /dev/null
+++ b/sonar-application/src/main/java/org/sonar/application/NullJarScanner.java
@@ -0,0 +1,35 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.application;
+
+import org.apache.tomcat.JarScanner;
+import org.apache.tomcat.JarScannerCallback;
+
+import javax.servlet.ServletContext;
+import java.util.Set;
+
+/**
+ * Disable taglib and web-fragment.xml scanning of Tomcat. Should speed up startup.
+ */
+class NullJarScanner implements JarScanner {
+ @Override
+ public void scan(ServletContext context, ClassLoader classloader, JarScannerCallback callback, Set<String> jarsToSkip) {
+ }
+}
diff --git a/sonar-application/src/main/java/org/sonar/application/Props.java b/sonar-application/src/main/java/org/sonar/application/Props.java
new file mode 100644
index 00000000000..a3d1a8b27e2
--- /dev/null
+++ b/sonar-application/src/main/java/org/sonar/application/Props.java
@@ -0,0 +1,84 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.application;
+
+import org.apache.commons.io.IOUtils;
+
+import javax.annotation.Nullable;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.Properties;
+
+/**
+ * TODO support env substitution
+ */
+class Props {
+ private final Properties props;
+
+ Props(Properties props) {
+ this.props = props;
+ }
+
+ String of(String key) {
+ return props.getProperty(key);
+ }
+
+ String of(String key, @Nullable String defaultValue) {
+ String s = of(key);
+ return s == null ? defaultValue : s;
+ }
+
+ Integer intOf(String key) {
+ String s = of(key);
+ if (s != null && !"".equals(s)) {
+ try {
+ return Integer.parseInt(s);
+ } catch (NumberFormatException e) {
+ throw new IllegalStateException("Value of property " + key + " is not an integer: " + s, e);
+ }
+ }
+ return null;
+ }
+
+ int intOf(String key, int defaultValue) {
+ Integer i = intOf(key);
+ return i == null ? defaultValue : i;
+ }
+
+ static Props create(Env env) {
+ File propsFile = env.file("conf/sonar.properties");
+ Properties p = new Properties();
+ FileReader reader = null;
+ try {
+ reader = new FileReader(propsFile);
+ p.load(reader);
+ p.putAll(System.getProperties());
+ return new Props(p);
+
+ } catch (Exception e) {
+ throw new IllegalStateException("File does not exist or can't be open: " + propsFile, e);
+
+ } finally {
+ IOUtils.closeQuietly(reader);
+ }
+ }
+}
diff --git a/sonar-application/src/main/java/org/sonar/application/StartServer.java b/sonar-application/src/main/java/org/sonar/application/StartServer.java
index 923f6ddd153..3704265007c 100644
--- a/sonar-application/src/main/java/org/sonar/application/StartServer.java
+++ b/sonar-application/src/main/java/org/sonar/application/StartServer.java
@@ -19,61 +19,33 @@
*/
package org.sonar.application;
-import org.apache.commons.io.FileUtils;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URISyntaxException;
-import java.util.Properties;
+// TODO dev mode
+// TODO sanitize jetty dependencies
+// TODO remove logback/slf4j from sonar-server
public final class StartServer {
- private static final String DEFAULT_WEB_HOST = "0.0.0.0";
- private static final int DEFAULT_WEB_PORT = 9000;
- private static final String DEFAULT_WEB_CONTEXT = "/";
- private static final String PROPERTIES_FILE_PATH = "/conf/sonar.properties";
-
- private StartServer() {
- }
- public static void main(String[] args) throws Exception {
- canCreateTemporaryFiles();
- configureHome();
+ private final EmbeddedTomcat tomcat;
- Properties configuration = getConfiguration();
- String host = configuration.getProperty("sonar.web.host", DEFAULT_WEB_HOST);
- int port = Integer.parseInt(configuration.getProperty("sonar.web.port", "" + DEFAULT_WEB_PORT));
- String context = configuration.getProperty("sonar.web.context", DEFAULT_WEB_CONTEXT);
- JettyEmbedder jetty = new JettyEmbedder(host, port, context, configuration);
+ public StartServer(Env env) {
+ Logging.init();
+ env.verifyWritableTempDir();
+ this.tomcat = new EmbeddedTomcat(env);
+ }
- jetty.start();
- Thread.currentThread().join();
+ void start() throws Exception {
+ tomcat.start();
}
- /**
- * This check is required in order to provide more meaningful message than JRuby - see SONAR-2715
- */
- private static void canCreateTemporaryFiles() {
- File file = null;
- try {
- file = File.createTempFile("sonar-check", "tmp");
- } catch (IOException e) {
- throw new IllegalStateException("Unable to create file in temporary directory, please check existence of it and permissions: " + FileUtils.getTempDirectoryPath(), e);
- } finally {
- FileUtils.deleteQuietly(file);
- }
+ int port() {
+ return tomcat.port();
}
- private static Properties getConfiguration() throws IOException {
- Properties properties = new Properties();
- properties.load(StartServer.class.getResourceAsStream(PROPERTIES_FILE_PATH));
- return properties;
+ void stop() throws Exception {
+ tomcat.stop();
}
- /**
- * @see org.sonar.server.platform.SonarHome#SONAR_HOME
- */
- private static void configureHome() throws URISyntaxException {
- File confFile = new File(StartServer.class.getResource(PROPERTIES_FILE_PATH).toURI());
- System.setProperty("SONAR_HOME", confFile.getParentFile().getParentFile().getAbsolutePath());
+ public static void main(String[] args) throws Exception {
+ new StartServer(new Env()).start();
}
}
diff --git a/sonar-application/src/main/java/org/sonar/application/Webapp.java b/sonar-application/src/main/java/org/sonar/application/Webapp.java
new file mode 100644
index 00000000000..70d33d829b5
--- /dev/null
+++ b/sonar-application/src/main/java/org/sonar/application/Webapp.java
@@ -0,0 +1,39 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.application;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.startup.Tomcat;
+
+class Webapp {
+
+ static void configure(Tomcat tomcat, Env env, Props props) {
+ String ctx = props.of("sonar.web.context", "/");
+ try {
+ System.setProperty("SONAR_HOME", env.rootDir().getAbsolutePath());
+ Context context = tomcat.addWebapp(ctx, env.file("web").getAbsolutePath());
+ context.setConfigFile(env.file("web/META-INF/context.xml").toURL());
+ context.setJarScanner(new NullJarScanner());
+
+ } catch (Exception e) {
+ throw new IllegalStateException("Fail to configure webapp", e);
+ }
+ }
+}
diff --git a/sonar-application/src/main/java/org/sonar/application/package-info.java b/sonar-application/src/main/java/org/sonar/application/package-info.java
new file mode 100644
index 00000000000..009b187eda5
--- /dev/null
+++ b/sonar-application/src/main/java/org/sonar/application/package-info.java
@@ -0,0 +1,23 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+@ParametersAreNonnullByDefault
+package org.sonar.application;
+
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-application/src/main/resources/org/sonar/application/webdefault.xml b/sonar-application/src/main/resources/org/sonar/application/webdefault.xml
deleted file mode 100644
index 75599d24cb4..00000000000
--- a/sonar-application/src/main/resources/org/sonar/application/webdefault.xml
+++ /dev/null
@@ -1,347 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-
- <!-- Modified version of webdefault.xml shipped inside jetty-webapp in order to remove JSP servlet -->
-
- <!-- ===================================================================== -->
- <!-- This file contains the default descriptor for web applications. -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- The intent of this descriptor is to include jetty specific or common -->
- <!-- configuration for all webapps. If a context has a webdefault.xml -->
- <!-- descriptor, it is applied before the contexts own web.xml file -->
- <!-- -->
- <!-- A context may be assigned a default descriptor by: -->
- <!-- + Calling WebApplicationContext.setDefaultsDescriptor -->
- <!-- + Passed an arg to addWebApplications -->
- <!-- -->
- <!-- This file is used both as the resource within the jetty.jar (which is -->
- <!-- used as the default if no explicit defaults descriptor is set) and it -->
- <!-- is copied to the etc directory of the Jetty distro and explicitly -->
- <!-- by the jetty.xml file. -->
- <!-- -->
- <!-- ===================================================================== -->
-<web-app
- xmlns="http://java.sun.com/xml/ns/javaee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- metadata-complete="true"
- version="2.5"
->
-
- <description>
- Default web.xml file.
- This file is applied to a Web application before it's own WEB_INF/web.xml file
- </description>
-
- <!-- ==================================================================== -->
- <!-- Removes static references to beans from javax.el.BeanELResolver to -->
- <!-- ensure webapp classloader can be released on undeploy -->
- <!-- ==================================================================== -->
- <listener>
- <listener-class>org.eclipse.jetty.servlet.listener.ELContextCleaner</listener-class>
- </listener>
-
- <!-- ==================================================================== -->
- <!-- Removes static cache of Methods from java.beans.Introspector to -->
- <!-- ensure webapp classloader can be released on undeploy -->
- <!-- ==================================================================== -->
- <listener>
- <listener-class>org.eclipse.jetty.servlet.listener.IntrospectorCleaner</listener-class>
- </listener>
-
- <!-- ==================================================================== -->
- <!-- The default servlet. -->
- <!-- This servlet, normally mapped to /, provides the handling for static -->
- <!-- content, OPTIONS and TRACE methods for the context. -->
- <!-- The following initParameters are supported: -->
- <!--
- * acceptRanges If true, range requests and responses are
- * supported
- *
- * dirAllowed If true, directory listings are returned if no
- * welcome file is found. Else 403 Forbidden.
- *
- * welcomeServlets If true, attempt to dispatch to welcome files
- * that are servlets, but only after no matching static
- * resources could be found. If false, then a welcome
- * file must exist on disk. If "exact", then exact
- * servlet matches are supported without an existing file.
- * Default is true.
- *
- * This must be false if you want directory listings,
- * but have index.jsp in your welcome file list.
- *
- * redirectWelcome If true, welcome files are redirected rather than
- * forwarded to.
- *
- * gzip If set to true, then static content will be served as
- * gzip content encoded if a matching resource is
- * found ending with ".gz"
- *
- * resourceBase Set to replace the context resource base
- *
- * resourceCache If set, this is a context attribute name, which the servlet
- * will use to look for a shared ResourceCache instance.
- *
- * relativeResourceBase
- * Set with a pathname relative to the base of the
- * servlet context root. Useful for only serving static content out
- * of only specific subdirectories.
- *
- * aliases If True, aliases of resources are allowed (eg. symbolic
- * links and caps variations). May bypass security constraints.
- *
- * maxCacheSize The maximum total size of the cache or 0 for no cache.
- * maxCachedFileSize The maximum size of a file to cache
- * maxCachedFiles The maximum number of files to cache
- *
- * useFileMappedBuffer
- * If set to true, it will use mapped file buffer to serve static content
- * when using NIO connector. Setting this value to false means that
- * a direct buffer will be used instead of a mapped file buffer.
- * By default, this is set to true.
- *
- * cacheControl If set, all static content will have this value set as the cache-control
- * header.
- -->
-
-
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <servlet>
- <servlet-name>default</servlet-name>
- <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
- <init-param>
- <param-name>aliases</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>acceptRanges</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <param-name>dirAllowed</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <param-name>welcomeServlets</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>redirectWelcome</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>maxCacheSize</param-name>
- <param-value>256000000</param-value>
- </init-param>
- <init-param>
- <param-name>maxCachedFileSize</param-name>
- <param-value>200000000</param-value>
- </init-param>
- <init-param>
- <param-name>maxCachedFiles</param-name>
- <param-value>2048</param-value>
- </init-param>
- <init-param>
- <param-name>gzip</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <param-name>useFileMappedBuffer</param-name>
- <param-value>true</param-value>
- </init-param>
- <!--
- <init-param>
- <param-name>resourceCache</param-name>
- <param-value>resourceCache</param-value>
- </init-param>
- -->
- <!--
- <init-param>
- <param-name>cacheControl</param-name>
- <param-value>max-age=3600,public</param-value>
- </init-param>
- -->
- <load-on-startup>0</load-on-startup>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>default</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
-
-
- <!-- ==================================================================== -->
- <session-config>
- <session-timeout>30</session-timeout>
- </session-config>
-
- <!-- ==================================================================== -->
- <locale-encoding-mapping-list>
- <locale-encoding-mapping>
- <locale>ar</locale>
- <encoding>ISO-8859-6</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>be</locale>
- <encoding>ISO-8859-5</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>bg</locale>
- <encoding>ISO-8859-5</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>ca</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>cs</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>da</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>de</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>el</locale>
- <encoding>ISO-8859-7</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>en</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>es</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>et</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>fi</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>fr</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>hr</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>hu</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>is</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>it</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>iw</locale>
- <encoding>ISO-8859-8</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>ja</locale>
- <encoding>Shift_JIS</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>ko</locale>
- <encoding>EUC-KR</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>lt</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>lv</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>mk</locale>
- <encoding>ISO-8859-5</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>nl</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>no</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>pl</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>pt</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>ro</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>ru</locale>
- <encoding>ISO-8859-5</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>sh</locale>
- <encoding>ISO-8859-5</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>sk</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>sl</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>sq</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>sr</locale>
- <encoding>ISO-8859-5</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>sv</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>tr</locale>
- <encoding>ISO-8859-9</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>uk</locale>
- <encoding>ISO-8859-5</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>zh</locale>
- <encoding>GB2312</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>zh_TW</locale>
- <encoding>Big5</encoding>
- </locale-encoding-mapping>
- </locale-encoding-mapping-list>
-
- <security-constraint>
- <web-resource-collection>
- <web-resource-name>Disable TRACE</web-resource-name>
- <url-pattern>/</url-pattern>
- <http-method>TRACE</http-method>
- </web-resource-collection>
- <auth-constraint/>
- </security-constraint>
-
-</web-app>
diff --git a/sonar-application/src/test/fake-app/conf/logback-access.xml b/sonar-application/src/test/fake-app/conf/logback-access.xml
new file mode 100644
index 00000000000..77cfc885d09
--- /dev/null
+++ b/sonar-application/src/test/fake-app/conf/logback-access.xml
@@ -0,0 +1,17 @@
+<!--
+
+ See http://logback.qos.ch/access.html#configuration
+
+-->
+<configuration debug="false">
+ <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"/>
+
+ <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+ <file>${SONAR_HOME}/logs/access.log</file>
+ <encoder>
+ <pattern>combined</pattern>
+ </encoder>
+ </appender>
+
+ <appender-ref ref="FILE" />
+</configuration>
diff --git a/sonar-application/src/test/fake-app/conf/sonar.properties b/sonar-application/src/test/fake-app/conf/sonar.properties
new file mode 100644
index 00000000000..e8e111dcab8
--- /dev/null
+++ b/sonar-application/src/test/fake-app/conf/sonar.properties
@@ -0,0 +1,2 @@
+# random open port
+sonar.web.port=0 \ No newline at end of file
diff --git a/sonar-application/src/test/fake-app/web/META-INF/context.xml b/sonar-application/src/test/fake-app/web/META-INF/context.xml
new file mode 100644
index 00000000000..5e31888a15e
--- /dev/null
+++ b/sonar-application/src/test/fake-app/web/META-INF/context.xml
@@ -0,0 +1,2 @@
+<Context antiJARLocking="true" antiResourceLocking="true">
+</Context>
diff --git a/sonar-application/src/test/fake-app/web/WEB-INF/web.xml b/sonar-application/src/test/fake-app/web/WEB-INF/web.xml
new file mode 100644
index 00000000000..9f13dabf72f
--- /dev/null
+++ b/sonar-application/src/test/fake-app/web/WEB-INF/web.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xmlns="http://java.sun.com/xml/ns/javaee"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
+ id="Fake"
+ version="3.0"
+ metadata-complete="true">
+
+ <display-name>Fake</display-name>
+
+</web-app>
diff --git a/sonar-application/src/test/fake-app/web/index.html b/sonar-application/src/test/fake-app/web/index.html
new file mode 100644
index 00000000000..5e1c309dae7
--- /dev/null
+++ b/sonar-application/src/test/fake-app/web/index.html
@@ -0,0 +1 @@
+Hello World \ No newline at end of file
diff --git a/sonar-application/src/test/java/org/sonar/application/ConnectorsTest.java b/sonar-application/src/test/java/org/sonar/application/ConnectorsTest.java
new file mode 100644
index 00000000000..b437227211f
--- /dev/null
+++ b/sonar-application/src/test/java/org/sonar/application/ConnectorsTest.java
@@ -0,0 +1,102 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.application;
+
+import org.apache.catalina.connector.Connector;
+import org.apache.catalina.startup.Tomcat;
+import org.junit.Test;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mockito;
+
+import java.util.Properties;
+
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+
+public class ConnectorsTest {
+ @Test
+ public void enable_shutdown_port() throws Exception {
+ Properties p = new Properties();
+ p.setProperty(Connectors.PROPERTY_SHUTDOWN_PORT, "9010");
+ p.setProperty(Connectors.PROPERTY_SHUTDOWN_TOKEN, "SHUTDOWN");
+ Props props = new Props(p);
+
+ Tomcat tomcat = mock(Tomcat.class, Mockito.RETURNS_DEEP_STUBS);
+ Connectors.configure(tomcat, props);
+
+ verify(tomcat.getServer()).setPort(9010);
+ verify(tomcat.getServer()).setShutdown("SHUTDOWN");
+ }
+
+ @Test
+ public void disable_shutdown_port_by_default() throws Exception {
+ Props props = new Props(new Properties());
+
+ Tomcat tomcat = mock(Tomcat.class, Mockito.RETURNS_DEEP_STUBS);
+ Connectors.configure(tomcat, props);
+
+ verify(tomcat.getServer(), never()).setPort(anyInt());
+ verify(tomcat.getServer(), never()).setShutdown(anyString());
+ }
+
+ @Test
+ public void configure_thread_pool() throws Exception {
+ Properties p = new Properties();
+ p.setProperty(Connectors.PROPERTY_MIN_THREADS, "2");
+ p.setProperty(Connectors.PROPERTY_MAX_THREADS, "30");
+ p.setProperty(Connectors.PROPERTY_ACCEPT_COUNT, "20");
+ Props props = new Props(p);
+
+ Tomcat tomcat = mock(Tomcat.class, Mockito.RETURNS_DEEP_STUBS);
+ Connectors.configure(tomcat, props);
+
+ verify(tomcat).setConnector(argThat(new ArgumentMatcher<Connector>() {
+ @Override
+ public boolean matches(Object o) {
+ Connector c = (Connector)o;
+ return (Integer)c.getProperty("minSpareThreads") == 2 &&
+ (Integer) c.getProperty("maxThreads") == 30 &&
+ (Integer) c.getProperty("acceptCount") == 20;
+ }
+ }));
+ }
+
+ @Test
+ public void configure_default_thread_pool() throws Exception {
+ Props props = new Props(new Properties());
+
+ Tomcat tomcat = mock(Tomcat.class, Mockito.RETURNS_DEEP_STUBS);
+ Connectors.configure(tomcat, props);
+
+ verify(tomcat).setConnector(argThat(new ArgumentMatcher<Connector>() {
+ @Override
+ public boolean matches(Object o) {
+ Connector c = (Connector)o;
+ return (Integer)c.getProperty("minSpareThreads") == 5 &&
+ (Integer) c.getProperty("maxThreads") == 50 &&
+ (Integer) c.getProperty("acceptCount") == 25;
+ }
+ }));
+ }
+}
diff --git a/sonar-application/src/test/java/org/sonar/application/EnvTest.java b/sonar-application/src/test/java/org/sonar/application/EnvTest.java
new file mode 100644
index 00000000000..0aab59fa26e
--- /dev/null
+++ b/sonar-application/src/test/java/org/sonar/application/EnvTest.java
@@ -0,0 +1,80 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.application;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class EnvTest {
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ @Test
+ public void files() throws Exception {
+ File home = temp.newFolder();
+ File confFile = new File(home, "conf/sonar.properties");
+ File logFile = new File(home, "logs/sonar.log");
+
+ FileUtils.touch(confFile);
+ FileUtils.touch(logFile);
+
+ Env env = new Env(confFile);
+
+ assertThat(env.rootDir()).isDirectory().exists().isEqualTo(home);
+ assertThat(env.file("conf/sonar.properties")).isFile().exists().isEqualTo(confFile);
+ assertThat(env.file("logs/sonar.log")).isFile().exists().isEqualTo(logFile);
+ assertThat(env.file("xxx/unknown.log")).doesNotExist();
+ }
+
+ @Test
+ public void fresh_dir() throws Exception {
+ File home = temp.newFolder();
+ File confFile = new File(home, "conf/sonar.properties");
+ File logFile = new File(home, "logs/sonar.log");
+
+ FileUtils.touch(confFile);
+ FileUtils.touch(logFile);
+
+ Env env = new Env(confFile);
+
+ File data = env.freshDir("data/h2");
+ assertThat(data).isDirectory().exists();
+ assertThat(data.getParentFile().getName()).isEqualTo("data");
+ assertThat(data.getParentFile().getParentFile()).isEqualTo(home);
+
+ // clean directory
+ File logs = env.freshDir("logs");
+ assertThat(logs).isDirectory().exists();
+ assertThat(logs.listFiles()).isEmpty();
+ }
+
+ @Test
+ public void temp_dir_should_be_writable() throws Exception {
+ new Env(temp.newFile()).verifyWritableTempDir();
+ // do not fail
+ }
+}
diff --git a/sonar-application/src/test/java/org/sonar/application/JettyEmbedderTest.java b/sonar-application/src/test/java/org/sonar/application/JettyEmbedderTest.java
deleted file mode 100644
index 5c7a35e163c..00000000000
--- a/sonar-application/src/test/java/org/sonar/application/JettyEmbedderTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * SonarQube, open source software quality management tool.
- * Copyright (C) 2008-2013 SonarSource
- * mailto:contact AT sonarsource DOT com
- *
- * SonarQube is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * SonarQube is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-package org.sonar.application;
-
-import org.apache.commons.lang.StringUtils;
-import org.junit.Test;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class JettyEmbedderTest {
-
- @Test
- public void shouldConfigureProgrammatically() throws Exception {
- JettyEmbedder jetty = new JettyEmbedder("1.2.3.4", 9999);
-
- assertThat(jetty.getServer().getConnectors()).hasSize(1);
- assertThat(jetty.getServer().getConnectors()[0].getPort()).isEqualTo(9999);
- assertThat(jetty.getServer().getConnectors()[0].getHost()).isEqualTo("1.2.3.4");
- }
-
- @Test
- public void shouldLoadPluginsClasspath() throws Exception {
- JettyEmbedder jetty = new JettyEmbedder("127.0.0.1", 9999);
-
- String classpath = jetty.getPluginsClasspath("/org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath");
- classpath = StringUtils.replaceChars(classpath, "\\", "/");
-
- assertThat(classpath).contains("org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath/plugin1.jar");
- assertThat(classpath).contains("org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath/plugin1.jar");
- assertThat(classpath).contains("org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath/plugin2.jar");
-
- // important : directories end with /
- assertThat(classpath).contains("org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath/,");
- }
-}
diff --git a/sonar-application/src/test/java/org/sonar/application/LoggingTest.java b/sonar-application/src/test/java/org/sonar/application/LoggingTest.java
new file mode 100644
index 00000000000..ca5f6ef3c51
--- /dev/null
+++ b/sonar-application/src/test/java/org/sonar/application/LoggingTest.java
@@ -0,0 +1,68 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.application;
+
+import ch.qos.logback.access.tomcat.LogbackValve;
+import org.apache.catalina.Valve;
+import org.apache.catalina.startup.Tomcat;
+import org.junit.Test;
+import org.mockito.ArgumentMatcher;
+import org.mockito.Mockito;
+
+import java.io.File;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.*;
+
+public class LoggingTest {
+ @Test
+ public void configure_access_logs() throws Exception {
+ Tomcat tomcat = mock(Tomcat.class, Mockito.RETURNS_DEEP_STUBS);
+ Env env = mock(Env.class);
+ final File propsFile = new File(getClass().getResource("/org/sonar/application/LoggingTest/logback-access.xml").toURI());
+ when(env.file(Logging.CONF_PATH)).thenReturn(propsFile);
+ Logging.configure(tomcat, env);
+
+ verify(tomcat.getHost().getPipeline()).addValve(argThat(new ArgumentMatcher<Valve>() {
+ @Override
+ public boolean matches(Object o) {
+ LogbackValve v = (LogbackValve) o;
+ return v.getFilename().equals(propsFile.getAbsolutePath());
+ }
+ }));
+ }
+
+ @Test
+ public void fail_if_missing_conf_file() throws Exception {
+ Tomcat tomcat = mock(Tomcat.class, Mockito.RETURNS_DEEP_STUBS);
+ Env env = mock(Env.class);
+ final File confFile = new File("target/does_not_exist/logback-access.xml");
+ when(env.file(Logging.CONF_PATH)).thenReturn(confFile);
+
+ try {
+ Logging.configure(tomcat, env);
+ fail();
+ } catch (IllegalStateException e) {
+ assertThat(e).hasMessage("File is missing: " + confFile.getAbsolutePath());
+ }
+ }
+}
diff --git a/sonar-application/src/test/java/org/sonar/application/NullJarScannerTest.java b/sonar-application/src/test/java/org/sonar/application/NullJarScannerTest.java
new file mode 100644
index 00000000000..50e3a9a60d0
--- /dev/null
+++ b/sonar-application/src/test/java/org/sonar/application/NullJarScannerTest.java
@@ -0,0 +1,43 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.application;
+
+import org.apache.tomcat.JarScannerCallback;
+import org.junit.Test;
+
+import javax.servlet.ServletContext;
+import java.util.HashSet;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+public class NullJarScannerTest {
+
+ @Test
+ public void does_nothing() {
+ ServletContext context = mock(ServletContext.class);
+ ClassLoader classloader = mock(ClassLoader.class);
+ JarScannerCallback callback = mock(JarScannerCallback.class);
+
+ new NullJarScanner().scan(context, classloader, callback, new HashSet<String>());
+
+ verifyZeroInteractions(context, classloader, callback);
+ }
+}
diff --git a/sonar-application/src/test/java/org/sonar/application/PropsTest.java b/sonar-application/src/test/java/org/sonar/application/PropsTest.java
new file mode 100644
index 00000000000..b2bd5d0fd69
--- /dev/null
+++ b/sonar-application/src/test/java/org/sonar/application/PropsTest.java
@@ -0,0 +1,98 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.application;
+
+import org.junit.Test;
+
+import java.io.File;
+import java.util.Properties;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class PropsTest {
+ @Test
+ public void of() throws Exception {
+ Properties p = new Properties();
+ p.setProperty("foo", "bar");
+ Props props = new Props(p);
+
+ assertThat(props.of("foo")).isEqualTo("bar");
+ assertThat(props.of("foo", "default value")).isEqualTo("bar");
+ assertThat(props.of("unknown")).isNull();
+ assertThat(props.of("unknown", "default value")).isEqualTo("default value");
+ }
+
+ @Test
+ public void intOf() throws Exception {
+ Properties p = new Properties();
+ p.setProperty("foo", "33");
+ Props props = new Props(p);
+
+ assertThat(props.intOf("foo")).isEqualTo(33);
+ assertThat(props.intOf("foo", 44)).isEqualTo(33);
+ assertThat(props.intOf("unknown")).isNull();
+ assertThat(props.intOf("unknown", 44)).isEqualTo(44);
+ }
+
+ @Test
+ public void intOf_not_integer() throws Exception {
+ Properties p = new Properties();
+ p.setProperty("foo", "bar");
+ Props props = new Props(p);
+
+ try {
+ props.intOf("foo");
+ fail();
+ } catch (IllegalStateException e) {
+ assertThat(e).hasMessage("Value of property foo is not an integer: bar");
+ }
+ }
+
+ @Test
+ public void load_file_and_system_properties() throws Exception {
+ Env env = mock(Env.class);
+ File propsFile = new File(getClass().getResource("/org/sonar/application/PropsTest/sonar.properties").toURI());
+ when(env.file("conf/sonar.properties")).thenReturn(propsFile);
+
+ Props props = Props.create(env);
+
+ assertThat(props.of("foo")).isEqualTo("bar");
+ assertThat(props.of("java.version")).isNotNull();
+
+ // system properties override file properties
+ assertThat(props.of("java.io.tmpdir")).isNotEmpty().isNotEqualTo("/should/be/overridden");
+ }
+
+ @Test
+ public void fail_if_file_does_not_exist() throws Exception {
+ Env env = mock(Env.class);
+ when(env.file("conf/sonar.properties")).thenReturn(new File("target/not_exist/sonar.properties"));
+
+ try {
+ Props.create(env);
+ fail();
+ } catch (IllegalStateException e) {
+ assertThat(e).hasMessage("File does not exist or can't be open: target/not_exist/sonar.properties");
+ }
+ }
+}
diff --git a/sonar-application/src/test/java/org/sonar/application/StartServerTest.java b/sonar-application/src/test/java/org/sonar/application/StartServerTest.java
new file mode 100644
index 00000000000..868a51288d2
--- /dev/null
+++ b/sonar-application/src/test/java/org/sonar/application/StartServerTest.java
@@ -0,0 +1,150 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2013 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.application;
+
+import com.github.kevinsawicki.http.HttpRequest;
+import org.apache.commons.io.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.assertions.Fail.fail;
+
+public class StartServerTest {
+
+ Env env = new Env(locateFakeConfFile());
+ StartServer starter = new StartServer(env);
+
+ @Before
+ @After
+ public void clean_generated_dirs() throws IOException {
+ FileUtils.deleteDirectory(env.file("temp"));
+ FileUtils.deleteDirectory(env.file("logs"));
+ }
+
+ @Test
+ public void start_server() throws Exception {
+ BackgroundThread background = new BackgroundThread(starter);
+ int port = 0;
+ try {
+ background.start();
+ boolean started = false;
+ for (int i = 0; i < 100; i++) {
+ // Waiting for server to be started.
+ // A random and open port is used (see conf/sonar.properties)
+ Thread.sleep(500L);
+ if (verifyUp() && verifyLogs()) {
+ port = starter.port();
+ started = true;
+ break;
+ }
+ }
+ assertThat(started).isTrue();
+ } finally {
+ starter.stop();
+ }
+
+ // Server is down
+ try {
+ assertThat(HttpRequest.get("http://localhost:" + port).ok()).isFalse();
+ } catch (HttpRequest.HttpRequestException e) {
+ // ok
+ }
+ }
+
+ private boolean verifyUp() {
+ if (starter.port() > 0) {
+ String url = "http://localhost:" + starter.port() + "/index.html";
+ HttpRequest request = HttpRequest.get(url);
+ if (request.ok() && "Hello World".equals(request.body(HttpRequest.CHARSET_UTF8))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean verifyLogs() {
+ File logFile = env.file("logs/access.log");
+ return logFile.isFile() && logFile.exists() && logFile.length()>0;
+ }
+
+ @Test
+ public void fail_if_started_twice() throws Exception {
+ BackgroundThread background = new BackgroundThread(starter);
+ try {
+ background.start();
+ boolean started = false;
+ for (int i = 0; i < 100; i++) {
+ // Waiting for server to be started.
+ // A random and open port is used (see conf/sonar.properties)
+ Thread.sleep(500L);
+ if (starter.port() > 0) {
+ try {
+ starter.start();
+ fail();
+ } catch (IllegalStateException e) {
+ assertThat(e.getMessage()).isEqualTo("Tomcat is already started");
+ started = true;
+ break;
+ }
+ }
+ }
+ assertThat(started).isTrue();
+
+ } finally {
+ starter.stop();
+ }
+ }
+
+ @Test
+ public void ignore_stop_if_not_running() throws Exception {
+ starter.stop();
+ starter.stop();
+ }
+
+ private File locateFakeConfFile() {
+ File confFile = new File("src/test/fake-app/conf/sonar.properties");
+ if (!confFile.exists()) {
+ confFile = new File("sonar-application/src/test/fake-app/conf/sonar.properties");
+ }
+ return confFile;
+ }
+
+ static class BackgroundThread extends Thread {
+ private StartServer server;
+
+ BackgroundThread(StartServer server) {
+ this.server = server;
+ }
+
+ @Override
+ public void run() {
+ try {
+ server.start();
+ } catch (Exception e) {
+ throw new IllegalStateException(e);
+ }
+ }
+ }
+}
diff --git a/sonar-application/src/test/resources/org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath/foo.xml b/sonar-application/src/test/resources/org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath/foo.xml
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/sonar-application/src/test/resources/org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath/foo.xml
+++ /dev/null
diff --git a/sonar-application/src/test/resources/org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath/plugin1.jar b/sonar-application/src/test/resources/org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath/plugin1.jar
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/sonar-application/src/test/resources/org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath/plugin1.jar
+++ /dev/null
diff --git a/sonar-application/src/test/resources/org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath/plugin2.jar b/sonar-application/src/test/resources/org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath/plugin2.jar
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/sonar-application/src/test/resources/org/sonar/application/JettyEmbedderTest/shouldLoadPluginsClasspath/plugin2.jar
+++ /dev/null
diff --git a/sonar-application/src/test/resources/org/sonar/application/LoggingTest/logback-access.xml b/sonar-application/src/test/resources/org/sonar/application/LoggingTest/logback-access.xml
new file mode 100644
index 00000000000..298193e01fa
--- /dev/null
+++ b/sonar-application/src/test/resources/org/sonar/application/LoggingTest/logback-access.xml
@@ -0,0 +1 @@
+<configuration/>
diff --git a/sonar-application/src/test/resources/org/sonar/application/PropsTest/sonar.properties b/sonar-application/src/test/resources/org/sonar/application/PropsTest/sonar.properties
new file mode 100644
index 00000000000..b73be15411b
--- /dev/null
+++ b/sonar-application/src/test/resources/org/sonar/application/PropsTest/sonar.properties
@@ -0,0 +1,2 @@
+foo=bar
+java.io.tmpdir=/should/be/overridden
diff --git a/sonar-batch/pom.xml b/sonar-batch/pom.xml
index 4c86b9e75f0..8d22fc02e7a 100644
--- a/sonar-batch/pom.xml
+++ b/sonar-batch/pom.xml
@@ -13,6 +13,11 @@
<dependencies>
<dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>com.akiban</groupId>
<artifactId>akiban-persistit</artifactId>
</dependency>
@@ -94,8 +99,8 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.mortbay.jetty</groupId>
- <artifactId>servlet-api</artifactId>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
diff --git a/sonar-core/pom.xml b/sonar-core/pom.xml
index 9712a01ce2e..2e52b7506c5 100644
--- a/sonar-core/pom.xml
+++ b/sonar-core/pom.xml
@@ -15,6 +15,11 @@
<dependencies>
<dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>${project.groupId}</groupId>
<artifactId>sonar-plugin-api</artifactId>
<exclusions>
diff --git a/sonar-plugin-api/pom.xml b/sonar-plugin-api/pom.xml
index 7d885fcb6eb..494d2291242 100644
--- a/sonar-plugin-api/pom.xml
+++ b/sonar-plugin-api/pom.xml
@@ -14,6 +14,11 @@
<name>SonarQube :: Plugin API</name>
<dependencies>
<dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-check-api</artifactId>
</dependency>
@@ -126,8 +131,9 @@
<artifactId>xalan</artifactId>
</dependency>
<dependency>
- <groupId>org.mortbay.jetty</groupId>
- <artifactId>servlet-api</artifactId>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
+ <version>3.0.1</version>
<optional>true</optional>
</dependency>
diff --git a/sonar-server/h2-start.sh b/sonar-server/h2-start.sh
index 9e2b5835df6..681987b24ae 100755
--- a/sonar-server/h2-start.sh
+++ b/sonar-server/h2-start.sh
@@ -1,3 +1,3 @@
#!/bin/sh
export MAVEN_OPTS='-Xmx768m -XX:MaxPermSize=128m'
-mvn clean jetty:run -Pstart-dev-server,h2 $*
+mvn clean org.apache.tomcat.maven:tomcat7-maven-plugin::run -Pstart-dev-server,h2 $*
diff --git a/sonar-server/pom.xml b/sonar-server/pom.xml
index 7b14a4d60ca..271bdc3d315 100644
--- a/sonar-server/pom.xml
+++ b/sonar-server/pom.xml
@@ -114,11 +114,6 @@
<artifactId>commons-codec</artifactId>
</dependency>
<dependency>
- <groupId>org.mortbay.jetty</groupId>
- <artifactId>servlet-api</artifactId>
- <scope>provided</scope>
- </dependency>
- <dependency>
<groupId>jfree</groupId>
<artifactId>jfreechart</artifactId>
</dependency>
@@ -135,11 +130,16 @@
<artifactId>jruby-rack</artifactId>
</dependency>
<dependency>
- <!-- GZIP filter -->
- <groupId>org.eclipse.jetty</groupId>
- <artifactId>jetty-servlets</artifactId>
+ <groupId>org.apache.tomcat.embed</groupId>
+ <artifactId>tomcat-embed-core</artifactId>
+ <version>7.0.42</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ <scope>provided</scope>
</dependency>
-
<!-- unit tests -->
<dependency>
<groupId>org.codehaus.sonar</groupId>
@@ -374,26 +374,18 @@
</executions>
</plugin>
<plugin>
- <groupId>org.mortbay.jetty</groupId>
- <artifactId>jetty-maven-plugin</artifactId>
- <version>${jetty.version}</version>
+ <groupId>org.apache.tomcat.maven</groupId>
+ <artifactId>tomcat7-maven-plugin</artifactId>
+ <version>2.1</version>
<configuration>
- <webAppConfig>
- <contextPath>/dev</contextPath>
- <defaultsDescriptor>${basedir}/src/dev/webdefault.xml</defaultsDescriptor>
- <descriptor>${basedir}/src/dev/web.xml</descriptor>
- </webAppConfig>
- <connectors>
- <connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector">
- <port>9000</port>
- <maxIdleTime>60000</maxIdleTime>
- </connector>
- </connectors>
+ <port>9000</port>
+ <path>/dev</path>
+ <!--<contextFile>${pom.basedir}/src/main/webapp/META-INF/context.xml</contextFile>-->
+ <tomcatWebXml>${pom.basedir}/src/dev/web.xml</tomcatWebXml>
+ <useNaming>false</useNaming>
<systemProperties>
- <systemProperty>
- <name>SONAR_HOME</name>
- <value>${project.build.directory}/sonar-dev-home</value>
- </systemProperty>
+ <SONAR_HOME>${pom.build.directory}/sonar-dev-home</SONAR_HOME>
+ <!--<java.io.tmpdir>${pom.basedir}/target/tomcat-tmp</java.io.tmpdir>-->
</systemProperties>
</configuration>
</plugin>
diff --git a/sonar-server/src/dev/web.xml b/sonar-server/src/dev/web.xml
index 77bc34d5f59..d6ec5654caf 100644
--- a/sonar-server/src/dev/web.xml
+++ b/sonar-server/src/dev/web.xml
@@ -2,7 +2,9 @@
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
- id="SonarQube" version="3.0">
+ id="SonarQube"
+ version="3.0"
+ metadata-complete="true">
<display-name>SonarQube</display-name>
<context-param>
diff --git a/sonar-server/src/dev/webdefault.xml b/sonar-server/src/dev/webdefault.xml
deleted file mode 100644
index 3967afba965..00000000000
--- a/sonar-server/src/dev/webdefault.xml
+++ /dev/null
@@ -1,507 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-
- <!-- ===================================================================== -->
- <!-- This file contains the default descriptor for web applications. -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- The intent of this descriptor is to include jetty specific or common -->
- <!-- configuration for all webapps. If a context has a webdefault.xml -->
- <!-- descriptor, it is applied before the contexts own web.xml file -->
- <!-- -->
- <!-- A context may be assigned a default descriptor by: -->
- <!-- + Calling WebApplicationContext.setDefaultsDescriptor -->
- <!-- + Passed an arg to addWebApplications -->
- <!-- -->
- <!-- This file is used both as the resource within the jetty.jar (which is -->
- <!-- used as the default if no explicit defaults descriptor is set) and it -->
- <!-- is copied to the etc directory of the Jetty distro and explicitly -->
- <!-- by the jetty.xml file. -->
- <!-- -->
- <!-- ===================================================================== -->
-<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns="http://java.sun.com/xml/ns/javaee"
- xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
- id="SonarQube" version="3.0">
-
- <description>
- Default web.xml file.
- This file is applied to a Web application before it's own WEB_INF/web.xml file
- </description>
-
-
- <!-- ==================================================================== -->
- <!-- Context params to control Session Cookies -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!--
- UNCOMMENT TO ACTIVATE <context-param> <param-name>org.eclipse.jetty.servlet.SessionDomain</param-name> <param-value>127.0.0.1</param-value> </context-param> <context-param>
- <param-name>org.eclipse.jetty.servlet.SessionPath</param-name> <param-value>/</param-value> </context-param> <context-param> <param-name>org.eclipse.jetty.servlet.MaxAge</param-name>
- <param-value>-1</param-value> </context-param>
- -->
-
-
- <!-- ==================================================================== -->
- <!-- The default servlet. -->
- <!-- This servlet, normally mapped to /, provides the handling for static -->
- <!-- content, OPTIONS and TRACE methods for the context. -->
- <!-- The following initParameters are supported: -->
- <!-- -->
- <!-- aliases If true, aliases like symlinks are allowed. Note -->
- <!-- that security constraints might be bypassed by -->
- <!-- aliases static content. -->
- <!-- -->
- <!-- acceptRanges If true, range requests and responses are -->
- <!-- supported -->
- <!-- -->
- <!-- dirAllowed If true, directory listings are returned if no -->
- <!-- welcome file is found. Else 403 Forbidden. -->
- <!-- -->
- <!-- welcomeServlets If true, attempt to dispatch to welcome files -->
- <!-- that are servlets, if no matching static -->
- <!-- resources can be found. -->
- <!-- -->
- <!-- redirectWelcome If true, redirect welcome file requests -->
- <!-- else use request dispatcher forwards -->
- <!-- -->
- <!-- gzip If set to true, then static content will be served-->
- <!-- as gzip content encoded if a matching resource is -->
- <!-- found ending with ".gz" -->
- <!-- -->
- <!-- resoureBase Can be set to replace the context resource base -->
- <!-- -->
- <!-- relativeResourceBase -->
- <!-- Set with a pathname relative to the base of the -->
- <!-- servlet context root. Useful for only serving -->
- <!-- static content from only specific subdirectories. -->
- <!-- -->
- <!-- useFileMappedBuffer -->
- <!-- If set to true (the default), a memory mapped -->
- <!-- file buffer will be used to serve static content -->
- <!-- when using an NIO connector. Setting this value -->
- <!-- to false means that a direct buffer will be used -->
- <!-- instead. If you are having trouble with Windows -->
- <!-- file locking, set this to false. -->
- <!-- -->
- <!-- cacheControl If set, all static content will have this value -->
- <!-- set as the cache-control header. -->
- <!-- -->
- <!-- maxCacheSize Maximum size of the static resource cache -->
- <!-- -->
- <!-- maxCachedFileSize Maximum size of any single file in the cache -->
- <!-- -->
- <!-- maxCachedFiles Maximum number of files in the cache -->
- <!-- -->
- <!-- cacheType "nio", "bio" or "both" to determine the type(s) -->
- <!-- of resource cache. A bio cached buffer may be used-->
- <!-- by nio but is not as efficient as a nio buffer. -->
- <!-- An nio cached buffer may not be used by bio. -->
- <!-- -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <servlet>
- <servlet-name>default</servlet-name>
- <servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
- <init-param>
- <param-name>aliases</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>acceptRanges</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <param-name>dirAllowed</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <param-name>welcomeServlets</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>redirectWelcome</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>maxCacheSize</param-name>
- <param-value>256000000</param-value>
- </init-param>
- <init-param>
- <param-name>maxCachedFileSize</param-name>
- <param-value>10000000</param-value>
- </init-param>
- <init-param>
- <param-name>maxCachedFiles</param-name>
- <param-value>1000</param-value>
- </init-param>
- <init-param>
- <param-name>cacheType</param-name>
- <param-value>both</param-value>
- </init-param>
- <init-param>
- <param-name>gzip</param-name>
- <param-value>true</param-value>
- </init-param>
- <init-param>
- <!-- Prevent lock of static resources on Windows in dev mode - see SONAR-2247 -->
- <param-name>useFileMappedBuffer</param-name>
- <param-value>false</param-value>
- </init-param>
- <!--
- <init-param>
- <param-name>cacheControl</param-name>
- <param-value>max-age=3600,public</param-value>
- </init-param>
- -->
- <load-on-startup>0</load-on-startup>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>default</servlet-name>
- <url-pattern>/</url-pattern>
- </servlet-mapping>
-
-
- <!-- ==================================================================== -->
- <!-- JSP Servlet -->
- <!-- This is the jasper JSP servlet from the jakarta project -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- The JSP page compiler and execution servlet, which is the mechanism -->
- <!-- used by Glassfish to support JSP pages. Traditionally, this servlet -->
- <!-- is mapped to URL patterh "*.jsp". This servlet supports the -->
- <!-- following initialization parameters (default values are in square -->
- <!-- brackets): -->
- <!-- -->
- <!-- checkInterval If development is false and reloading is true, -->
- <!-- background compiles are enabled. checkInterval -->
- <!-- is the time in seconds between checks to see -->
- <!-- if a JSP page needs to be recompiled. [300] -->
- <!-- -->
- <!-- compiler Which compiler Ant should use to compile JSP -->
- <!-- pages. See the Ant documenation for more -->
- <!-- information. [javac] -->
- <!-- -->
- <!-- classdebuginfo Should the class file be compiled with -->
- <!-- debugging information? [true] -->
- <!-- -->
- <!-- classpath What class path should I use while compiling -->
- <!-- generated servlets? [Created dynamically -->
- <!-- based on the current web application] -->
- <!-- Set to ? to make the container explicitly set -->
- <!-- this parameter. -->
- <!-- -->
- <!-- development Is Jasper used in development mode (will check -->
- <!-- for JSP modification on every access)? [true] -->
- <!-- -->
- <!-- enablePooling Determines whether tag handler pooling is -->
- <!-- enabled [true] -->
- <!-- -->
- <!-- fork Tell Ant to fork compiles of JSP pages so that -->
- <!-- a separate JVM is used for JSP page compiles -->
- <!-- from the one Tomcat is running in. [true] -->
- <!-- -->
- <!-- ieClassId The class-id value to be sent to Internet -->
- <!-- Explorer when using <jsp:plugin> tags. -->
- <!-- [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93] -->
- <!-- -->
- <!-- javaEncoding Java file encoding to use for generating java -->
- <!-- source files. [UTF-8] -->
- <!-- -->
- <!-- keepgenerated Should we keep the generated Java source code -->
- <!-- for each page instead of deleting it? [true] -->
- <!-- -->
- <!-- logVerbosityLevel The level of detailed messages to be produced -->
- <!-- by this servlet. Increasing levels cause the -->
- <!-- generation of more messages. Valid values are -->
- <!-- FATAL, ERROR, WARNING, INFORMATION, and DEBUG. -->
- <!-- [WARNING] -->
- <!-- -->
- <!-- mappedfile Should we generate static content with one -->
- <!-- print statement per input line, to ease -->
- <!-- debugging? [false] -->
- <!-- -->
- <!-- -->
- <!-- reloading Should Jasper check for modified JSPs? [true] -->
- <!-- -->
- <!-- suppressSmap Should the generation of SMAP info for JSR45 -->
- <!-- debugging be suppressed? [false] -->
- <!-- -->
- <!-- dumpSmap Should the SMAP info for JSR45 debugging be -->
- <!-- dumped to a file? [false] -->
- <!-- False if suppressSmap is true -->
- <!-- -->
- <!-- scratchdir What scratch directory should we use when -->
- <!-- compiling JSP pages? [default work directory -->
- <!-- for the current web application] -->
- <!-- -->
- <!-- tagpoolMaxSize The maximum tag handler pool size [5] -->
- <!-- -->
- <!-- xpoweredBy Determines whether X-Powered-By response -->
- <!-- header is added by generated servlet [false] -->
- <!-- -->
- <!-- If you wish to use Jikes to compile JSP pages: -->
- <!-- Set the init parameter "compiler" to "jikes". Define -->
- <!-- the property "-Dbuild.compiler.emacs=true" when starting Jetty -->
- <!-- to cause Jikes to emit error messages in a format compatible with -->
- <!-- Jasper. -->
- <!-- If you get an error reporting that jikes can't use UTF-8 encoding, -->
- <!-- try setting the init parameter "javaEncoding" to "ISO-8859-1". -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <servlet
- id="jsp"
- >
- <servlet-name>jsp</servlet-name>
- <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
- <init-param>
- <param-name>logVerbosityLevel</param-name>
- <param-value>DEBUG</param-value>
- </init-param>
- <init-param>
- <param-name>fork</param-name>
- <param-value>false</param-value>
- </init-param>
- <init-param>
- <param-name>xpoweredBy</param-name>
- <param-value>false</param-value>
- </init-param>
- <!--
- <init-param>
- <param-name>classpath</param-name>
- <param-value>?</param-value>
- </init-param>
- -->
- <load-on-startup>0</load-on-startup>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>jsp</servlet-name>
- <url-pattern>*.jsp</url-pattern>
- <url-pattern>*.jspf</url-pattern>
- <url-pattern>*.jspx</url-pattern>
- <url-pattern>*.xsp</url-pattern>
- <url-pattern>*.JSP</url-pattern>
- <url-pattern>*.JSPF</url-pattern>
- <url-pattern>*.JSPX</url-pattern>
- <url-pattern>*.XSP</url-pattern>
- </servlet-mapping>
-
- <!-- ==================================================================== -->
- <!-- Dynamic Servlet Invoker. -->
- <!-- This servlet invokes anonymous servlets that have not been defined -->
- <!-- in the web.xml or by other means. The first element of the pathInfo -->
- <!-- of a request passed to the envoker is treated as a servlet name for -->
- <!-- an existing servlet, or as a class name of a new servlet. -->
- <!-- This servlet is normally mapped to /servlet/* -->
- <!-- This servlet support the following initParams: -->
- <!-- -->
- <!-- nonContextServlets If false, the invoker can only load -->
- <!-- servlets from the contexts classloader. -->
- <!-- This is false by default and setting this -->
- <!-- to true may have security implications. -->
- <!-- -->
- <!-- verbose If true, log dynamic loads -->
- <!-- -->
- <!-- * All other parameters are copied to the -->
- <!-- each dynamic servlet as init parameters -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!--
- Uncomment for dynamic invocation <servlet> <servlet-name>invoker</servlet-name> <servlet-class>org.eclipse.jetty.servlet.Invoker</servlet-class> <init-param> <param-name>verbose</param-name>
- <param-value>false</param-value> </init-param> <init-param> <param-name>nonContextServlets</param-name> <param-value>false</param-value> </init-param> <init-param>
- <param-name>dynamicParam</param-name> <param-value>anyValue</param-value> </init-param> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>invoker</servlet-name>
- <url-pattern>/servlet/*</url-pattern> </servlet-mapping>
- -->
-
-
-
- <!-- ==================================================================== -->
- <session-config>
- <session-timeout>30</session-timeout>
- </session-config>
-
- <!-- ==================================================================== -->
- <!-- Default MIME mappings -->
- <!-- The default MIME mappings are provided by the mime.properties -->
- <!-- resource in the org.eclipse.jetty.server.jar file. Additional or modified -->
- <!-- mappings may be specified here -->
- <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
- <!-- UNCOMMENT TO ACTIVATE
- <mime-mapping>
- <extension>mysuffix</extension>
- <mime-type>mymime/type</mime-type>
- </mime-mapping>
- -->
-
- <!-- ==================================================================== -->
- <welcome-file-list>
- <welcome-file>index.html</welcome-file>
- <welcome-file>index.htm</welcome-file>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
-
- <!-- ==================================================================== -->
- <locale-encoding-mapping-list>
- <locale-encoding-mapping>
- <locale>ar</locale>
- <encoding>ISO-8859-6</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>be</locale>
- <encoding>ISO-8859-5</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>bg</locale>
- <encoding>ISO-8859-5</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>ca</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>cs</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>da</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>de</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>el</locale>
- <encoding>ISO-8859-7</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>en</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>es</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>et</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>fi</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>fr</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>hr</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>hu</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>is</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>it</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>iw</locale>
- <encoding>ISO-8859-8</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>ja</locale>
- <encoding>Shift_JIS</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>ko</locale>
- <encoding>EUC-KR</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>lt</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>lv</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>mk</locale>
- <encoding>ISO-8859-5</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>nl</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>no</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>pl</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>pt</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>ro</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>ru</locale>
- <encoding>ISO-8859-5</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>sh</locale>
- <encoding>ISO-8859-5</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>sk</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>sl</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>sq</locale>
- <encoding>ISO-8859-2</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>sr</locale>
- <encoding>ISO-8859-5</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>sv</locale>
- <encoding>ISO-8859-1</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>tr</locale>
- <encoding>ISO-8859-9</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>uk</locale>
- <encoding>ISO-8859-5</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>zh</locale>
- <encoding>GB2312</encoding>
- </locale-encoding-mapping>
- <locale-encoding-mapping>
- <locale>zh_TW</locale>
- <encoding>Big5</encoding>
- </locale-encoding-mapping>
- </locale-encoding-mapping-list>
-
- <security-constraint>
- <web-resource-collection>
- <web-resource-name>Disable TRACE</web-resource-name>
- <url-pattern>/</url-pattern>
- <http-method>TRACE</http-method>
- </web-resource-collection>
- <auth-constraint/>
- </security-constraint>
-
-</web-app>
-
diff --git a/sonar-server/src/main/java/org/sonar/server/startup/GenerateBootstrapIndex.java b/sonar-server/src/main/java/org/sonar/server/startup/GenerateBootstrapIndex.java
index e2891a827d2..b1768c451df 100644
--- a/sonar-server/src/main/java/org/sonar/server/startup/GenerateBootstrapIndex.java
+++ b/sonar-server/src/main/java/org/sonar/server/startup/GenerateBootstrapIndex.java
@@ -84,7 +84,7 @@ public final class GenerateBootstrapIndex {
return libs;
}
- private static final String[] IGNORE = {"jtds", "mysql", "postgresql", "jruby", "jfreechart", "eastwood", "jetty"};
+ private static final String[] IGNORE = {"jtds", "mysql", "postgresql", "jruby", "jfreechart", "eastwood"};
/**
* Dirty hack to disable downloading for certain files.
diff --git a/sonar-server/src/main/webapp/META-INF/context.xml b/sonar-server/src/main/webapp/META-INF/context.xml
index 389b9f408d1..b2c70d32f0f 100644
--- a/sonar-server/src/main/webapp/META-INF/context.xml
+++ b/sonar-server/src/main/webapp/META-INF/context.xml
@@ -1,3 +1,4 @@
-<Context antiJARLocking="true" antiResourceLocking="true" useHttpOnly="true">
- <ResourceLink name="jdbc/sonar" global="jdbc/sonar" type="javax.sql.DataSource" />
-</Context> \ No newline at end of file
+<Context antiJARLocking="true" antiResourceLocking="true" useHttpOnly="true" reloadable="false" processTlds="false"
+ unpackWAR="false" useNaming="false" xmlValidation="false" xmlNamespaceAware="false" tldValidation="false"
+ tldNamespaceAware="false">
+</Context>
diff --git a/sonar-server/src/main/webapp/WEB-INF/web.xml b/sonar-server/src/main/webapp/WEB-INF/web.xml
index 51e389f9639..69c75338ee5 100644
--- a/sonar-server/src/main/webapp/WEB-INF/web.xml
+++ b/sonar-server/src/main/webapp/WEB-INF/web.xml
@@ -2,7 +2,9 @@
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
- id="SonarQube" version="3.0">
+ id="SonarQube"
+ version="3.0"
+ metadata-complete="true">
<display-name>SonarQube</display-name>
<context-param>
@@ -46,31 +48,7 @@
<filter-name>RackFilter</filter-name>
<filter-class>org.jruby.rack.RackFilter</filter-class>
</filter>
- <filter>
- <!-- compatibility with servlet 2.5 containers like tomcat 6 -->
- <filter-name>ContinuationFilter</filter-name>
- <filter-class>org.eclipse.jetty.continuation.ContinuationFilter</filter-class>
- </filter>
- <filter>
- <filter-name>GZIPFilter</filter-name>
- <filter-class>org.eclipse.jetty.servlets.GzipFilter</filter-class>
- <init-param>
- <param-name>minGzipSize</param-name>
- <param-value>1024</param-value>
- </init-param>
- <init-param>
- <param-name>bufferSize</param-name>
- <param-value>16384</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>ContinuationFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
- <filter-mapping>
- <filter-name>GZIPFilter</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
+
<filter-mapping>
<filter-name>DatabaseSessionFilter</filter-name>
<url-pattern>/*</url-pattern>
diff --git a/sonar-server/src/test/java/org/sonar/server/startup/GenerateBootstrapIndexTest.java b/sonar-server/src/test/java/org/sonar/server/startup/GenerateBootstrapIndexTest.java
index 4bf0d40f0d2..77fff0b93e0 100644
--- a/sonar-server/src/test/java/org/sonar/server/startup/GenerateBootstrapIndexTest.java
+++ b/sonar-server/src/test/java/org/sonar/server/startup/GenerateBootstrapIndexTest.java
@@ -59,7 +59,6 @@ public class GenerateBootstrapIndexTest {
assertThat(GenerateBootstrapIndex.isIgnored("jtds-1.2.4.jar")).isTrue();
assertThat(GenerateBootstrapIndex.isIgnored("jfreechart-1.0.9.jar")).isTrue();
assertThat(GenerateBootstrapIndex.isIgnored("eastwood-1.1.0.jar")).isTrue();
- assertThat(GenerateBootstrapIndex.isIgnored("jetty-util-6.1.24.jar")).isTrue();
assertThat(GenerateBootstrapIndex.isIgnored("jruby-complete-1.5.6.jar")).isTrue();
assertThat(GenerateBootstrapIndex.isIgnored("jruby-rack-1.0.5.jar")).isTrue();
}
diff --git a/sonar-ws-client/pom.xml b/sonar-ws-client/pom.xml
index 3d0d98ae3d6..a836636f58f 100644
--- a/sonar-ws-client/pom.xml
+++ b/sonar-ws-client/pom.xml
@@ -51,8 +51,8 @@
<scope>test</scope>
</dependency>
<dependency>
- <groupId>org.mortbay.jetty</groupId>
- <artifactId>servlet-api</artifactId>
+ <groupId>javax.servlet</groupId>
+ <artifactId>javax.servlet-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>