Small cleanups to conventions projects. (#4839)
This commit is contained in:
parent
231ab6bf59
commit
458ebc5e55
|
@ -1,5 +1,4 @@
|
||||||
plugins {
|
plugins {
|
||||||
`java-gradle-plugin`
|
|
||||||
`kotlin-dsl`
|
`kotlin-dsl`
|
||||||
// When updating, update below in dependencies too
|
// When updating, update below in dependencies too
|
||||||
id("com.diffplug.spotless") version "5.16.0"
|
id("com.diffplug.spotless") version "5.16.0"
|
||||||
|
@ -29,8 +28,7 @@ dependencies {
|
||||||
implementation(gradleApi())
|
implementation(gradleApi())
|
||||||
implementation(localGroovy())
|
implementation(localGroovy())
|
||||||
|
|
||||||
implementation("io.opentelemetry.instrumentation.muzzle-generation:io.opentelemetry.instrumentation.muzzle-generation.gradle.plugin")
|
implementation("io.opentelemetry.instrumentation:gradle-plugins:1.9.1-alpha")
|
||||||
implementation("io.opentelemetry.instrumentation.muzzle-check:io.opentelemetry.instrumentation.muzzle-check.gradle.plugin")
|
|
||||||
|
|
||||||
implementation("org.eclipse.aether:aether-connector-basic:1.1.0")
|
implementation("org.eclipse.aether:aether-connector-basic:1.1.0")
|
||||||
implementation("org.eclipse.aether:aether-transport-http:1.1.0")
|
implementation("org.eclipse.aether:aether-transport-http:1.1.0")
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
includeBuild("../gradle-plugins") {
|
includeBuild("../gradle-plugins") {
|
||||||
dependencySubstitution {
|
dependencySubstitution {
|
||||||
substitute(module("io.opentelemetry.instrumentation.muzzle-generation:io.opentelemetry.instrumentation.muzzle-generation.gradle.plugin")).using(project(":"))
|
substitute(module("io.opentelemetry.instrumentation:gradle-plugins")).using(project(":"))
|
||||||
substitute(module("io.opentelemetry.instrumentation.muzzle-check:io.opentelemetry.instrumentation.muzzle-check.gradle.plugin")).using(project(":"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
pluginManagement {
|
pluginManagement {
|
||||||
plugins {
|
plugins {
|
||||||
id("com.gradle.plugin-publish") version "0.15.0"
|
id("com.gradle.plugin-publish") version "0.15.0"
|
||||||
id("org.jetbrains.kotlin.jvm") version "1.5.10"
|
|
||||||
id("io.github.gradle-nexus.publish-plugin") version "1.1.0"
|
id("io.github.gradle-nexus.publish-plugin") version "1.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,117 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright The OpenTelemetry Authors
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
package io.opentelemetry.javaagent.muzzle.matcher;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Entry point for the muzzle gradle plugin.
|
|
||||||
*
|
|
||||||
* <p>In order to understand this class and its weirdness, one has to remember that there are three
|
|
||||||
* different independent class loaders at play here.
|
|
||||||
*
|
|
||||||
* <p>First, Gradle class loader that has loaded the muzzle-check plugin that calls this class. This
|
|
||||||
* one has a lot of Gradle specific stuff and we don't want it to be available during muzzle checks.
|
|
||||||
*
|
|
||||||
* <p>Second, there is agent or instrumentation class loader, which contains all
|
|
||||||
* InstrumentationModules and helper classes. The actual muzzle check process happens "inside" that
|
|
||||||
* class loader. This means that we load {@code
|
|
||||||
* io.opentelemetry.javaagent.tooling.muzzle.ClassLoaderMatcher} from it and we allow it to find all
|
|
||||||
* InstrumentationModules from agent class loader.
|
|
||||||
*
|
|
||||||
* <p>Finally, there is user class loader. It contains the specific version of the instrumented
|
|
||||||
* library that we want to muzzle-check: "does this version provide all the expected hooks and
|
|
||||||
* classes and methods that our instrumentations expect".
|
|
||||||
*/
|
|
||||||
|
|
||||||
// TODO the next line is not true anymore. Switch from System.err to Gradle logger.
|
|
||||||
// Runs in special classloader so tedious to provide access to the Gradle logger.
|
|
||||||
@SuppressWarnings("SystemOut")
|
|
||||||
public final class MuzzleGradlePluginUtil {
|
|
||||||
private static final String INDENT = " ";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verifies that all instrumentations present in the {@code agentClassLoader} can be safely
|
|
||||||
* applied to the passed {@code userClassLoader}.
|
|
||||||
*
|
|
||||||
* <p>This method throws whenever one of the following step fails (and {@code assertPass} is
|
|
||||||
* true):
|
|
||||||
*
|
|
||||||
* <ol>
|
|
||||||
* <li>{@code userClassLoader} is not matched by the {@code
|
|
||||||
* InstrumentationModule#classLoaderMatcher()} method
|
|
||||||
* <li>{@code ReferenceMatcher} of any instrumentation module finds any mismatch
|
|
||||||
* <li>any helper class defined in {@code InstrumentationModule#getMuzzleHelperClassNames()}
|
|
||||||
* fails to be injected into {@code userClassLoader}
|
|
||||||
* </ol>
|
|
||||||
*
|
|
||||||
* <p>When {@code assertPass = false} this method behaves in an opposite way: failure in any of
|
|
||||||
* the first two steps is expected (helper classes are not injected at all).
|
|
||||||
*
|
|
||||||
* <p>This method is repeatedly called by the {@code :muzzle} gradle task - each tested dependency
|
|
||||||
* version passes different {@code userClassLoader}.
|
|
||||||
*/
|
|
||||||
public static void assertInstrumentationMuzzled(
|
|
||||||
ClassLoader agentClassLoader, ClassLoader userClassLoader, boolean assertPass)
|
|
||||||
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException,
|
|
||||||
IllegalAccessException {
|
|
||||||
|
|
||||||
Class<?> matcherClass =
|
|
||||||
agentClassLoader.loadClass("io.opentelemetry.javaagent.tooling.muzzle.ClassLoaderMatcher");
|
|
||||||
|
|
||||||
// We cannot reference Mismatch class directly here, because we are loaded from a differen
|
|
||||||
// classloader.
|
|
||||||
Map<String, List<Object>> allMismatches =
|
|
||||||
(Map<String, List<Object>>)
|
|
||||||
matcherClass
|
|
||||||
.getMethod("matchesAll", ClassLoader.class, boolean.class)
|
|
||||||
.invoke(null, userClassLoader, assertPass);
|
|
||||||
|
|
||||||
allMismatches.forEach(
|
|
||||||
(moduleName, mismatches) -> {
|
|
||||||
boolean passed = mismatches.isEmpty();
|
|
||||||
|
|
||||||
if (passed && !assertPass) {
|
|
||||||
System.err.println("MUZZLE PASSED " + moduleName + " BUT FAILURE WAS EXPECTED");
|
|
||||||
throw new IllegalStateException(
|
|
||||||
"Instrumentation unexpectedly passed Muzzle validation");
|
|
||||||
} else if (!passed && assertPass) {
|
|
||||||
System.err.println("FAILED MUZZLE VALIDATION: " + moduleName + " mismatches:");
|
|
||||||
|
|
||||||
for (Object mismatch : mismatches) {
|
|
||||||
System.err.println("-- " + mismatch);
|
|
||||||
}
|
|
||||||
throw new IllegalStateException("Instrumentation failed Muzzle validation");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
int validatedModulesCount = allMismatches.size();
|
|
||||||
if (validatedModulesCount == 0) {
|
|
||||||
String errorMessage = "Did not found any InstrumentationModule to validate!";
|
|
||||||
System.err.println(errorMessage);
|
|
||||||
throw new IllegalStateException(errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prints all references from all instrumentation modules present in the passed {@code
|
|
||||||
* instrumentationClassLoader}.
|
|
||||||
*
|
|
||||||
* <p>Called by the {@code printMuzzleReferences} gradle task.
|
|
||||||
*/
|
|
||||||
public static void printMuzzleReferences(ClassLoader instrumentationClassLoader)
|
|
||||||
throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException,
|
|
||||||
IllegalAccessException {
|
|
||||||
Class<?> matcherClass =
|
|
||||||
instrumentationClassLoader.loadClass(
|
|
||||||
"io.opentelemetry.javaagent.tooling.muzzle.ReferencesPrinter");
|
|
||||||
matcherClass.getMethod("printMuzzleReferences").invoke(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private MuzzleGradlePluginUtil() {}
|
|
||||||
}
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* Copyright The OpenTelemetry Authors
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package io.opentelemetry.javaagent.muzzle.matcher
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point for the muzzle gradle plugin.
|
||||||
|
*
|
||||||
|
* <p>In order to understand this class and its weirdness, one has to remember that there are three
|
||||||
|
* different independent class loaders at play here.
|
||||||
|
*
|
||||||
|
* <p>First, Gradle class loader that has loaded the muzzle-check plugin that calls this class. This
|
||||||
|
* one has a lot of Gradle specific stuff and we don't want it to be available during muzzle checks.
|
||||||
|
*
|
||||||
|
* <p>Second, there is agent or instrumentation class loader, which contains all
|
||||||
|
* InstrumentationModules and helper classes. The actual muzzle check process happens "inside" that
|
||||||
|
* class loader. This means that we load {@code
|
||||||
|
* io.opentelemetry.javaagent.tooling.muzzle.ClassLoaderMatcher} from it and we allow it to find all
|
||||||
|
* InstrumentationModules from agent class loader.
|
||||||
|
*
|
||||||
|
* <p>Finally, there is user class loader. It contains the specific version of the instrumented
|
||||||
|
* library that we want to muzzle-check: "does this version provide all the expected hooks and
|
||||||
|
* classes and methods that our instrumentations expect".
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO the next line is not true anymore. Switch from System.err to Gradle logger.
|
||||||
|
// Runs in special classloader so tedious to provide access to the Gradle logger.
|
||||||
|
class MuzzleGradlePluginUtil {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
/**
|
||||||
|
* Verifies that all instrumentations present in the {@code agentClassLoader} can be safely
|
||||||
|
* applied to the passed {@code userClassLoader}.
|
||||||
|
*
|
||||||
|
* <p>This method throws whenever one of the following step fails (and {@code assertPass} is
|
||||||
|
* true):
|
||||||
|
*
|
||||||
|
* <ol>
|
||||||
|
* <li>{@code userClassLoader} is not matched by the {@code
|
||||||
|
* InstrumentationModule#classLoaderMatcher()} method
|
||||||
|
* <li>{@code ReferenceMatcher} of any instrumentation module finds any mismatch
|
||||||
|
* <li>any helper class defined in {@code InstrumentationModule#getMuzzleHelperClassNames()}
|
||||||
|
* fails to be injected into {@code userClassLoader}
|
||||||
|
* </ol>
|
||||||
|
*
|
||||||
|
* <p>When {@code assertPass = false} this method behaves in an opposite way: failure in any of
|
||||||
|
* the first two steps is expected (helper classes are not injected at all).
|
||||||
|
*
|
||||||
|
* <p>This method is repeatedly called by the {@code :muzzle} gradle task - each tested dependency
|
||||||
|
* version passes different {@code userClassLoader}.
|
||||||
|
*/
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
fun assertInstrumentationMuzzled(agentClassLoader: ClassLoader, userClassLoader: ClassLoader, assertPass: Boolean) {
|
||||||
|
val matcherClass = agentClassLoader.loadClass("io.opentelemetry.javaagent.tooling.muzzle.ClassLoaderMatcher")
|
||||||
|
|
||||||
|
// We cannot reference Mismatch class directly here, because we are loaded from a differen
|
||||||
|
// classloader.
|
||||||
|
|
||||||
|
// We cannot reference Mismatch class directly here, because we are loaded from a differen
|
||||||
|
// classloader.
|
||||||
|
val allMismatches = matcherClass
|
||||||
|
.getMethod("matchesAll", ClassLoader::class.java, Boolean::class.javaPrimitiveType)
|
||||||
|
.invoke(null, userClassLoader, assertPass)
|
||||||
|
as Map<String, List<Any>>
|
||||||
|
|
||||||
|
allMismatches.forEach { moduleName, mismatches ->
|
||||||
|
val passed = mismatches.isEmpty()
|
||||||
|
if (passed && !assertPass) {
|
||||||
|
System.err.println("MUZZLE PASSED $moduleName BUT FAILURE WAS EXPECTED")
|
||||||
|
throw IllegalStateException("Instrumentation unexpectedly passed Muzzle validation")
|
||||||
|
} else if (!passed && assertPass) {
|
||||||
|
System.err.println("FAILED MUZZLE VALIDATION: $moduleName mismatches:")
|
||||||
|
for (mismatch in mismatches) {
|
||||||
|
System.err.println("-- $mismatch")
|
||||||
|
}
|
||||||
|
throw IllegalStateException("Instrumentation failed Muzzle validation")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val validatedModulesCount = allMismatches.size
|
||||||
|
if (validatedModulesCount == 0) {
|
||||||
|
val errorMessage = "Did not found any InstrumentationModule to validate!"
|
||||||
|
System.err.println(errorMessage)
|
||||||
|
throw IllegalStateException(errorMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prints all references from all instrumentation modules present in the passed {@code
|
||||||
|
* instrumentationClassLoader}.
|
||||||
|
*
|
||||||
|
* <p>Called by the {@code printMuzzleReferences} gradle task.
|
||||||
|
*/
|
||||||
|
fun printMuzzleReferences(instrumentationClassLoader: ClassLoader) {
|
||||||
|
val matcherClass = instrumentationClassLoader.loadClass(
|
||||||
|
"io.opentelemetry.javaagent.tooling.muzzle.ReferencesPrinter")
|
||||||
|
matcherClass.getMethod("printMuzzleReferences").invoke(null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,7 +17,8 @@ org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m \
|
||||||
--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
|
--add-opens=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
|
||||||
--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
|
--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED
|
||||||
|
|
||||||
org.gradle.warning.mode=fail
|
# Currently causes failure when importing project in IntelliJ
|
||||||
|
# org.gradle.warning.mode=fail
|
||||||
|
|
||||||
# To allow caching more tasks in buildSrc project
|
# To allow caching more tasks in buildSrc project
|
||||||
# This property is not mentioned in Gradle documentation
|
# This property is not mentioned in Gradle documentation
|
||||||
|
|
Loading…
Reference in New Issue