diff --git a/pom.xml b/pom.xml
index e838bb299dd..fd6c4de3470 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1423,33 +1423,6 @@
false
jsr166e/**
-
- org/elasticsearch/common/logging/log4j/ConsoleAppender*
- org/elasticsearch/common/http/client/HttpDownloadHelper*
- org/elasticsearch/common/cli/Terminal*
- org/elasticsearch/plugins/PluginManager$SysOut.class
- org/elasticsearch/common/http/client/HttpDownloadHelper.class
- org/elasticsearch/bootstrap/Bootstrap.class
- org/elasticsearch/Version.class
- org/elasticsearch/common/lucene/search/Queries$QueryWrapperFilterFactory.class
-
-
- org/elasticsearch/common/util/MathUtils.class
- org/elasticsearch/common/math/UnboxedMathUtils.class
- org/elasticsearch/cluster/routing/OperationRouting.class
-
-
- org/elasticsearch/common/lucene/search/XFilteredQuery.class
-
-
- org/elasticsearch/common/io/Channels.class
-
-
- org/elasticsearch/common/lucene/Lucene$LenientParser.class
-
-
- org/elasticsearch/common/util/concurrent/FutureUtils.class
-
@@ -1462,6 +1435,7 @@
dev-tools/forbidden/all-signatures.txt
${forbidden.signatures}
+ **.SuppressForbidden
compile
diff --git a/src/main/java/org/elasticsearch/Version.java b/src/main/java/org/elasticsearch/Version.java
index fdd3f5fe3b3..5d59d28448a 100644
--- a/src/main/java/org/elasticsearch/Version.java
+++ b/src/main/java/org/elasticsearch/Version.java
@@ -21,6 +21,7 @@ package org.elasticsearch;
import org.elasticsearch.cluster.metadata.IndexMetaData;
import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.inject.AbstractModule;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
@@ -580,6 +581,7 @@ public class Version {
return sb.toString();
}
+ @SuppressForbidden(reason = "System.out.*")
public static void main(String[] args) {
System.out.println("Version: " + Version.CURRENT + ", Build: " + Build.CURRENT.hashShort() + "/" + Build.CURRENT.timestamp() + ", JVM: " + JvmInfo.jvmInfo().version());
}
diff --git a/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java b/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
index 664940cd0c5..81f73b5c80b 100644
--- a/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
+++ b/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java
@@ -22,6 +22,7 @@ package org.elasticsearch.bootstrap;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.Version;
import org.elasticsearch.common.PidFile;
+import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.inject.CreationException;
import org.elasticsearch.common.inject.spi.Message;
@@ -90,6 +91,7 @@ public class Bootstrap {
}
}
+ @SuppressForbidden(reason = "Exception#printStackTrace()")
private static void setupLogging(Tuple tuple) {
try {
tuple.v1().getClassLoader().loadClass("org.apache.log4j.Logger");
@@ -99,7 +101,7 @@ public class Bootstrap {
} catch (NoClassDefFoundError e) {
// no log4j
} catch (Exception e) {
- System.err.println("Failed to configure logging...");
+ sysError("Failed to configure logging...", false);
e.printStackTrace();
}
}
@@ -154,8 +156,7 @@ public class Bootstrap {
PidFile.create(Paths.get(pidFile), true);
} catch (Exception e) {
String errorMessage = buildErrorMessage("pid", e);
- System.err.println(errorMessage);
- System.err.flush();
+ sysError(errorMessage, true);
System.exit(3);
}
}
@@ -171,8 +172,7 @@ public class Bootstrap {
setupLogging(tuple);
} catch (Exception e) {
String errorMessage = buildErrorMessage("Setup", e);
- System.err.println(errorMessage);
- System.err.flush();
+ sysError(errorMessage, true);
System.exit(3);
}
@@ -191,7 +191,7 @@ public class Bootstrap {
try {
if (!foreground) {
Loggers.disableConsoleLogging();
- System.out.close();
+ closeSystOut();
}
// fail if using broken version
@@ -203,7 +203,7 @@ public class Bootstrap {
bootstrap.start();
if (!foreground) {
- System.err.close();
+ closeSysError();
}
keepAliveLatch = new CountDownLatch(1);
@@ -234,8 +234,7 @@ public class Bootstrap {
}
String errorMessage = buildErrorMessage(stage, e);
if (foreground) {
- System.err.println(errorMessage);
- System.err.flush();
+ sysError(errorMessage, true);
Loggers.disableConsoleLogging();
}
logger.error("Exception", e);
@@ -244,6 +243,24 @@ public class Bootstrap {
}
}
+ @SuppressForbidden(reason = "System#out")
+ private static void closeSystOut() {
+ System.out.close();
+ }
+
+ @SuppressForbidden(reason = "System#err")
+ private static void closeSysError() {
+ System.err.close();
+ }
+
+ @SuppressForbidden(reason = "System#err")
+ private static void sysError(String line, boolean flush) {
+ System.err.println(line);
+ if (flush) {
+ System.err.flush();
+ }
+ }
+
private static String buildErrorMessage(String stage, Throwable e) {
StringBuilder errorMessage = new StringBuilder("{").append(Version.CURRENT).append("}: ");
errorMessage.append(stage).append(" Failed ...\n");
diff --git a/src/main/java/org/elasticsearch/cluster/routing/OperationRouting.java b/src/main/java/org/elasticsearch/cluster/routing/OperationRouting.java
index d9080cd2873..4c4cba24507 100644
--- a/src/main/java/org/elasticsearch/cluster/routing/OperationRouting.java
+++ b/src/main/java/org/elasticsearch/cluster/routing/OperationRouting.java
@@ -28,6 +28,7 @@ import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.cluster.routing.allocation.decider.AwarenessAllocationDecider;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.component.AbstractComponent;
import org.elasticsearch.common.inject.Inject;
import org.elasticsearch.common.math.MathUtils;
@@ -247,6 +248,7 @@ public class OperationRouting extends AbstractComponent {
return indexShard;
}
+ @SuppressForbidden(reason = "Math#abs is trappy")
private int shardId(ClusterState clusterState, String index, String type, String id, @Nullable String routing) {
final IndexMetaData indexMetaData = indexMetaData(clusterState, index);
final Version createdVersion = indexMetaData.getCreationVersion();
diff --git a/src/main/java/org/elasticsearch/common/SuppressForbidden.java b/src/main/java/org/elasticsearch/common/SuppressForbidden.java
new file mode 100644
index 00000000000..3dffbdc2d1f
--- /dev/null
+++ b/src/main/java/org/elasticsearch/common/SuppressForbidden.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to Elasticsearch under one or more contributor
+ * license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright
+ * ownership. Elasticsearch licenses this file to you under
+ * the Apache License, Version 2.0 (the "License"); you may
+ * not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.elasticsearch.common;
+
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+/**
+ * Annotation to suppress forbidden-apis errors inside a whole class, a method, or a field.
+ */
+@Retention(RetentionPolicy.CLASS)
+@Target({ ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE })
+public @interface SuppressForbidden {
+ String reason();
+}
diff --git a/src/main/java/org/elasticsearch/common/cli/Terminal.java b/src/main/java/org/elasticsearch/common/cli/Terminal.java
index 14e936d90e3..583eb9cc3a9 100644
--- a/src/main/java/org/elasticsearch/common/cli/Terminal.java
+++ b/src/main/java/org/elasticsearch/common/cli/Terminal.java
@@ -20,6 +20,7 @@
package org.elasticsearch.common.cli;
import org.apache.commons.cli.CommandLine;
+import org.elasticsearch.common.SuppressForbidden;
import java.io.*;
import java.util.Locale;
@@ -27,6 +28,7 @@ import java.util.Locale;
/**
*
*/
+@SuppressForbidden(reason = "System#out")
public abstract class Terminal {
public static final String DEBUG_SYSTEM_PROPERTY = "es.cli.debug";
@@ -163,6 +165,7 @@ public abstract class Terminal {
}
}
+ @SuppressForbidden(reason = "System#out")
private static class SystemTerminal extends Terminal {
private final PrintWriter printWriter = new PrintWriter(System.out);
diff --git a/src/main/java/org/elasticsearch/common/http/client/HttpDownloadHelper.java b/src/main/java/org/elasticsearch/common/http/client/HttpDownloadHelper.java
index f044877a981..c39ae1f90f0 100644
--- a/src/main/java/org/elasticsearch/common/http/client/HttpDownloadHelper.java
+++ b/src/main/java/org/elasticsearch/common/http/client/HttpDownloadHelper.java
@@ -23,6 +23,7 @@ import org.apache.lucene.util.IOUtils;
import org.elasticsearch.ElasticsearchTimeoutException;
import org.elasticsearch.Version;
import org.elasticsearch.common.Nullable;
+import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.unit.TimeValue;
import java.io.*;
@@ -134,6 +135,7 @@ public class HttpDownloadHelper {
/**
* verbose progress system prints to some output stream
*/
+ @SuppressForbidden(reason = "System#out")
public static class VerboseProgress implements DownloadProgress {
private int dots = 0;
// CheckStyle:VisibilityModifier OFF - bc
diff --git a/src/main/java/org/elasticsearch/common/io/Channels.java b/src/main/java/org/elasticsearch/common/io/Channels.java
index b76250b014c..a192825e9f8 100644
--- a/src/main/java/org/elasticsearch/common/io/Channels.java
+++ b/src/main/java/org/elasticsearch/common/io/Channels.java
@@ -19,6 +19,7 @@
package org.elasticsearch.common.io;
+import org.elasticsearch.common.SuppressForbidden;
import org.jboss.netty.buffer.ChannelBuffer;
import java.io.EOFException;
@@ -28,6 +29,7 @@ import java.nio.channels.FileChannel;
import java.nio.channels.GatheringByteChannel;
import java.nio.channels.WritableByteChannel;
+@SuppressForbidden(reason = "Channel#read")
public final class Channels {
private Channels() {
diff --git a/src/main/java/org/elasticsearch/common/logging/log4j/ConsoleAppender.java b/src/main/java/org/elasticsearch/common/logging/log4j/ConsoleAppender.java
index f23a138a194..940749bfa8b 100644
--- a/src/main/java/org/elasticsearch/common/logging/log4j/ConsoleAppender.java
+++ b/src/main/java/org/elasticsearch/common/logging/log4j/ConsoleAppender.java
@@ -22,6 +22,7 @@ package org.elasticsearch.common.logging.log4j;
import org.apache.log4j.Layout;
import org.apache.log4j.WriterAppender;
import org.apache.log4j.helpers.LogLog;
+import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.logging.Loggers;
import java.io.IOException;
@@ -138,6 +139,7 @@ public class ConsoleAppender extends WriterAppender {
* Prepares the appender for use.
*/
@Override
+ @SuppressForbidden(reason = "System#out")
public void activateOptions() {
if (follow) {
if (target.equals(SYSTEM_ERR)) {
@@ -172,6 +174,7 @@ public class ConsoleAppender extends WriterAppender {
* An implementation of OutputStream that redirects to the
* current System.err.
*/
+ @SuppressForbidden(reason = "System#err")
private static class SystemErrStream extends OutputStream {
public SystemErrStream() {
}
@@ -194,6 +197,7 @@ public class ConsoleAppender extends WriterAppender {
}
@Override
+
public void write(final byte[] b, final int off, final int len)
throws IOException {
if (!Loggers.consoleLoggingEnabled()) {
@@ -215,6 +219,7 @@ public class ConsoleAppender extends WriterAppender {
* An implementation of OutputStream that redirects to the
* current System.out.
*/
+ @SuppressForbidden(reason = "System#err")
private static class SystemOutStream extends OutputStream {
public SystemOutStream() {
}
diff --git a/src/main/java/org/elasticsearch/common/lucene/Lucene.java b/src/main/java/org/elasticsearch/common/lucene/Lucene.java
index 7a4063b3323..1307be75cc8 100644
--- a/src/main/java/org/elasticsearch/common/lucene/Lucene.java
+++ b/src/main/java/org/elasticsearch/common/lucene/Lucene.java
@@ -54,6 +54,7 @@ import org.elasticsearch.ElasticsearchIllegalStateException;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
+import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.logging.ESLogger;
@@ -659,6 +660,7 @@ public class Lucene {
return LenientParser.parse(toParse, defaultValue);
}
+ @SuppressForbidden(reason = "Version#parseLeniently() used in a central place")
private static final class LenientParser {
public static Version parse(String toParse, Version defaultValue) {
if (Strings.hasLength(toParse)) {
diff --git a/src/main/java/org/elasticsearch/common/lucene/search/Queries.java b/src/main/java/org/elasticsearch/common/lucene/search/Queries.java
index 10b9797451a..fecabf246be 100644
--- a/src/main/java/org/elasticsearch/common/lucene/search/Queries.java
+++ b/src/main/java/org/elasticsearch/common/lucene/search/Queries.java
@@ -21,6 +21,7 @@ package org.elasticsearch.common.lucene.search;
import org.apache.lucene.search.*;
import org.elasticsearch.common.Nullable;
+import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.index.query.QueryParseContext;
import org.elasticsearch.index.search.child.CustomQueryWrappingFilter;
@@ -148,22 +149,12 @@ public class Queries {
* If a filter has an anti per segment execution / caching nature then @{@link CustomQueryWrappingFilter} is returned
* otherwise the standard {@link org.apache.lucene.search.QueryWrapperFilter} is returned.
*/
+ @SuppressForbidden(reason = "QueryWrapperFilter cachability")
public static Filter wrap(Query query, QueryParseContext context) {
- return FACTORY.wrap(query, context);
- }
-
- private static final QueryWrapperFilterFactory FACTORY = new QueryWrapperFilterFactory();
- // NOTE: This is a separate class since we added QueryWrapperFilter as a forbidden API
- // that way we can exclude only the inner class without excluding the entire Queries class
- // and potentially miss a forbidden API usage!
- private static final class QueryWrapperFilterFactory {
-
- public Filter wrap(Query query, QueryParseContext context) {
- if (context.requireCustomQueryWrappingFilter() || CustomQueryWrappingFilter.shouldUseCustomQueryWrappingFilter(query)) {
- return new CustomQueryWrappingFilter(query);
- } else {
- return new QueryWrapperFilter(query);
- }
+ if (context.requireCustomQueryWrappingFilter() || CustomQueryWrappingFilter.shouldUseCustomQueryWrappingFilter(query)) {
+ return new CustomQueryWrappingFilter(query);
+ } else {
+ return new QueryWrapperFilter(query);
}
}
}
diff --git a/src/main/java/org/elasticsearch/common/math/UnboxedMathUtils.java b/src/main/java/org/elasticsearch/common/math/UnboxedMathUtils.java
index 606b4be3862..6c8e0b45f70 100644
--- a/src/main/java/org/elasticsearch/common/math/UnboxedMathUtils.java
+++ b/src/main/java/org/elasticsearch/common/math/UnboxedMathUtils.java
@@ -19,6 +19,8 @@
package org.elasticsearch.common.math;
+import org.elasticsearch.common.SuppressForbidden;
+
import java.util.concurrent.ThreadLocalRandom;
/**
@@ -456,18 +458,22 @@ public class UnboxedMathUtils {
return ThreadLocalRandom.current().nextLong(l);
}
+ @SuppressForbidden(reason = "Math#abs is trappy")
public static int abs(Integer a) {
return Math.abs(a);
}
+ @SuppressForbidden(reason = "Math#abs is trappy")
public static long abs(Long a) {
return Math.abs(a);
}
+ @SuppressForbidden(reason = "Math#abs is trappy")
public static float abs(Float a) {
return Math.abs(a);
}
+ @SuppressForbidden(reason = "Math#abs is trappy")
public static double abs(Double a) {
return Math.abs(a);
}
diff --git a/src/main/java/org/elasticsearch/common/util/concurrent/FutureUtils.java b/src/main/java/org/elasticsearch/common/util/concurrent/FutureUtils.java
index f7abe4aedba..55bb61be723 100644
--- a/src/main/java/org/elasticsearch/common/util/concurrent/FutureUtils.java
+++ b/src/main/java/org/elasticsearch/common/util/concurrent/FutureUtils.java
@@ -19,7 +19,7 @@
package org.elasticsearch.common.util.concurrent;
-import org.elasticsearch.ElasticsearchIllegalArgumentException;
+import org.elasticsearch.common.SuppressForbidden;
import java.util.concurrent.Future;
@@ -27,6 +27,7 @@ import java.util.concurrent.Future;
*/
public class FutureUtils {
+ @SuppressForbidden(reason = "Future#cancel()")
public static boolean cancel(Future> toCancel) {
if (toCancel != null) {
return toCancel.cancel(false); // this method is a forbidden API since it interrupts threads
diff --git a/src/main/java/org/elasticsearch/plugins/PluginManager.java b/src/main/java/org/elasticsearch/plugins/PluginManager.java
index eb9e59547b8..fbd89b9f27a 100644
--- a/src/main/java/org/elasticsearch/plugins/PluginManager.java
+++ b/src/main/java/org/elasticsearch/plugins/PluginManager.java
@@ -21,26 +21,22 @@ package org.elasticsearch.plugins;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
import org.apache.lucene.util.IOUtils;
import org.elasticsearch.*;
+import org.elasticsearch.common.SuppressForbidden;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.http.client.HttpDownloadHelper;
import org.elasticsearch.common.io.FileSystemUtils;
-import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.env.Environment;
-import org.elasticsearch.index.Index;
import org.elasticsearch.node.internal.InternalSettingsPreparer;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
-import java.io.File;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.MalformedURLException;
@@ -48,7 +44,6 @@ import java.net.URL;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.PosixFileAttributeView;
-import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermission;
import java.util.*;
@@ -582,6 +577,7 @@ public class PluginManager {
if (outputMode != OutputMode.SILENT) SysOut.println(line);
}
+ @SuppressForbidden(reason = "System#out")
static class SysOut {
public static void newline() {