lucene/gradle/validation/forbidden-apis.gradle
Mike Drob b335034615
Require Thread Names in Solr (#2264)
When we are creating a new thread we should give it a descriptive name and enforce this via ForbiddenAPIs. This doesn't apply to Runnable or Callable objects that we pass to an executor, since those should be getting named by the executor itself.

We don't require this in tests because the tests should be more self contained and there is less benefit in descriptive names. If somebody is already profiling a test, then they likely have the context to understand what the unnamed threads are doing, whereas a thread dump from a running Solr instance should have good thread names for everything. This is especially helpful when doing profiling, otherwise we end up with a bunch of Thread-# that are hard to tell apart and search on.
2021-01-28 15:04:15 -06:00

139 lines
4.5 KiB
Groovy

/*
* 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.
*/
// This configures application of forbidden API rules
// via https://github.com/policeman-tools/forbidden-apis
def resources = scriptResources(buildscript)
// Only apply forbidden-apis to java projects.
allprojects { prj ->
plugins.withId("java", {
prj.apply plugin: 'de.thetaphi.forbiddenapis'
// This helper method appends signature files based on a set of true
// dependencies from a given configuration.
def dynamicSignatures = { configuration, suffix ->
def resolvedMods = configuration.resolvedConfiguration.resolvedArtifacts
.collect { a -> a.moduleVersion.id }
def deps = resolvedMods
.collect { id -> [
"${id.group}.${id.name}.all.txt",
"${id.group}.${id.name}.${suffix}.txt",
]}
.flatten()
.sort()
deps += ["defaults.all.txt", "defaults.${suffix}.txt"]
deps.each { sig ->
def signaturesFile = file("${resources}/${sig}")
if (signaturesFile.exists()) {
logger.info("Signature file applied: ${sig}")
signaturesFiles += files(signaturesFile)
} else {
logger.debug("Signature file omitted (does not exist): ${sig}")
}
}
// commons-io is special: forbiddenapis has a versioned bundledSignature.
bundledSignatures += resolvedMods
.findAll { id -> id.group == 'commons-io' && id.name == 'commons-io' }
.collect { id -> "${id.name}-unsafe-${id.version}" as String }
}
// Configure defaults for sourceSets.main
forbiddenApisMain {
bundledSignatures += [
'jdk-unsafe',
'jdk-deprecated',
'jdk-non-portable',
'jdk-reflection',
'jdk-system-out',
]
suppressAnnotations += [
"**.SuppressForbidden"
]
}
// Configure defaults for sourceSets.test
forbiddenApisTest {
bundledSignatures += [
'jdk-unsafe',
'jdk-deprecated',
'jdk-non-portable',
'jdk-reflection',
]
signaturesFiles = files(
file("${resources}/defaults.tests.txt")
)
suppressAnnotations += [
"**.SuppressForbidden"
]
}
// Disable sysout signatures for these projects.
if (prj.path in [
":lucene:demo",
":lucene:benchmark",
":lucene:test-framework",
":solr:solr-ref-guide",
":solr:test-framework"
]) {
forbiddenApisMain.bundledSignatures -= [
'jdk-system-out'
]
}
// Configure lucene-specific rules.
if (prj.path.startsWith(":lucene")) {
forbiddenApisMain {
doFirst dynamicSignatures.curry(configurations.compileClasspath, "lucene")
}
forbiddenApisTest {
doFirst dynamicSignatures.curry(configurations.testCompileClasspath, "lucene")
}
}
// Configure solr-specific rules.
if (prj.path.startsWith(":solr")) {
forbiddenApisMain {
doFirst dynamicSignatures.curry(configurations.compileClasspath, "solr")
signaturesFiles += files(file("${resources}/java.solr.txt"))
}
forbiddenApisTest {
doFirst dynamicSignatures.curry(configurations.testCompileClasspath, "solr")
}
}
// We rely on resolved configurations to compute the relevant set of rule
// files for forbiddenApis. Since we don't want to resolve these configurations until
// the task is executed, we can't really use them as task inputs properly. This is a
// chicken-and-egg problem.
//
// This is the simplest workaround possible: just point at all the rule files and indicate
// them as inputs. This way if a rule is modified, checks will be reapplied.
configure([forbiddenApisMain, forbiddenApisTest]) { task ->
task.inputs.dir(file(resources))
}
})
}