Merge "Merge branch 'stable-3.6'"
diff --git a/Documentation/config-gerrit.txt b/Documentation/config-gerrit.txt
index 2b20cab..d1f2786 100644
--- a/Documentation/config-gerrit.txt
+++ b/Documentation/config-gerrit.txt
@@ -5256,13 +5256,13 @@
 end of the request the performance events are handed over to the
 link:dev-plugins.html#performance-logger[PerformanceLogger] plugins.
 This means if performance logging is enabled, the memory footprint of
-requests is slightly increased.
+requests can be markedly increased.
+In one recorded case the impact was an overall heap increase of 40%
+(using the metrics-reporter-graphite plugin), in other instances the
+heap increase wasn't nearly as dramatic and the impact is most likely
+dependent on which plugin is used.
 +
-This setting has no effect if no
-link:dev-plugins.html#performance-logger[PerformanceLogger] plugins are
-installed, because then performance logging is always disabled.
-+
-By default, true.
+By default, false.
 
 [[tracing.exportPerformanceMetrics]]tracing.exportPerformanceMetrics::
 +
diff --git a/Documentation/dev-plugins.txt b/Documentation/dev-plugins.txt
index ca5480a..ca72f8b 100644
--- a/Documentation/dev-plugins.txt
+++ b/Documentation/dev-plugins.txt
@@ -208,6 +208,28 @@
 The canonical web URL may be injected into any .jar plugin regardless of
 whether or not the plugin provides an HTTP servlet.
 
+[[plugin_resources]]
+=== Plugin resources
+
+Plugins are able to access their own resources without having to go through
+the implementation details on how they are packaged or deployed to Gerrit.
+
+The following example shows a MyClass in a plugin that is able to access the
+last modified time of the "myresource" loaded.
+
+[source,java]
+----
+public class MyClass {
+
+  @Inject
+  public MyClass(Plugin plugin) {
+    long myresourceTime = plugin.getContentScanner().getEntry("myresource").getTime();
+  }
+
+  [...]
+}
+----
+
 [[reload_method]]
 === Reload Method
 
diff --git a/java/com/google/gerrit/server/experiments/ExperimentFeaturesConstants.java b/java/com/google/gerrit/server/experiments/ExperimentFeaturesConstants.java
index f7b6788..9deea8a 100644
--- a/java/com/google/gerrit/server/experiments/ExperimentFeaturesConstants.java
+++ b/java/com/google/gerrit/server/experiments/ExperimentFeaturesConstants.java
@@ -22,6 +22,8 @@
   /** Features that are known experiments and can be referenced in the code. */
   public static String UI_FEATURE_PATCHSET_COMMENTS = "UiFeature__patchset_comments";
 
+  public static String UI_FEATURE_SUBMIT_REQUIREMENTS_UI = "UiFeature__submit_requirements_ui";
+
   public static String GERRIT_BACKEND_REQUEST_FEATURE_REMOVE_REVISION_ETAG =
       "GerritBackendRequestFeature__remove_revision_etag";
 
@@ -43,5 +45,5 @@
 
   /** Features, enabled by default in the current release. */
   public static final ImmutableSet<String> DEFAULT_ENABLED_FEATURES =
-      ImmutableSet.of(UI_FEATURE_PATCHSET_COMMENTS);
+      ImmutableSet.of(UI_FEATURE_PATCHSET_COMMENTS, UI_FEATURE_SUBMIT_REQUIREMENTS_UI);
 }
diff --git a/java/com/google/gerrit/server/logging/LoggingContext.java b/java/com/google/gerrit/server/logging/LoggingContext.java
index 3907da5..eac96a6 100644
--- a/java/com/google/gerrit/server/logging/LoggingContext.java
+++ b/java/com/google/gerrit/server/logging/LoggingContext.java
@@ -90,8 +90,9 @@
     return tags.get() == null
         && forceLogging.get() == null
         && performanceLogging.get() == null
+        && (performanceLogRecords.get() == null || performanceLogRecords.get().isEmtpy())
         && aclLogging.get() == null
-        && aclLogRecords.get() == null;
+        && (aclLogRecords.get() == null || aclLogRecords.get().isEmpty());
   }
 
   public void clear() {
diff --git a/java/com/google/gerrit/server/logging/MutableAclLogRecords.java b/java/com/google/gerrit/server/logging/MutableAclLogRecords.java
index baa9b1f..a692d2b 100644
--- a/java/com/google/gerrit/server/logging/MutableAclLogRecords.java
+++ b/java/com/google/gerrit/server/logging/MutableAclLogRecords.java
@@ -45,6 +45,10 @@
     return ImmutableList.copyOf(aclLogRecords);
   }
 
