]> source.dussan.org Git - sonarqube.git/commitdiff
Fix non-deterministic NPE in BaseLogger due to incorrect static field initialization
authorSimon Brandhof <simon.brandhof@sonarsource.com>
Fri, 20 Feb 2015 09:54:53 +0000 (10:54 +0100)
committerSimon Brandhof <simon.brandhof@sonarsource.com>
Fri, 20 Feb 2015 09:54:59 +0000 (10:54 +0100)
sonar-plugin-api/src/main/java/org/sonar/api/utils/log/BaseLogger.java
sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogInterceptor.java
sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogInterceptors.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogTester.java
sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogInterceptorsTest.java [new file with mode: 0644]
sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogTesterTest.java

index f4c7e3c95f9a82dae61255794e55d1ae80156f5d..fec49378945102eb0415a4a8b6b5ffb66a292ee4 100644 (file)
@@ -24,127 +24,127 @@ import javax.annotation.Nullable;
 abstract class BaseLogger implements Logger {
   @Override
   public void trace(String msg) {
-    LogInterceptor.instance().log(msg);
+    LogInterceptors.get().log(msg);
     doTrace(msg);
   }
 
   @Override
   public void trace(String pattern, @Nullable Object arg) {
-    LogInterceptor.instance().log(pattern, arg);
+    LogInterceptors.get().log(pattern, arg);
     doTrace(pattern, arg);
   }
 
   @Override
   public void trace(String msg, @Nullable Object arg1, @Nullable Object arg2) {
-    LogInterceptor.instance().log(msg, arg1, arg2);
+    LogInterceptors.get().log(msg, arg1, arg2);
     doTrace(msg, arg1, arg2);
   }
 
   @Override
   public void trace(String msg, Object... args) {
-    LogInterceptor.instance().log(msg, args);
+    LogInterceptors.get().log(msg, args);
     doTrace(msg, args);
   }
 
   @Override
   public void debug(String msg) {
-    LogInterceptor.instance().log(msg);
+    LogInterceptors.get().log(msg);
     doDebug(msg);
   }
 
   @Override
   public void debug(String pattern, @Nullable Object arg) {
-    LogInterceptor.instance().log(pattern, arg);
+    LogInterceptors.get().log(pattern, arg);
     doDebug(pattern, arg);
   }
 
   @Override
   public void debug(String msg, @Nullable Object arg1, @Nullable Object arg2) {
-    LogInterceptor.instance().log(msg, arg1, arg2);
+    LogInterceptors.get().log(msg, arg1, arg2);
     doDebug(msg, arg1, arg2);
   }
 
   @Override
   public void debug(String msg, Object... args) {
-    LogInterceptor.instance().log(msg, args);
+    LogInterceptors.get().log(msg, args);
     doDebug(msg, args);
   }
 
   @Override
   public void info(String msg) {
-    LogInterceptor.instance().log(msg);
+    LogInterceptors.get().log(msg);
     doInfo(msg);
   }
 
   @Override
   public void info(String msg, @Nullable Object arg) {
-    LogInterceptor.instance().log(msg, arg);
+    LogInterceptors.get().log(msg, arg);
     doInfo(msg, arg);
   }
 
   @Override
   public void info(String msg, @Nullable Object arg1, @Nullable Object arg2) {
-    LogInterceptor.instance().log(msg, arg1, arg2);
+    LogInterceptors.get().log(msg, arg1, arg2);
     doInfo(msg, arg1, arg2);
   }
 
   @Override
   public void info(String msg, Object... args) {
-    LogInterceptor.instance().log(msg, args);
+    LogInterceptors.get().log(msg, args);
     doInfo(msg, args);
   }
 
   @Override
   public void warn(String msg) {
-    LogInterceptor.instance().log(msg);
+    LogInterceptors.get().log(msg);
     doWarn(msg);
   }
 
   @Override
   public void warn(String msg, @Nullable Object arg) {
-    LogInterceptor.instance().log(msg, arg);
+    LogInterceptors.get().log(msg, arg);
     doWarn(msg, arg);
   }
 
   @Override
   public void warn(String msg, @Nullable Object arg1, @Nullable Object arg2) {
-    LogInterceptor.instance().log(msg, arg1, arg2);
+    LogInterceptors.get().log(msg, arg1, arg2);
     doWarn(msg, arg1, arg2);
   }
 
   @Override
   public void warn(String msg, Object... args) {
-    LogInterceptor.instance().log(msg, args);
+    LogInterceptors.get().log(msg, args);
     doWarn(msg, args);
   }
 
   @Override
   public void error(String msg) {
-    LogInterceptor.instance().log(msg);
+    LogInterceptors.get().log(msg);
     doError(msg);
   }
 
   @Override
   public void error(String msg, @Nullable Object arg) {
-    LogInterceptor.instance().log(msg, arg);
+    LogInterceptors.get().log(msg, arg);
     doError(msg, arg);
   }
 
   @Override
   public void error(String msg, @Nullable Object arg1, @Nullable Object arg2) {
-    LogInterceptor.instance().log(msg, arg1, arg2);
+    LogInterceptors.get().log(msg, arg1, arg2);
     doError(msg, arg1, arg2);
   }
 
   @Override
   public void error(String msg, Object... args) {
-    LogInterceptor.instance().log(msg, args);
+    LogInterceptors.get().log(msg, args);
     doError(msg, args);
   }
 
   @Override
   public void error(String msg, Throwable thrown) {
-    LogInterceptor.instance().log(msg, thrown);
+    LogInterceptors.get().log(msg, thrown);
     doError(msg, thrown);
   }
 
index ff844379d9edfab711a511be8fe4a46a5966a678..49701a01df3c35af924dac97e3b1bd454741a2b8 100644 (file)
  */
 package org.sonar.api.utils.log;
 
-import com.google.common.base.Preconditions;
-
 abstract class LogInterceptor {
 
-  private static LogInterceptor instance = NullInterceptor.NULL_INSTANCE;
-
   abstract void log(String msg);
 
   abstract void log(String msg, Object arg);
@@ -34,13 +30,4 @@ abstract class LogInterceptor {
   abstract void log(String msg, Object... args);
 
   abstract void log(String msg, Throwable thrown);
-
-  static LogInterceptor instance() {
-    return instance;
-  }
-
-  static void setInstance(LogInterceptor li) {
-    Preconditions.checkArgument(li != null);
-    instance = li;
-  }
 }
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogInterceptors.java b/sonar-plugin-api/src/main/java/org/sonar/api/utils/log/LogInterceptors.java
new file mode 100644 (file)
index 0000000..a17ab97
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.api.utils.log;
+
+import com.google.common.base.Preconditions;
+
+class LogInterceptors {
+
+  private static LogInterceptor instance = NullInterceptor.NULL_INSTANCE;
+
+  private LogInterceptors() {
+  }
+
+  static LogInterceptor get() {
+    return instance;
+  }
+
+  static void set(LogInterceptor li) {
+    Preconditions.checkArgument(li != null);
+    instance = li;
+  }
+}
index ac63133bfc2224a2b11f6cc7928bb425906a8766..630492277cedf64f09de24a79820f7e435d896e2 100644 (file)
@@ -65,13 +65,13 @@ public class LogTester extends ExternalResource {
     initialLevel = Loggers.getFactory().getLevel();
 
     // this shared instance breaks compatibility with parallel execution of tests
-    LogInterceptor.setInstance(new ListInterceptor());
+    LogInterceptors.set(new ListInterceptor());
     setLevel(LoggerLevel.TRACE);
   }
 
   @Override
   protected void after() {
-    LogInterceptor.setInstance(NullInterceptor.NULL_INSTANCE);
+    LogInterceptors.set(NullInterceptor.NULL_INSTANCE);
     setLevel(initialLevel);
   }
 
@@ -92,11 +92,11 @@ public class LogTester extends ExternalResource {
    * Logs in chronological order (item at index 0 is the oldest one)
    */
   public List<String> logs() {
-    return ((ListInterceptor) LogInterceptor.instance()).logs();
+    return ((ListInterceptor) LogInterceptors.get()).logs();
   }
 
   public LogTester clear() {
-    ((ListInterceptor) LogInterceptor.instance()).clear();
+    ((ListInterceptor) LogInterceptors.get()).clear();
     return this;
   }
 }
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogInterceptorsTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/utils/log/LogInterceptorsTest.java
new file mode 100644 (file)
index 0000000..7a5adbe
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 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.api.utils.log;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class LogInterceptorsTest {
+
+  @Test
+  public void default_is_null_interceptor() throws Exception {
+    // production-ready
+    assertThat(LogInterceptors.get()).isInstanceOf(NullInterceptor.class);
+  }
+
+  @Test(expected = IllegalArgumentException.class)
+  public void instance_cant_be_null() throws Exception {
+    LogInterceptors.set(null);
+  }
+}
index 8b10230815b17d8943ae02cf700d59cf7087ae6f..9fd01343f34a444477f6b493c627d0beb219cd50 100644 (file)
@@ -59,6 +59,6 @@ public class LogTesterTest {
     assertThat(sut.logs()).isEmpty();
 
     sut.after();
-    assertThat(LogInterceptor.instance()).isSameAs(NullInterceptor.NULL_INSTANCE);
+    assertThat(LogInterceptors.get()).isSameAs(NullInterceptor.NULL_INSTANCE);
   }
 }