#  Licensed to the Apache Software Foundation (ASF) under one or more
#  contributor license agreements.  See the NOTICE file distributed with
#  this work for additional information regarding copyright ownership.
#  The ASF 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.

@defaultMessage Spawns threads with vague names; use a custom thread factory (Lucene's NamedThreadFactory, Solr's SolrNamedThreadFactory) and name threads so that you can tell (by its name) which executor it is associated with
java.util.concurrent.Executors#newFixedThreadPool(int)
java.util.concurrent.Executors#newSingleThreadExecutor()
java.util.concurrent.Executors#newCachedThreadPool()
java.util.concurrent.Executors#newSingleThreadScheduledExecutor()
java.util.concurrent.Executors#newScheduledThreadPool(int)
java.util.concurrent.Executors#defaultThreadFactory()
java.util.concurrent.Executors#privilegedThreadFactory()

@defaultMessage Spawns threads without MDC logging context; use ExecutorUtil.newMDCAwareFixedThreadPool instead
java.util.concurrent.Executors#newFixedThreadPool(int,java.util.concurrent.ThreadFactory)

@defaultMessage Spawns threads without MDC logging context; use ExecutorUtil.newMDCAwareSingleThreadExecutor instead
java.util.concurrent.Executors#newSingleThreadExecutor(java.util.concurrent.ThreadFactory)

@defaultMessage Spawns threads without MDC logging context; use ExecutorUtil.newMDCAwareCachedThreadPool instead
java.util.concurrent.Executors#newCachedThreadPool(java.util.concurrent.ThreadFactory)

@defaultMessage Use ExecutorUtil.MDCAwareThreadPoolExecutor instead of ThreadPoolExecutor
java.util.concurrent.ThreadPoolExecutor#<init>(**)

@defaultMessage Must specify an explicit executor to run async tasks so that we have named threads
java.util.concurrent.CompletableFuture#runAsync(java.lang.Runnable)
java.util.concurrent.CompletableFuture#supplyAsync(java.util.function.Supplier)

@defaultMessage Properties files should be read/written with Reader/Writer, using UTF-8 charset. This allows reading older files with unicode escapes, too.
java.util.Properties#load(java.io.InputStream)
java.util.Properties#save(java.io.OutputStream,java.lang.String)
java.util.Properties#store(java.io.OutputStream,java.lang.String)

@defaultMessage The context classloader should never be used for resource lookups, unless there is a 3rd party library that needs it. Always pass a classloader down as method parameters.
java.lang.Thread#getContextClassLoader()
java.lang.Thread#setContextClassLoader(java.lang.ClassLoader)

java.lang.Character#codePointBefore(char[],int) @ Implicit start offset is error-prone when the char[] is a buffer and the first chars are random chars
java.lang.Character#codePointAt(char[],int) @ Implicit end offset is error-prone when the char[] is a buffer and the last chars are random chars

java.io.File#delete() @ use Files.delete for real exception, IOUtils.deleteFilesIgnoringExceptions if you dont care

java.util.Collections#shuffle(java.util.List) @ Use shuffle(List, Random) instead so that it can be reproduced

java.util.Locale#forLanguageTag(java.lang.String) @ use new Locale.Builder().setLanguageTag(...).build() which has error handling
java.util.Locale#toString() @ use Locale#toLanguageTag() for a standardized BCP47 locale name


@defaultMessage Direct calls to force the JVM to quit are forbidden in server code.
java.lang.System#exit(int)
java.lang.Runtime#exit(int)

@defaultMessage Constructors for wrapper classes of Java primitives should be avoided in favor of the public static methods available or autoboxing
java.lang.Integer#<init>(**)
java.lang.Byte#<init>(**)
java.lang.Short#<init>(**)
java.lang.Long#<init>(**)
java.lang.Boolean#<init>(**)
java.lang.Character#<init>(**)
java.lang.Float#<init>(**)
java.lang.Double#<init>(**)

@defaultMessage Java deserialization is unsafe when the data is untrusted. The java developer is powerless: no checks or casts help, exploitation can happen in places such as clinit or finalize!
java.io.ObjectInputStream
java.io.ObjectOutputStream

@defaultMessage Don't set a dictionary on a Deflater using a method that takes an offset or ByteBuffer (JDK-8252739)
java.util.zip.Deflater#setDictionary(byte[],int,int)
java.util.zip.Deflater#setDictionary(java.nio.ByteBuffer)

@defaultMessage Use RTimer/TimeOut/System.nanoTime for time comparisons, and `new Date()` output/debugging/stats of timestamps. If for some miscellaneous reason, you absolutely need to use this, use a SuppressForbidden.
java.lang.System#currentTimeMillis()

@defaultMessage Use slf4j classes instead
java.util.logging.**

@defaultMessage Use List.sort(Comparator) instead of Collections.sort(List, Comparator) please.
java.util.Collections#sort(java.util.List, java.util.Comparator)

@defaultMessage Use URI.toURL() to construct an instance of URL.
java.net.URL#<init>(**)

@defaultMessage Use Locale.Builder instead.
java.util.Locale#<init>(**)