+  public boolean isEmpty() {
+    return aclLogRecords.isEmpty();
+  }
+
   @Override
   public String toString() {
     return MoreObjects.toStringHelper(this).add("aclLogRecords", aclLogRecords).toString();
diff --git a/java/com/google/gerrit/server/logging/MutablePerformanceLogRecords.java b/java/com/google/gerrit/server/logging/MutablePerformanceLogRecords.java
index 4ee70d7..2965719 100644
--- a/java/com/google/gerrit/server/logging/MutablePerformanceLogRecords.java
+++ b/java/com/google/gerrit/server/logging/MutablePerformanceLogRecords.java
@@ -46,6 +46,10 @@
     return ImmutableList.copyOf(performanceLogRecords);
   }
 
+  public boolean isEmtpy() {
+    return performanceLogRecords.isEmpty();
+  }
+
   @Override
   public String toString() {
     return MoreObjects.toStringHelper(this)
diff --git a/java/com/google/gerrit/server/logging/PerformanceLogContext.java b/java/com/google/gerrit/server/logging/PerformanceLogContext.java
index 65e033b15..90e716f 100644
--- a/java/com/google/gerrit/server/logging/PerformanceLogContext.java
+++ b/java/com/google/gerrit/server/logging/PerformanceLogContext.java
@@ -56,7 +56,7 @@
     // Do not create performance log entries if performance logging is disabled or if no
     // PerformanceLogger is registered.
     boolean enablePerformanceLogging =
-        gerritConfig.getBoolean("tracing", "performanceLogging", true);
+        gerritConfig.getBoolean("tracing", "performanceLogging", false);
     LoggingContext.getInstance()
         .performanceLogging(
             enablePerformanceLogging && !Iterables.isEmpty(performanceLoggers.entries()));
diff --git a/java/com/google/gerrit/server/plugins/ServerPluginInfoModule.java b/java/com/google/gerrit/server/plugins/ServerPluginInfoModule.java
index 639b278..60dff84 100644
--- a/java/com/google/gerrit/server/plugins/ServerPluginInfoModule.java
+++ b/java/com/google/gerrit/server/plugins/ServerPluginInfoModule.java
@@ -49,6 +49,7 @@
     bind(String.class)
         .annotatedWith(PluginCanonicalWebUrl.class)
         .toInstance(plugin.getPluginCanonicalWebUrl());
+    bind(Plugin.class).toInstance(plugin);
 
     install(
         new LifecycleModule() {
diff --git a/java/com/google/gerrit/testing/BUILD b/java/com/google/gerrit/testing/BUILD
index 798a2d4..fea00e9 100644
--- a/java/com/google/gerrit/testing/BUILD
+++ b/java/com/google/gerrit/testing/BUILD
@@ -48,6 +48,7 @@
         "//lib/flogger:api",
         "//lib/guice",
         "//lib/guice:guice-servlet",
+        "//lib/log:impl-log4j",
         "//lib/truth",
     ],
 )
diff --git a/javatests/com/google/gerrit/acceptance/rest/TraceIT.java b/javatests/com/google/gerrit/acceptance/rest/TraceIT.java
index 7e40b2b..64e3762 100644
--- a/javatests/com/google/gerrit/acceptance/rest/TraceIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/TraceIT.java
@@ -374,6 +374,7 @@
   }
 
   @Test
