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() {