diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2011-10-09 18:44:11 +0200 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2011-10-09 18:44:11 +0200 |
commit | 45e2d5db126fd13552b56f51ad5ead72615e71d0 (patch) | |
tree | ad63ac861c02c8eaf66378f5bff9f853907b5fe3 | |
parent | e72f4ca2d9be6d3dafd345664cc7244efd2a5a7c (diff) | |
download | sonarqube-45e2d5db126fd13552b56f51ad5ead72615e71d0.tar.gz sonarqube-45e2d5db126fd13552b56f51ad5ead72615e71d0.zip |
SONAR-2881 Do not rebuild the WAR file when changing conf/logback.xml
30 files changed, 341 insertions, 204 deletions
@@ -702,32 +702,27 @@ <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> - <version>1.5.6</version> + <version>1.6.2</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> - <version>1.5.6</version> + <version>1.6.2</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> - <version>1.5.6</version> + <version>1.6.2</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> - <version>0.9.15</version> + <version>0.9.30</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> - <version>0.9.15</version> - </dependency> - <dependency> - <groupId>janino</groupId> - <artifactId>janino</artifactId> - <version>2.5.10</version> + <version>0.9.30</version> </dependency> <dependency> <groupId>org.apache.derby</groupId> diff --git a/sonar-application/pom.xml b/sonar-application/pom.xml index 2e009da50ef..f4c91172d7a 100644 --- a/sonar-application/pom.xml +++ b/sonar-application/pom.xml @@ -83,26 +83,6 @@ <scope>test</scope> </dependency> <dependency> - <groupId>org.slf4j</groupId> - <artifactId>jcl-over-slf4j</artifactId> - </dependency> - <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> - </dependency> - <dependency> - <groupId>ch.qos.logback</groupId> - <artifactId>logback-classic</artifactId> - </dependency> - <dependency> - <groupId>ch.qos.logback</groupId> - <artifactId>logback-core</artifactId> - </dependency> - <dependency> - <groupId>janino</groupId> - <artifactId>janino</artifactId> - </dependency> - <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> diff --git a/sonar-application/src/main/assembly/conf/logback.xml b/sonar-application/src/main/assembly/conf/logback.xml index 407cbdbe265..e84e65ad635 100644 --- a/sonar-application/src/main/assembly/conf/logback.xml +++ b/sonar-application/src/main/assembly/conf/logback.xml @@ -2,72 +2,42 @@ <configuration debug="false"> - <!-- appender used when deploying Sonar WAR on a JEE server --> - <appender name="SONAR_WAR" class="ch.qos.logback.core.ConsoleAppender"> - <!-- avoid to log 404 file not found messages from the rails file servlet --> - <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> - <evaluator name="mavenRepoFileNotFound"> - <expression>message.startsWith("files: File not found: /maven")</expression> - </evaluator> - <OnMismatch>NEUTRAL</OnMismatch> - <OnMatch>DENY</OnMatch> - </filter> - <layout class="ch.qos.logback.classic.PatternLayout"> - <pattern> - %d{yyyy.MM.dd HH:mm:ss} %-5level %logger{20} %X %msg%n - </pattern> - </layout> - </appender> - - <!-- SONAR_STANDALONE/ --> - <!-- do not edit/remove the previous comment --> <appender name="SONAR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> - <File>../../logs/sonar.log</File> + <File>${SONAR_HOME}/logs/sonar.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> - <param name="FileNamePattern" value="../../logs/sonar.%i.log"/> + <param name="FileNamePattern" value="${SONAR_HOME}/logs/sonar.%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> - <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> - <evaluator name="mavenRepoFileNotFound"> - <expression>message.startsWith("files: File not found: /maven")</expression> - </evaluator> - <OnMismatch>NEUTRAL</OnMismatch> - <OnMatch>DENY</OnMatch> - </filter> - <layout class="ch.qos.logback.classic.PatternLayout"> + <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern> %d{yyyy.MM.dd HH:mm:ss} %-5level %logger{20} %X %msg%n </pattern> - </layout> + </encoder> </appender> <!-- appender used to profile Sonar Server --> <appender name="PROFILING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> - <File>../../logs/profiling.log</File> + <File>${SONAR_HOME}/logs/profiling.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> - <param name="FileNamePattern" value="../../logs/profiling.%i.log"/> + <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> - <layout class="ch.qos.logback.classic.PatternLayout"> + <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern> %d{yyyy.MM.dd HH:mm:ss} %-5level %logger{20} %X %msg%n </pattern> - </layout> + </encoder> </appender> - <!-- do not edit/remove the following comment --> - <!-- /SONAR_STANDALONE --> - - - <!-- + <!-- Profiling of JRuby on Rails requests . Uncomment in order to log HTTP and SQL requests. Execute the following command to get the HTTP requests with execution time > 10s : grep 'rails Completed in [0-9]\{5,\}ms' < profiling.log diff --git a/sonar-application/src/main/assembly/war/build.xml b/sonar-application/src/main/assembly/war/build.xml index 0832a7a58ff..9a2467fb881 100644 --- a/sonar-application/src/main/assembly/war/build.xml +++ b/sonar-application/src/main/assembly/war/build.xml @@ -32,25 +32,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 <fileset dir="../extensions/jdbc-driver" includes="**/*.jar"/> </copy> - <replace file="build/sonar-server/WEB-INF/classes/sonar-war.properties" token="#sonar.home=" value="sonar.home=${sonarHome}" /> - - <!-- copy the logback config --> - <copy todir="build/sonar-server/WEB-INF/classes"> - <fileset dir="../conf" includes="logback.xml"/> - </copy> - - <!-- remove appenders configured for standalone mode --> - <replace file="build/sonar-server/WEB-INF/classes/logback.xml"> - <replacetoken><![CDATA[<appender-ref ref="SONAR_FILE"/>]]></replacetoken> - <replacevalue><![CDATA[<appender-ref ref="SONAR_WAR"/>]]></replacevalue> - </replace> - <replace file="build/sonar-server/WEB-INF/classes/logback.xml"> - <replacetoken><![CDATA[<appender-ref ref="PROFILING_FILE"/>]]></replacetoken> - <replacevalue><![CDATA[<appender-ref ref="SONAR_WAR"/>]]></replacevalue> - </replace> - - <!-- see SONAR-1811. The appender SONAR_FILE must be removed from logback configuration --> - <replaceregexp file="build/sonar-server/WEB-INF/classes/logback.xml" match="SONAR_STANDALONE/(.*)/SONAR_STANDALONE" replace="" byline="false" flags="gs"/> + <replace file="build/sonar-server/WEB-INF/classes/sonar-war.properties" token="#SONAR_HOME=" value="SONAR_HOME=${sonarHome}" /> <war destfile="sonar.war" webxml="build/sonar-server/WEB-INF/web.xml"> <fileset dir="build/sonar-server"/> diff --git a/sonar-application/src/main/java/org/sonar/application/JettyEmbedder.java b/sonar-application/src/main/java/org/sonar/application/JettyEmbedder.java index 37b9c9c216b..713ecab0267 100644 --- a/sonar-application/src/main/java/org/sonar/application/JettyEmbedder.java +++ b/sonar-application/src/main/java/org/sonar/application/JettyEmbedder.java @@ -29,7 +29,6 @@ import org.mortbay.jetty.nio.SelectChannelConnector; import org.mortbay.jetty.webapp.WebAppContext; import org.mortbay.thread.QueuedThreadPool; import org.mortbay.xml.XmlConfiguration; -import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; @@ -85,11 +84,12 @@ public class JettyEmbedder { try { server.stop(); } catch (Exception e) { - LoggerFactory.getLogger(getClass()).error("Can not stop the Jetty server", e); + System.err.println("Can not stop the Jetty server"); + e.printStackTrace(); } } }); - LoggerFactory.getLogger("org.sonar.INFO").info("Sonar started: " + toString()); +// LoggerFactory.getLogger("org.sonar.INFO").info("Sonar started: " + toString()); } private Server configureProgrammatically() throws URISyntaxException, IOException { @@ -123,7 +123,7 @@ public class JettyEmbedder { connector.setAcceptors(2); connector.setConfidentialPort(8443); if (ajp13Port > 0) { - LoggerFactory.getLogger("org.sonar.INFO").info("AJP13 connector is on port " + ajp13Port); + System.out.println("AJP13 connector is on port " + ajp13Port); Connector ajpConnector = new Ajp13SocketConnector(); ajpConnector.setPort(ajp13Port); server.addConnector(ajpConnector); 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 c92b5069e6e..1af81c86d0e 100644 --- a/sonar-application/src/main/java/org/sonar/application/StartServer.java +++ b/sonar-application/src/main/java/org/sonar/application/StartServer.java @@ -34,7 +34,6 @@ public final class StartServer { } public static void main(String[] args) throws Exception { - configureLogback(); configureHome(); Properties configuration = getConfiguration(); @@ -51,7 +50,7 @@ public final class StartServer { private static void configureRequestLogs(JettyEmbedder jetty, Properties configuration) { String filenamePattern = configuration.getProperty("sonar.web.jettyRequestLogs"); - if (filenamePattern!=null) { + if (filenamePattern != null) { jetty.configureRequestLogs(filenamePattern); } } @@ -64,12 +63,7 @@ public final class StartServer { private static void configureHome() throws URISyntaxException { File confFile = new File(StartServer.class.getResource("/conf/sonar.properties").toURI()); - System.setProperty("sonar.home", confFile.getParentFile().getParentFile().getAbsolutePath()); - } - - private static void configureLogback() throws URISyntaxException { - File confFile = new File(StartServer.class.getResource("/conf/logback.xml").toURI()); - System.setProperty("logback.configurationFile", confFile.getAbsolutePath()); - System.setProperty("logback.ContextSelector", "JNDI"); + System.setProperty("SONAR_HOME" /* see constant org.sonar.server.platform.SonarHome.PROPERTY */, + confFile.getParentFile().getParentFile().getAbsolutePath()); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/config/BatchSettingsEnhancer.java b/sonar-batch/src/main/java/org/sonar/batch/config/BatchSettingsEnhancer.java index a770fa64adf..ec6030cf747 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/config/BatchSettingsEnhancer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/config/BatchSettingsEnhancer.java @@ -44,7 +44,7 @@ public final class BatchSettingsEnhancer { public void start() { String projectKey = reactor.getRoot().getKey(); setIfNotDefined(ConfigurationUtils.getProjectProperties(dbFactory, projectKey)); - setIfNotDefined(ConfigurationUtils.getGlobalProperties(dbFactory)); + setIfNotDefined(ConfigurationUtils.getGeneralProperties(dbFactory)); settings.updateDeprecatedCommonsConfiguration(); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/config/ProjectSettings.java b/sonar-batch/src/main/java/org/sonar/batch/config/ProjectSettings.java index 4fcc837791b..ca5e52ff96d 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/config/ProjectSettings.java +++ b/sonar-batch/src/main/java/org/sonar/batch/config/ProjectSettings.java @@ -73,7 +73,7 @@ public class ProjectSettings extends Settings { } private void loadDatabaseGlobalSettings() { - List<Property> props = ConfigurationUtils.getGlobalProperties(dbFactory); + List<Property> props = ConfigurationUtils.getGeneralProperties(dbFactory); for (Property dbProperty : props) { setProperty(dbProperty.getKey(), dbProperty.getValue()); } diff --git a/sonar-channel/pom.xml b/sonar-channel/pom.xml index b6834b99a00..1f5f17bdb6d 100644 --- a/sonar-channel/pom.xml +++ b/sonar-channel/pom.xml @@ -30,10 +30,5 @@ <artifactId>hamcrest-all</artifactId> <scope>test</scope> </dependency> - <dependency> - <groupId>ch.qos.logback</groupId> - <artifactId>logback-classic</artifactId> - <scope>test</scope> - </dependency> </dependencies> </project>
\ No newline at end of file diff --git a/sonar-core/src/main/java/org/sonar/core/config/ConfigurationUtils.java b/sonar-core/src/main/java/org/sonar/core/config/ConfigurationUtils.java index bf4eda351a4..e5ea9230a47 100644 --- a/sonar-core/src/main/java/org/sonar/core/config/ConfigurationUtils.java +++ b/sonar-core/src/main/java/org/sonar/core/config/ConfigurationUtils.java @@ -51,13 +51,13 @@ public final class ConfigurationUtils { public static Properties openProperties(File file) throws IOException { FileInputStream input = FileUtils.openInputStream(file); - return openInputStream(input); + return readInputStream(input); } /** * Note that the input stream is closed in this method. */ - public static Properties openInputStream(InputStream input) throws IOException { + public static Properties readInputStream(InputStream input) throws IOException { try { Properties p = new Properties(); p.load(input); @@ -97,7 +97,7 @@ public final class ConfigurationUtils { return Collections.emptyList(); } - public static List<Property> getGlobalProperties(DatabaseSessionFactory dbFactory) { + public static List<Property> getGeneralProperties(DatabaseSessionFactory dbFactory) { DatabaseSession session = prepareDbSession(dbFactory); return session .createQuery("from " + Property.class.getSimpleName() + " p where p.resourceId is null and p.userId is null") diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java b/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java index 958e01870d3..d6eb8becffa 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java @@ -64,7 +64,7 @@ public interface CoreProperties { /* Global settings */ - String SONAR_HOME = "sonar.home"; + String SONAR_HOME = "SONAR_HOME"; String PROJECT_BRANCH_PROPERTY = "sonar.branch"; String PROJECT_VERSION_PROPERTY = "sonar.projectVersion"; diff --git a/sonar-server/pom.xml b/sonar-server/pom.xml index 33a79cde664..4cd62ce8577 100644 --- a/sonar-server/pom.xml +++ b/sonar-server/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> <groupId>org.codehaus.sonar</groupId> @@ -100,10 +101,6 @@ <artifactId>commons-io</artifactId> </dependency> <dependency> - <groupId>org.slf4j</groupId> - <artifactId>slf4j-api</artifactId> - </dependency> - <dependency> <groupId>org.picocontainer</groupId> <artifactId>picocontainer</artifactId> </dependency> @@ -125,9 +122,11 @@ <groupId>jfree</groupId> <artifactId>jfreechart</artifactId> </dependency> + + <!-- logging --> <dependency> - <groupId>janino</groupId> - <artifactId>janino</artifactId> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-api</artifactId> </dependency> <dependency> <groupId>ch.qos.logback</groupId> @@ -138,6 +137,16 @@ <artifactId>logback-core</artifactId> </dependency> <dependency> + <groupId>org.slf4j</groupId> + <artifactId>jcl-over-slf4j</artifactId> + </dependency> + <dependency> + <groupId>org.slf4j</groupId> + <artifactId>log4j-over-slf4j</artifactId> + </dependency> + + + <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> </dependency> @@ -369,7 +378,7 @@ </connectors> <systemProperties> <systemProperty> - <name>sonar.home</name> + <name>SONAR_HOME</name> <value>${project.build.directory}/sonar-dev-home</value> </systemProperty> </systemProperties> diff --git a/sonar-server/src/main/java/org/sonar/server/database/JndiDatabaseConnector.java b/sonar-server/src/main/java/org/sonar/server/database/JndiDatabaseConnector.java index 52d016c0b0e..d4742cda149 100644 --- a/sonar-server/src/main/java/org/sonar/server/database/JndiDatabaseConnector.java +++ b/sonar-server/src/main/java/org/sonar/server/database/JndiDatabaseConnector.java @@ -19,7 +19,6 @@ */ package org.sonar.server.database; -import org.apache.commons.configuration.Configuration; import org.apache.commons.dbcp.BasicDataSourceFactory; import org.apache.commons.lang.StringUtils; import org.hibernate.cfg.Environment; @@ -32,7 +31,6 @@ import org.sonar.jpa.session.AbstractDatabaseConnector; import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; -import java.util.Iterator; import java.util.List; import java.util.Properties; diff --git a/sonar-server/src/main/java/org/sonar/server/mavendeployer/MavenRepository.java b/sonar-server/src/main/java/org/sonar/server/mavendeployer/MavenRepository.java index bf956a5949e..3fc026d0629 100644 --- a/sonar-server/src/main/java/org/sonar/server/mavendeployer/MavenRepository.java +++ b/sonar-server/src/main/java/org/sonar/server/mavendeployer/MavenRepository.java @@ -22,7 +22,7 @@ package org.sonar.server.mavendeployer; import org.apache.commons.io.FileUtils; import org.sonar.api.config.Settings; import org.sonar.api.platform.Server; -import org.sonar.server.configuration.ServerSettings; +import org.sonar.server.platform.ServerSettings; import org.sonar.server.platform.DefaultServerFileSystem; import java.io.File; diff --git a/sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java b/sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java index a3ea2935404..ab70ba90188 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/DefaultServerFileSystem.java @@ -26,7 +26,6 @@ import org.sonar.api.config.Settings; import org.sonar.api.platform.ServerFileSystem; import org.sonar.api.utils.Logs; import org.sonar.jpa.session.DatabaseConnector; -import org.sonar.server.configuration.ServerSettings; import java.io.File; import java.io.IOException; diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Logback.java b/sonar-server/src/main/java/org/sonar/server/platform/Logback.java new file mode 100644 index 00000000000..eec641e2f65 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/platform/Logback.java @@ -0,0 +1,53 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.server.platform; + +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.joran.JoranConfigurator; +import ch.qos.logback.core.joran.spi.JoranException; +import ch.qos.logback.core.util.StatusPrinter; +import org.slf4j.LoggerFactory; + +import java.io.File; + +/** + * Configure Logback with $SONAR_HOME/conf/logback.xml + * + * @since 2.12 + */ +final class Logback { + + static void configure() { + configure(new File(SonarHome.getHome(), "conf/logback.xml")); + } + + static void configure(File logbackFile) { + LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); + try { + JoranConfigurator configurator = new JoranConfigurator(); + configurator.setContext(lc); + lc.reset(); + configurator.doConfigure(logbackFile); + } catch (JoranException e) { + // StatusPrinter will handle this + } + StatusPrinter.printInCaseOfErrorsOrWarnings(lc); + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java index 8f65905de3e..3c4ae6601ce 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/Platform.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/Platform.java @@ -50,7 +50,6 @@ import org.sonar.jpa.session.DatabaseSessionFactory; import org.sonar.jpa.session.DatabaseSessionProvider; import org.sonar.jpa.session.ThreadLocalDatabaseSessionFactory; import org.sonar.server.charts.ChartFactory; -import org.sonar.server.configuration.ServerSettings; import org.sonar.server.configuration.Backup; import org.sonar.server.configuration.ProfilesManager; import org.sonar.server.database.EmbeddedDatabaseFactory; diff --git a/sonar-server/src/main/java/org/sonar/server/platform/PlatformLifecycleListener.java b/sonar-server/src/main/java/org/sonar/server/platform/PlatformLifecycleListener.java index 526e4f68239..10dcb45375c 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/PlatformLifecycleListener.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/PlatformLifecycleListener.java @@ -25,6 +25,7 @@ import javax.servlet.ServletContextListener; public final class PlatformLifecycleListener implements ServletContextListener { public void contextInitialized(ServletContextEvent event) { + Logback.configure(); Platform.getInstance().init(event.getServletContext()); Platform.getInstance().start(); } diff --git a/sonar-server/src/main/java/org/sonar/server/configuration/ServerSettings.java b/sonar-server/src/main/java/org/sonar/server/platform/ServerSettings.java index 72b0afb6a8d..2dc7409741d 100644 --- a/sonar-server/src/main/java/org/sonar/server/configuration/ServerSettings.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/ServerSettings.java @@ -17,27 +17,29 @@ * License along with Sonar; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 */ -package org.sonar.server.configuration; +package org.sonar.server.platform; import org.apache.commons.configuration.Configuration; -import org.apache.commons.lang.StringUtils; import org.sonar.api.CoreProperties; import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.config.Settings; -import org.sonar.api.database.DatabaseSession; import org.sonar.api.database.configuration.Property; import org.sonar.core.config.ConfigurationUtils; import org.sonar.jpa.session.DatabaseSessionFactory; import javax.servlet.ServletContext; import java.io.File; -import java.io.IOException; -import java.io.InputStream; import java.util.List; import java.util.Properties; /** - * Load settings from environment, conf/sonar.properties and database + * Load settings in the following order (the last override the first) : + * <ol> + * <li>general settings persisted in database</li> + * <li>file $SONAR_HOME/conf/sonar.properties</li> + * <li>environment variables</li> + * <li>system properties</li> + * </ol> * * @since 2.12 */ @@ -47,32 +49,41 @@ public class ServerSettings extends Settings { private DatabaseSessionFactory sessionFactory; private Configuration deprecatedConfiguration; - private File sonarHome; private File deployDir; public ServerSettings(PropertyDefinitions definitions, Configuration deprecatedConfiguration, ServletContext servletContext) { super(definitions); this.deprecatedConfiguration = deprecatedConfiguration; - this.sonarHome = getSonarHome(); this.deployDir = getDeployDir(servletContext); load(); } + ServerSettings(PropertyDefinitions definitions, Configuration deprecatedConfiguration, File deployDir, File sonarHome) { + super(definitions); + this.deprecatedConfiguration = deprecatedConfiguration; + this.deployDir = deployDir; + load(sonarHome); + } + public ServerSettings setSessionFactory(DatabaseSessionFactory sessionFactory) { this.sessionFactory = sessionFactory; return this; } public ServerSettings load() { + return load(SonarHome.getHome()); + } + + ServerSettings load(File sonarHome) { clear(); setProperty(CoreProperties.SONAR_HOME, sonarHome.getAbsolutePath()); setProperty(DEPLOY_DIR, deployDir.getAbsolutePath()); - - // order is important + + // order is important : the last override the first loadDatabaseSettings(); + loadPropertiesFile(sonarHome); addEnvironmentVariables(); addSystemProperties(); - loadPropertiesFile(); // update deprecated configuration ConfigurationUtils.copyToCommonsConfiguration(properties, deprecatedConfiguration); @@ -82,21 +93,14 @@ public class ServerSettings extends Settings { private void loadDatabaseSettings() { if (sessionFactory != null) { - DatabaseSession session = sessionFactory.getSession(); - - // Ugly workaround before the move to myBatis - // Session is not up-to-date when Ruby on Rails inserts new rows in its own transaction. Seems like - // Hibernate keeps a cache... - session.commit(); - List<Property> properties = session.createQuery("from " + Property.class.getSimpleName() + " p where p.resourceId is null and p.userId is null").getResultList(); - + List<Property> properties = ConfigurationUtils.getGeneralProperties(sessionFactory); for (Property property : properties) { setProperty(property.getKey(), property.getValue()); } } } - private void loadPropertiesFile() { + private void loadPropertiesFile(File sonarHome) { File propertiesFile = new File(sonarHome, "conf/sonar.properties"); if (!propertiesFile.isFile() || !propertiesFile.exists()) { throw new IllegalStateException("Properties file does not exist: " + propertiesFile); @@ -106,7 +110,6 @@ public class ServerSettings extends Settings { Properties p = ConfigurationUtils.openProperties(propertiesFile); p = ConfigurationUtils.interpolateEnvVariables(p); addProperties(p); - } catch (Exception e) { throw new IllegalStateException("Fail to load configuration file: " + propertiesFile, e); } @@ -123,34 +126,4 @@ public class ServerSettings extends Settings { } return dir; } - - static File getSonarHome() { - String home = System.getProperty("sonar.home"); - if (StringUtils.isBlank(home)) { - home = System.getenv("SONAR_HOME"); - if (StringUtils.isBlank(home)) { - Properties warProps = openWarProperties(); - home = warProps.getProperty("sonar.home"); - } - } - - if (StringUtils.isBlank(home)) { - throw new IllegalStateException("Please set location to SONAR_HOME"); - } - - File dir = new File(home); - if (!dir.isDirectory() || !dir.exists()) { - throw new IllegalStateException("SONAR_HOME is not valid: " + home); - } - return dir; - } - - private static Properties openWarProperties() { - try { - InputStream input = ServerSettings.class.getResourceAsStream("/sonar-war.properties"); - return ConfigurationUtils.openInputStream(input); - } catch (IOException e) { - throw new IllegalStateException("Fail to load the file sonar-war.properties", e); - } - } } diff --git a/sonar-server/src/main/java/org/sonar/server/platform/ServerStartException.java b/sonar-server/src/main/java/org/sonar/server/platform/ServerStartException.java index 828c80505e2..e1cd5522226 100644 --- a/sonar-server/src/main/java/org/sonar/server/platform/ServerStartException.java +++ b/sonar-server/src/main/java/org/sonar/server/platform/ServerStartException.java @@ -21,9 +21,6 @@ package org.sonar.server.platform; public class ServerStartException extends RuntimeException { - public ServerStartException() { - } - public ServerStartException(String s) { super(s); } @@ -31,8 +28,4 @@ public class ServerStartException extends RuntimeException { public ServerStartException(String s, Throwable throwable) { super(s, throwable); } - - public ServerStartException(Throwable throwable) { - super(throwable); - } } diff --git a/sonar-server/src/main/java/org/sonar/server/platform/SonarHome.java b/sonar-server/src/main/java/org/sonar/server/platform/SonarHome.java new file mode 100644 index 00000000000..454f2fd5a43 --- /dev/null +++ b/sonar-server/src/main/java/org/sonar/server/platform/SonarHome.java @@ -0,0 +1,83 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.server.platform; + +import org.apache.commons.lang.StringUtils; +import org.sonar.core.config.ConfigurationUtils; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +/** + * Search fo the Sonar installation directory in the following ordered steps : + * <ol> + * <li>system property SONAR_HOME</li> + * <li>environment variable SONAR_HOME</li> + * <li>property SONAR_HOME in the file WEB-INF/classes/sonar-war.properties</li> + * </ol> + * + * @since 2.12 + */ +final class SonarHome { + + static final String PROPERTY = "SONAR_HOME"; + private static File home; + + static File getHome() { + if (home == null) { + home = locate(); + System.setProperty(PROPERTY, home.getAbsolutePath()); + } + return home; + } + + static File locate() { + String home = System.getProperty(PROPERTY); + if (StringUtils.isBlank(home)) { + home = System.getenv(PROPERTY); + if (StringUtils.isBlank(home)) { + home = openWarProperties().getProperty(PROPERTY); + } + } + + if (StringUtils.isBlank(home)) { + throw new IllegalStateException("Sonar home is not defined. " + + "Please set the environment variable/system property " + PROPERTY + " or edit the file WEB-INF/classes/sonar-war.properties"); + } + + File dir = new File(home); + if (!dir.isDirectory() || !dir.exists()) { + throw new IllegalStateException(PROPERTY + " is not valid: " + home + ". Please fix the environment variable/system property SONAR_HOME or " + + "the file WEB-INF/classes/sonar-war.properties"); + } + return dir; + } + + private static Properties openWarProperties() { + try { + InputStream input = SonarHome.class.getResourceAsStream("/sonar-war.properties"); + return ConfigurationUtils.readInputStream(input); // it closes the stream + } catch (IOException e) { + throw new IllegalStateException("Fail to load the file sonar-war.properties", e); + } + } +} diff --git a/sonar-server/src/main/java/org/sonar/server/startup/GwtPublisher.java b/sonar-server/src/main/java/org/sonar/server/startup/GwtPublisher.java index f61f2bc1b73..6f3e0c69e52 100644 --- a/sonar-server/src/main/java/org/sonar/server/startup/GwtPublisher.java +++ b/sonar-server/src/main/java/org/sonar/server/startup/GwtPublisher.java @@ -29,7 +29,7 @@ import org.sonar.api.utils.SonarException; import org.sonar.api.utils.TimeProfiler; import org.sonar.api.utils.ZipUtils; import org.sonar.api.web.GwtExtension; -import org.sonar.server.configuration.ServerSettings; +import org.sonar.server.platform.ServerSettings; import java.io.File; import java.io.IOException; diff --git a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java index 59598488060..e4747e37a89 100644 --- a/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java +++ b/sonar-server/src/main/java/org/sonar/server/ui/JRubyFacade.java @@ -37,7 +37,7 @@ import org.sonar.core.i18n.RuleI18nManager; import org.sonar.jpa.dialect.Dialect; import org.sonar.jpa.session.DatabaseConnector; import org.sonar.markdown.Markdown; -import org.sonar.server.configuration.ServerSettings; +import org.sonar.server.platform.ServerSettings; import org.sonar.server.configuration.Backup; import org.sonar.server.configuration.ProfilesManager; import org.sonar.server.filters.Filter; diff --git a/sonar-server/src/main/resources/sonar-war.properties b/sonar-server/src/main/resources/sonar-war.properties index f0787339955..de2350c3887 100644 --- a/sonar-server/src/main/resources/sonar-war.properties +++ b/sonar-server/src/main/resources/sonar-war.properties @@ -1,9 +1,5 @@ # This file is used only when deploying the webapp to an application server. # It is ignored when using the standalone mode shipped by default. -# The path to the Sonar home directory must be defined : -# - by setting the environment variable SONAR_HOME in the app server -# - or by setting the system property sonar.home in the app server -# - or by uncommenting and setting the following property before deploying the webapp - -#sonar.home=
\ No newline at end of file +# Path to Sonar installation directory, if the environment variable/system property SONAR_HOME is not defined +#SONAR_HOME=
\ No newline at end of file diff --git a/sonar-server/src/main/webapp/WEB-INF/web.xml b/sonar-server/src/main/webapp/WEB-INF/web.xml index cdc3a9d3ca8..23172c43dbe 100644 --- a/sonar-server/src/main/webapp/WEB-INF/web.xml +++ b/sonar-server/src/main/webapp/WEB-INF/web.xml @@ -26,13 +26,6 @@ <param-value>1</param-value> </context-param> - <env-entry> - <description>JNDI logback context</description> - <env-entry-name>logback/context-name</env-entry-name> - <env-entry-type>java.lang.String</env-entry-type> - <env-entry-value>Sonar</env-entry-value> - </env-entry> - <filter> <filter-name>DatabaseSessionFilter</filter-name> <filter-class>org.sonar.server.ui.DatabaseSessionFilter</filter-class> @@ -126,8 +119,5 @@ <listener> <listener-class>org.jruby.rack.rails.RailsServletContextListener</listener-class> </listener> - <listener> - <listener-class>ch.qos.logback.classic.selector.servlet.ContextDetachingSCL</listener-class> - </listener> </web-app> diff --git a/sonar-server/src/test/java/org/sonar/server/database/JndiDatabaseConnectorTest.java b/sonar-server/src/test/java/org/sonar/server/database/JndiDatabaseConnectorTest.java index aa2e30497a7..898c4605697 100644 --- a/sonar-server/src/test/java/org/sonar/server/database/JndiDatabaseConnectorTest.java +++ b/sonar-server/src/test/java/org/sonar/server/database/JndiDatabaseConnectorTest.java @@ -19,15 +19,12 @@ */ package org.sonar.server.database; -import org.apache.commons.configuration.Configuration; -import org.apache.commons.configuration.PropertiesConfiguration; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.sonar.api.config.Settings; import org.sonar.api.database.DatabaseProperties; import org.sonar.jpa.entity.SchemaMigration; -import org.sonar.server.configuration.ServerSettings; import javax.naming.Context; import javax.persistence.EntityManagerFactory; diff --git a/sonar-server/src/test/java/org/sonar/server/platform/ServerSettingsTest.java b/sonar-server/src/test/java/org/sonar/server/platform/ServerSettingsTest.java new file mode 100644 index 00000000000..148853d73d6 --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/platform/ServerSettingsTest.java @@ -0,0 +1,79 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.server.platform; + +import org.apache.commons.configuration.BaseConfiguration; +import org.junit.Test; +import org.sonar.api.config.PropertyDefinitions; +import org.sonar.jpa.test.AbstractDbUnitTestCase; + +import java.io.File; +import java.net.URISyntaxException; + +import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertThat; + +public class ServerSettingsTest extends AbstractDbUnitTestCase { + + private static File home = getHome(); + + @Test + public void shouldLoadPropertiesFile() throws URISyntaxException { + ServerSettings settings = new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), home); + + assertThat(settings.getString("hello"), is("world")); + } + + @Test + public void systemPropertiesShouldOverridePropertiesFile() throws URISyntaxException { + System.setProperty("ServerSettingsTestEnv", "in_env"); + ServerSettings settings = new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), home); + + assertThat(settings.getString("ServerSettingsTestEnv"), is("in_env")); + } + + @Test(expected = IllegalStateException.class) + public void shouldFailIfPropertiesFileNotFound() { + File sonarHome = new File("unknown/path"); + new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), sonarHome); + } + + @Test + public void shouldLoadPersistedGeneralSettings() throws URISyntaxException { + setupData("db/shared"); + + ServerSettings settings = new ServerSettings(new PropertyDefinitions(), new BaseConfiguration(), new File("."), home); + settings.setSessionFactory(getSessionFactory()); + settings.load(home); + + assertThat(settings.getString("general_only"), is("is_general")); + assertThat(settings.getString("general_and_project"), is("is_general")); + assertThat(settings.getString("project_only"), nullValue()); + } + + private static File getHome() { + try { + return new File(ServerSettingsTest.class.getResource("/org/sonar/server/platform/ServerSettingsTest/").toURI()); + } catch (URISyntaxException e) { + throw new IllegalStateException(e); + } + } +} diff --git a/sonar-server/src/test/java/org/sonar/server/platform/SonarHomeTest.java b/sonar-server/src/test/java/org/sonar/server/platform/SonarHomeTest.java new file mode 100644 index 00000000000..69a652e09af --- /dev/null +++ b/sonar-server/src/test/java/org/sonar/server/platform/SonarHomeTest.java @@ -0,0 +1,29 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.server.platform; + +import org.junit.Test; + +public class SonarHomeTest { + @Test + public void iDontKnowHowToSimplyTestThisClass() { + + } +} diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerSettingsTest/conf/sonar.properties b/sonar-server/src/test/resources/org/sonar/server/platform/ServerSettingsTest/conf/sonar.properties new file mode 100644 index 00000000000..016382d7fe1 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/platform/ServerSettingsTest/conf/sonar.properties @@ -0,0 +1,2 @@ +hello: world +ServerSettingsTestEnv: in_file
\ No newline at end of file diff --git a/sonar-server/src/test/resources/org/sonar/server/platform/ServerSettingsTest/db/shared.xml b/sonar-server/src/test/resources/org/sonar/server/platform/ServerSettingsTest/db/shared.xml new file mode 100644 index 00000000000..f3a1b304598 --- /dev/null +++ b/sonar-server/src/test/resources/org/sonar/server/platform/ServerSettingsTest/db/shared.xml @@ -0,0 +1,20 @@ +<dataset> + + <!-- project --> + <projects long_name="[null]" id="3333" scope="PRJ" qualifier="TRK" kee="mygroup:anotherproject" name="[null]" + root_id="[null]" + description="[null]" + enabled="true" language="java" copy_resource_id="[null]"/> + + <!-- general properties --> + <properties prop_key="general_only" resource_id="[null]" user_id="[null]" text_value="is_general"/> + <properties prop_key="general_and_project" resource_id="[null]" user_id="[null]" text_value="is_general"/> + + <!-- project properties: do not load --> + <properties prop_key="general_and_project" resource_id="3333" user_id="[null]" text_value="is_project"/> + <properties prop_key="project_only" resource_id="3333" user_id="[null]" text_value="is_project"/> + + <!-- user properties : do not load --> + <properties prop_key="user" resource_id="[null]" user_id="110" text_value="is_user"/> + +</dataset>
\ No newline at end of file |