+  @GerritConfig(name = "tracing.performanceLogging", value = "true")
   public void performanceLoggingForRestCall() throws Exception {
     PerformanceLogger testPerformanceLogger = mock(PerformanceLogger.class);
     try (Registration registration =
@@ -385,6 +386,7 @@
   }
 
   @Test
+  @GerritConfig(name = "tracing.performanceLogging", value = "true")
   public void performanceLoggingForPush() throws Exception {
     PerformanceLogger testPerformanceLogger = mock(PerformanceLogger.class);
     try (Registration registration =
@@ -397,8 +399,7 @@
   }
 
   @Test
-  @GerritConfig(name = "tracing.performanceLogging", value = "false")
-  public void noPerformanceLoggingIfDisabled() throws Exception {
+  public void noPerformanceLoggingByDefault() throws Exception {
     PerformanceLogger testPerformanceLogger = mock(PerformanceLogger.class);
     try (Registration registration =
         extensionRegistry.newRegistration().add(testPerformanceLogger)) {
diff --git a/javatests/com/google/gerrit/acceptance/server/experiments/ExperimentFeaturesIT.java b/javatests/com/google/gerrit/acceptance/server/experiments/ExperimentFeaturesIT.java
index 09e6dfe..b2a0ded 100644
--- a/javatests/com/google/gerrit/acceptance/server/experiments/ExperimentFeaturesIT.java
+++ b/javatests/com/google/gerrit/acceptance/server/experiments/ExperimentFeaturesIT.java
@@ -65,7 +65,7 @@
       values = {"enabledFeature"})
   @GerritConfig(
       name = "experiments.disabled",
-      values = {"UiFeature__patchset_comments"})
+      values = {"UiFeature__patchset_comments", "UiFeature__submit_requirements_ui"})
   public void configOverride_defaultFeatureDisabled() {
     assertThat(experimentFeatures.isFeatureEnabled("enabledFeature")).isTrue();
     assertThat(
diff --git a/javatests/com/google/gerrit/acceptance/ssh/SshTraceIT.java b/javatests/com/google/gerrit/acceptance/ssh/SshTraceIT.java
index ce5cff7..84c3936 100644
--- a/javatests/com/google/gerrit/acceptance/ssh/SshTraceIT.java
+++ b/javatests/com/google/gerrit/acceptance/ssh/SshTraceIT.java
@@ -23,6 +23,7 @@
 import com.google.gerrit.acceptance.ExtensionRegistry;
 import com.google.gerrit.acceptance.ExtensionRegistry.Registration;
 import com.google.gerrit.acceptance.UseSsh;
+import com.google.gerrit.acceptance.config.GerritConfig;
 import com.google.gerrit.server.logging.LoggingContext;
 import com.google.gerrit.server.logging.Metadata;
 import com.google.gerrit.server.logging.PerformanceLogger;
@@ -92,6 +93,7 @@
   }
 
   @Test
+  @GerritConfig(name = "tracing.performanceLogging", value = "true")
   public void performanceLoggingForSshCall() throws Exception {
     TestPerformanceLogger testPerformanceLogger = new TestPerformanceLogger();
     try (Registration registration =
diff --git a/javatests/com/google/gerrit/httpd/raw/IndexServletTest.java b/javatests/com/google/gerrit/httpd/raw/IndexServletTest.java
index 634231f..f65e823 100644
--- a/javatests/com/google/gerrit/httpd/raw/IndexServletTest.java
+++ b/javatests/com/google/gerrit/httpd/raw/IndexServletTest.java
@@ -105,7 +105,7 @@
     assertThat(output)
         .contains(
             "window.ENABLED_EXPERIMENTS = JSON.parse('\\x5b\\x22"
-                + String.join("\\x22,", expectedEnabled)
+                + String.join("\\x22,\\x22", expectedEnabled)
                 + "\\x22\\x5d');</script>");
   }
 }
diff --git a/javatests/com/google/gerrit/server/logging/LoggingContextAwareExecutorServiceTest.java b/javatests/com/google/gerrit/server/logging/LoggingContextAwareExecutorServiceTest.java
index 8d019f3..1f0da16 100644
--- a/javatests/com/google/gerrit/server/logging/LoggingContextAwareExecutorServiceTest.java
+++ b/javatests/com/google/gerrit/server/logging/LoggingContextAwareExecutorServiceTest.java
@@ -56,6 +56,9 @@
           }
         };
     performanceLoggerRegistrationHandle = performanceLoggers.add("gerrit", testPerformanceLogger);
+
+    // Enable performance logging
+    config.setBoolean("tracing", null, "performanceLogging", true);
   }
 
   @After
diff --git a/javatests/com/google/gerrit/server/logging/PerformanceLogContextTest.java b/javatests/com/google/gerrit/server/logging/PerformanceLogContextTest.java
index e60d6b4..b1cd8fb 100644
--- a/javatests/com/google/gerrit/server/logging/PerformanceLogContextTest.java
+++ b/javatests/com/google/gerrit/server/logging/PerformanceLogContextTest.java
@@ -56,6 +56,9 @@
 
     testPerformanceLogger = new TestPerformanceLogger();
     performanceLoggerRegistrationHandle = performanceLoggers.add("gerrit", testPerformanceLogger);
+
+    // Enable performance logging
+    config.setBoolean("tracing", null, "performanceLogging", true);
   }
 
   @After