Merge "Avoid passing @Singleton to args4j"
diff --git a/java/com/google/gerrit/httpd/restapi/ParameterParser.java b/java/com/google/gerrit/httpd/restapi/ParameterParser.java
index 326cab8..3ab409e 100644
--- a/java/com/google/gerrit/httpd/restapi/ParameterParser.java
+++ b/java/com/google/gerrit/httpd/restapi/ParameterParser.java
@@ -43,6 +43,7 @@
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.inject.Inject;
+import com.google.inject.Singleton;
import java.io.IOException;
import java.io.StringWriter;
import java.util.HashSet;
@@ -153,6 +154,12 @@
this.parserFactory = pf;
}
+ /**
+ * Parses query parameters ({@code in}) into annotated option fields of {@code param}.
+ *
+ * @return true if parsing was successful. Requesting help is considered failure and returns
+ * false.
+ */
<T> boolean parse(
T param,
DynamicOptions pluginOptions,
@@ -160,6 +167,10 @@
HttpServletRequest req,
HttpServletResponse res)
throws IOException {
+ if (param.getClass().getAnnotation(Singleton.class) != null) {
+ // Command-line parsing mutates the object, so we can't have options on @Singleton.
+ return true;
+ }
CmdLineParser clp = parserFactory.create(param);
pluginOptions.setBean(param);
pluginOptions.startLifecycleListeners();
diff --git a/javatests/com/google/gerrit/acceptance/rest/binding/PluginProvidedRootRestApiBindingsIT.java b/javatests/com/google/gerrit/acceptance/rest/binding/PluginProvidedRootRestApiBindingsIT.java
index b447534..16dc294 100644
--- a/javatests/com/google/gerrit/acceptance/rest/binding/PluginProvidedRootRestApiBindingsIT.java
+++ b/javatests/com/google/gerrit/acceptance/rest/binding/PluginProvidedRootRestApiBindingsIT.java
@@ -16,6 +16,7 @@
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
+import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.acceptance.AbstractDaemonTest;
@@ -48,6 +49,7 @@
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import org.junit.Test;
+import org.kohsuke.args4j.Option;
/**
* Tests for checking plugin-provided REST API bindings directly under {@code /}.
@@ -192,8 +194,15 @@
@Singleton
static class TestGet implements RestReadView<TestPluginResource> {
+
+ @Option(name = "--crash")
+ String crash;
+
@Override
public Response<String> apply(TestPluginResource resource) throws Exception {
+ if (!Strings.nullToEmpty(crash).isEmpty()) {
+ throw new IllegalStateException();
+ }
return Response.ok("test");
}
}
@@ -204,4 +213,13 @@
RestApiCallHelper.execute(adminRestSession, TEST_CALLS.asList());
}
}
+
+ @Test
+ public void testOptionOnSingletonIsIgnored() throws Exception {
+ try (AutoCloseable ignored = installPlugin(PLUGIN_NAME, null, MyPluginHttpModule.class, null)) {
+ RestApiCallHelper.execute(
+ adminRestSession,
+ RestCall.get("/plugins/" + PLUGIN_NAME + "/test-collection/1/detail?crash=xyz"));
+ }
+ }
}