diff --git a/conventions/src/main/kotlin/otel.scala-conventions.gradle.kts b/conventions/src/main/kotlin/otel.scala-conventions.gradle.kts index e52d1e00d9..b273b7510f 100644 --- a/conventions/src/main/kotlin/otel.scala-conventions.gradle.kts +++ b/conventions/src/main/kotlin/otel.scala-conventions.gradle.kts @@ -5,7 +5,7 @@ plugins { } dependencies { - testImplementation("org.scala-lang:scala-library") + testCompileOnly("org.scala-lang:scala-library:2.11.12") } tasks { diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 676c0c894b..e2e9401b31 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -100,7 +100,6 @@ val DEPENDENCIES = listOf( "org.codehaus.mojo:animal-sniffer-annotations:1.22", "org.junit-pioneer:junit-pioneer:1.9.0", "org.objenesis:objenesis:3.3", - "org.scala-lang:scala-library:2.11.12", // Note that this is only referenced as "org.springframework.boot" in build files, not the artifact name. "org.springframework.boot:spring-boot-dependencies:2.7.5", "javax.validation:validation-api:2.0.1.Final", diff --git a/instrumentation/executors/javaagent/build.gradle.kts b/instrumentation/executors/javaagent/build.gradle.kts index 07beaabb27..87a7ea4090 100644 --- a/instrumentation/executors/javaagent/build.gradle.kts +++ b/instrumentation/executors/javaagent/build.gradle.kts @@ -1,5 +1,6 @@ plugins { id("otel.javaagent-instrumentation") + id("otel.scala-conventions") } muzzle { @@ -12,6 +13,8 @@ dependencies { bootstrap(project(":instrumentation:executors:bootstrap")) testImplementation(project(":instrumentation:executors:testing")) + + testImplementation("org.scala-lang:scala-library:2.11.12") } testing { diff --git a/instrumentation/scala-fork-join-2.8/javaagent/src/test/scala/io/opentelemetry/javaagent/instrumentation/scalaexecutors/ScalaInstrumentationTest.scala b/instrumentation/executors/javaagent/src/test/scala/io/opentelemetry/javaagent/instrumentation/scalaexecutors/ScalaInstrumentationTest.scala similarity index 100% rename from instrumentation/scala-fork-join-2.8/javaagent/src/test/scala/io/opentelemetry/javaagent/instrumentation/scalaexecutors/ScalaInstrumentationTest.scala rename to instrumentation/executors/javaagent/src/test/scala/io/opentelemetry/javaagent/instrumentation/scalaexecutors/ScalaInstrumentationTest.scala diff --git a/instrumentation/jdbc/javaagent/build.gradle.kts b/instrumentation/jdbc/javaagent/build.gradle.kts index 0f92effb53..8285c44bff 100644 --- a/instrumentation/jdbc/javaagent/build.gradle.kts +++ b/instrumentation/jdbc/javaagent/build.gradle.kts @@ -1,5 +1,6 @@ plugins { id("otel.javaagent-instrumentation") + id("otel.scala-conventions") } muzzle { @@ -34,6 +35,11 @@ dependencies { latestDepTestLibrary("org.apache.derby:derby:10.14.+") testImplementation(project(":instrumentation:jdbc:testing")) + + // these dependencies are for SlickTest + testImplementation("org.scala-lang:scala-library:2.11.12") + testImplementation("com.typesafe.slick:slick_2.11:3.2.0") + testImplementation("com.h2database:h2:1.4.197") } sourceSets { @@ -46,6 +52,22 @@ sourceSets { } } -tasks.withType().configureEach { - jvmArgs("-Dotel.instrumentation.jdbc-datasource.enabled=true") +tasks { + val testSlick by registering(Test::class) { + filter { + includeTestsMatching("SlickTest") + } + include("**/SlickTest.*") + } + + test { + filter { + excludeTestsMatching("SlickTest") + } + jvmArgs("-Dotel.instrumentation.jdbc-datasource.enabled=true") + } + + check { + dependsOn(testSlick) + } } diff --git a/instrumentation/scala-fork-join-2.8/javaagent/src/slickTest/scala/io/opentelemetry/javaagent/instrumentation/scalaexecutors/SlickTest.scala b/instrumentation/jdbc/javaagent/src/test/scala/io/opentelemetry/javaagent/instrumentation/scalaexecutors/SlickTest.scala similarity index 100% rename from instrumentation/scala-fork-join-2.8/javaagent/src/slickTest/scala/io/opentelemetry/javaagent/instrumentation/scalaexecutors/SlickTest.scala rename to instrumentation/jdbc/javaagent/src/test/scala/io/opentelemetry/javaagent/instrumentation/scalaexecutors/SlickTest.scala diff --git a/instrumentation/scala-fork-join-2.8/javaagent/build.gradle.kts b/instrumentation/scala-fork-join-2.8/javaagent/build.gradle.kts index 299ce908b8..e0184ca8e5 100644 --- a/instrumentation/scala-fork-join-2.8/javaagent/build.gradle.kts +++ b/instrumentation/scala-fork-join-2.8/javaagent/build.gradle.kts @@ -1,7 +1,6 @@ plugins { id("otel.javaagent-instrumentation") id("otel.scala-conventions") - id("org.unbroken-dome.test-sets") } muzzle { @@ -13,10 +12,6 @@ muzzle { } } -testSets { - create("slickTest") -} - dependencies { bootstrap(project(":instrumentation:executors:bootstrap")) @@ -24,21 +19,5 @@ dependencies { latestDepTestLibrary("org.scala-lang:scala-library:2.11.+") - testInstrumentation(project(":instrumentation:jdbc:javaagent")) - testImplementation(project(":instrumentation:executors:testing")) - - add("slickTestImplementation", project(":testing-common")) - add("slickTestImplementation", "org.scala-lang:scala-library") - add("slickTestImplementation", "com.typesafe.slick:slick_2.11:3.2.0") - add("slickTestImplementation", "com.h2database:h2:1.4.197") -} - -// Run Slick library tests along with the rest of tests -tasks { - val slickTest by existing - - check { - dependsOn(slickTest) - } } diff --git a/instrumentation/scala-fork-join-2.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/scalaexecutors/ScalaForkJoinPoolInstrumentation.java b/instrumentation/scala-fork-join-2.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/scalaexecutors/ScalaForkJoinPoolInstrumentation.java index 527de45e9c..6be8e81145 100644 --- a/instrumentation/scala-fork-join-2.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/scalaexecutors/ScalaForkJoinPoolInstrumentation.java +++ b/instrumentation/scala-fork-join-2.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/scalaexecutors/ScalaForkJoinPoolInstrumentation.java @@ -6,6 +6,7 @@ package io.opentelemetry.javaagent.instrumentation.scalaexecutors; import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.namedOneOf; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import io.opentelemetry.context.Context; @@ -24,22 +25,14 @@ public class ScalaForkJoinPoolInstrumentation implements TypeInstrumentation { @Override public ElementMatcher typeMatcher() { - // This might need to be an extendsClass matcher... return named("scala.concurrent.forkjoin.ForkJoinPool"); } @Override public void transform(TypeTransformer transformer) { transformer.applyAdviceToMethod( - named("execute") - .and(takesArgument(0, named(ScalaForkJoinTaskInstrumentation.TASK_CLASS_NAME))), - ScalaForkJoinPoolInstrumentation.class.getName() + "$SetScalaForkJoinStateAdvice"); - transformer.applyAdviceToMethod( - named("submit") - .and(takesArgument(0, named(ScalaForkJoinTaskInstrumentation.TASK_CLASS_NAME))), - ScalaForkJoinPoolInstrumentation.class.getName() + "$SetScalaForkJoinStateAdvice"); - transformer.applyAdviceToMethod( - named("invoke") + // doSubmit is internal method prior to 2.11, and externalPush is the internal method after + namedOneOf("doSubmit", "externalPush") .and(takesArgument(0, named(ScalaForkJoinTaskInstrumentation.TASK_CLASS_NAME))), ScalaForkJoinPoolInstrumentation.class.getName() + "$SetScalaForkJoinStateAdvice"); } diff --git a/instrumentation/scala-fork-join-2.8/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/scalaexecutors/ForkJoinPoolBridge.java b/instrumentation/scala-fork-join-2.8/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/scalaexecutors/ForkJoinPoolBridge.java new file mode 100644 index 0000000000..b472beec34 --- /dev/null +++ b/instrumentation/scala-fork-join-2.8/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/scalaexecutors/ForkJoinPoolBridge.java @@ -0,0 +1,114 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.scalaexecutors; + +import java.util.Collection; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import org.jetbrains.annotations.NotNull; +import scala.concurrent.forkjoin.ForkJoinPool; +import scala.concurrent.forkjoin.ForkJoinTask; + +public class ForkJoinPoolBridge implements ExecutorService { + + private final ForkJoinPool delegate; + + public ForkJoinPoolBridge(ForkJoinPool delegate) { + this.delegate = delegate; + } + + @Override + public void shutdown() { + delegate.shutdown(); + } + + @NotNull + @Override + public List shutdownNow() { + return delegate.shutdownNow(); + } + + @Override + public boolean isShutdown() { + return delegate.isShutdown(); + } + + @Override + public boolean isTerminated() { + return delegate.isTerminated(); + } + + @Override + public boolean awaitTermination(long timeout, @NotNull TimeUnit unit) + throws InterruptedException { + return delegate.awaitTermination(timeout, unit); + } + + @NotNull + @Override + public Future submit(@NotNull Callable task) { + return delegate.submit(task); + } + + @NotNull + @Override + public Future submit(@NotNull Runnable task, T result) { + return delegate.submit(task, result); + } + + @NotNull + @Override + public Future submit(@NotNull Runnable task) { + return delegate.submit(task); + } + + @NotNull + @Override + public List> invokeAll(@NotNull Collection> tasks) { + return delegate.invokeAll(tasks); + } + + @NotNull + @Override + public List> invokeAll( + @NotNull Collection> tasks, long timeout, @NotNull TimeUnit unit) { + // Scala 2.8's ForkJoinPool doesn't have corresponding method + return delegate.invokeAll(tasks); + } + + @NotNull + @Override + public T invokeAny(@NotNull Collection> tasks) + throws InterruptedException, ExecutionException { + // Scala 2.8's ForkJoinPool doesn't have corresponding method + return delegate.submit(tasks.iterator().next()).get(); + } + + @Override + public T invokeAny( + @NotNull Collection> tasks, long timeout, @NotNull TimeUnit unit) + throws InterruptedException, ExecutionException { + // Scala 2.8's ForkJoinPool doesn't have corresponding method + return delegate.submit(tasks.iterator().next()).get(); + } + + public T invoke(ForkJoinTask task) { + return delegate.invoke(task); + } + + @Override + public void execute(@NotNull Runnable command) { + delegate.execute(command); + } + + public void execute(ForkJoinTask task) { + delegate.execute(task); + } +} diff --git a/instrumentation/scala-fork-join-2.8/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/scalaexecutors/ScalaExecutorInstrumentationTest.java b/instrumentation/scala-fork-join-2.8/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/scalaexecutors/ScalaExecutorInstrumentationTest.java index c856c9258b..7628197cf5 100644 --- a/instrumentation/scala-fork-join-2.8/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/scalaexecutors/ScalaExecutorInstrumentationTest.java +++ b/instrumentation/scala-fork-join-2.8/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/scalaexecutors/ScalaExecutorInstrumentationTest.java @@ -14,13 +14,13 @@ import scala.concurrent.forkjoin.ForkJoinPool; import scala.concurrent.forkjoin.ForkJoinTask; class ScalaExecutorInstrumentationTest - extends AbstractExecutorServiceTest { + extends AbstractExecutorServiceTest { @RegisterExtension static final InstrumentationExtension testing = AgentInstrumentationExtension.create(); ScalaExecutorInstrumentationTest() { - super(new ForkJoinPool(), testing); + super(new ForkJoinPoolBridge(new ForkJoinPool()), testing); } @Override @@ -34,7 +34,7 @@ class ScalaExecutorInstrumentationTest } @Test - void submitForkJoinTask() { - executeTwoTasks(task -> executor().submit((ForkJoinTask) task)); + void executeForkJoinTask() { + executeTwoTasks(task -> executor().execute((ForkJoinTask) task)); } }