Skip to content

Commit

Permalink
Add compatibility with Java 21 (#1655)
Browse files Browse the repository at this point in the history
* Bumped ByteBuddy-Version and fixed Lambda-Problem in InstrumentationConfigurationResolver.

* - Added Java 21 to Agent Test Matrix
- Made Lambda-Check simpler

* bumped gradle-version to 8.7

* made java 21 test independend.

* test-workflow update.

* moved docker plugin version to props.

* updated workflow

* changed jdk determination step to bash

* clean gradle cache before executing assemble.

* changed default wrapper to 8.7

* added DockerPlugin-Version to clean-step

* added Downgrade Step for Java 8

* cahnged order of clean and downgrade

* set shell to bash

* deleted property from downgrade step.

* Chaynged to other downgrade strat.

* Downgraded Default Gradle Version

* Downgraded Default Palantir Docker Version

* add comments

* change image

* update spring config

* fix: more lambda-problems solved

* fix: auto-tracing test for java 21

* fix: auto-tracing test for java 21

* fix: HttpInMetric test for java 21 and AutoTracing for IBM JDK

* fix: disable debug log might solve oom-issue on ibm-java

* fix: changed max-heap-size for systemTest

---------

Co-authored-by: EddeCCC <eduard.schander@gmx.de>
  • Loading branch information
levinkerschberger and EddeCCC authored Jul 4, 2024
1 parent 34c61db commit f3ec22b
Show file tree
Hide file tree
Showing 15 changed files with 94 additions and 22 deletions.
32 changes: 28 additions & 4 deletions .github/workflows/agent_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,21 +24,45 @@ jobs:
fail-fast: false
matrix:
dockerimage:
- 'ibmcom/ibmjava:8-sdk'
- 'ibmjava:8-sdk'
- 'eclipse-temurin:8'
- 'eclipse-temurin:11'
- 'eclipse-temurin:17'
- 'eclipse-temurin:21'
container: ${{ matrix.dockerimage }}
steps:
- uses: actions/checkout@v3
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Determine JDK version
id: determine-jdk
# if Java 21 is used, update com.palantir.docker to 0.36.0, because 0.34.0 is not compatible with gradle 8
# Java 21 needs at least gradle 8
shell: bash
run: |
java_version=$(java -version 2>&1 | awk -F '"' '/version/ {print $2}')
echo "Java version: $java_version"
if [[ "$java_version" == 21* ]]; then
echo "::set-output name=gradle_property::comPalantirDockerVersion=0.36.0"
else
echo "::set-output name=gradle_property::comPalantirDockerVersion=0.34.0"
fi
- name: Upgrade Wrapper to 8.7 for Java 21
# Java 21 needs at least gradle 8
shell: bash
run: |
if [[ "${{ matrix.dockerimage }}" == "eclipse-temurin:21" ]]; then
sed -i 's/gradle-7.6-bin.zip/gradle-8.7-bin.zip/' gradle/wrapper/gradle-wrapper.properties
cat gradle/wrapper/gradle-wrapper.properties
fi
- name: Clean Gradle cache
run: ./gradlew -P${{ steps.determine-jdk.outputs.gradle_property }} clean
- name: assemble
run: ./gradlew :inspectit-ocelot-core:assemble
run: ./gradlew -P${{ steps.determine-jdk.outputs.gradle_property }} :inspectit-ocelot-core:assemble
- name: test
run: ./gradlew :inspectit-ocelot-core:test --no-daemon
run: ./gradlew -P${{ steps.determine-jdk.outputs.gradle_property }} :inspectit-ocelot-core:test --no-daemon
- name: systemTest
run: ./gradlew :inspectit-ocelot-agent:systemTest
run: ./gradlew -P${{ steps.determine-jdk.outputs.gradle_property }} :inspectit-ocelot-agent:systemTest
- name: upload test results
uses: actions/upload-artifact@v2
if: ${{ failure() }}
Expand Down
6 changes: 3 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -140,10 +140,10 @@ tasks.register('codeCoverageReport', JacocoReport) {
}

reports {
xml.enabled true
xml.required = true
xml.destination file("${buildDir}/reports/jacoco/report.xml")
html.enabled true
html.required = true
html.destination file("${buildDir}/reports/jacoco/html")
csv.enabled false
csv.required = false
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import org.springframework.boot.gradle.tasks.bundling.BootJar

plugins {
alias(libs.plugins.comPalantirDocker)
id("com.palantir.docker") version "${comPalantirDockerVersion}"
alias(configServerLibs.plugins.orgSpringframeworkBoot)
alias(libs.plugins.orgCyclonedxBom)
alias(configServerLibs.plugins.ioSpringDependencyManagement)
Expand Down
5 changes: 5 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Select Docker Plugin Version
# For JDK Version < 21 we need to set this to "0.34.0"
# For JDK Version >= 21 we need to set this to "0.36.0"
# Above, we need "0.36.0". Cause this is experimental, we will keep it at 0.34.0 for now.
comPalantirDockerVersion=0.34.0
5 changes: 3 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ ioOpentelemetryOpentelemetrySemconv = { module = "io.opentelemetry:opentelemetry
ioPrometheusSimpleclientHttpserver = "io.prometheus:simpleclient_httpserver:0.15.0"
javaxAnnotationJavaxAnnotationApi = "javax.annotation:javax.annotation-api:1.3.2"
log4j = "log4j:log4j:1.2.17"
netBytebuddyByteBuddy = "net.bytebuddy:byte-buddy:1.12.23"
netBytebuddyByteBuddy = "net.bytebuddy:byte-buddy:1.14.15"
netLogstashLogbackLogstashLogbackEncoder = "net.logstash.logback:logstash-logback-encoder:7.4"
orgApacheCommonsCommonsCollections4 = "org.apache.commons:commons-collections4:4.4"
orgApacheCommonsCommonsLang3 = "org.apache.commons:commons-lang3:3.13.0"
Expand All @@ -76,7 +76,7 @@ orgApacheLoggingLog4jLog4jCore = { module = "org.apache.logging.log4j:log4j-core
orgApacheTomcatEmbedTomcatEmbedEl = "org.apache.tomcat.embed:tomcat-embed-el:9.0.85"
orgAssertjAssertjCore = "org.assertj:assertj-core:3.22.0"
orgAssertjAssertjGuava = "org.assertj:assertj-guava:3.24.2"
orgAwaitility = "org.awaitility:awaitility:4.2.0"
orgAwaitility = "org.awaitility:awaitility:4.2.1"
orgEclipseJettyJettyServer = { module = "org.eclipse.jetty:jetty-server", version.ref = "orgEclipseJetty" }
orgHibernateValidatorHibernateValidator = "org.hibernate.validator:hibernate-validator:6.2.5.Final"
orgInfluxdbInfluxdbJava = "org.influxdb:influxdb-java:2.23"
Expand Down Expand Up @@ -117,6 +117,7 @@ comGithubBenManesVersions = "com.github.ben-manes.versions:0.48.0"
comGithubJk1DependencyLicenseReport = "com.github.jk1.dependency-license-report:2.0"
comGithubNodeGradleNode = "com.github.node-gradle.node:7.0.1"
# @pin There is a newer Version 0.35.0, but it is not Java 8 compatible
# For the Agent, this is currently provided via gradle.properties to make it dynamic.
comPalantirDocker = "com.palantir.docker:0.34.0"
ioSpringDependencyManagement = "io.spring.dependency-management:1.1.4"
meChampeauJmh = "me.champeau.jmh:0.7.2"
Expand Down
12 changes: 11 additions & 1 deletion inspectit-ocelot-agent/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ import org.springframework.boot.gradle.plugin.SpringBootPlugin
plugins {
alias(libs.plugins.meChampeauJmh)
id 'maven-publish'
alias(libs.plugins.comPalantirDocker)
id("com.palantir.docker") version "${comPalantirDockerVersion}"
alias(libs.plugins.orgSpringframeworkBoot) apply false
alias(libs.plugins.ioSpringDependencyManagement)
}



dependencyManagement {
imports {
mavenBom(SpringBootPlugin.BOM_COORDINATES)
Expand Down Expand Up @@ -260,6 +262,10 @@ task systemTest {
includes = ["rocks/inspectit/*"]
}

minHeapSize = "128m"
maxHeapSize = "2048m"



// The JaCoCo agent must be specified first so that it can instrument our agent.
// This is a work around for the issue that the JaCoCo agent is added last, cf.
Expand Down Expand Up @@ -289,6 +295,9 @@ task systemTest {
// that they are not garbage collected before being closed.
jvmArgs "-Dio.opentelemetry.context.enableStrictContext=true"

minHeapSize = "128m"
maxHeapSize = "2048m"

// enable reflection used in TestUtils#initializeOpenTelemetryForSystemTesting for JDK 11 and later
if(JavaVersion.current() >= JavaVersion.VERSION_11) {
// --add-opens has the following syntax: {A}/{package}={B}
Expand All @@ -309,6 +318,7 @@ task systemTest {
systemTest.dependsOn perVersionSystemTest
}
}

systemTest.mustRunAfter test
check.dependsOn systemTest

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ public static class TestServlet extends HttpServlet {

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setStatus(123);
// 123 was not a valid status code and rejected by jdk 21
resp.setStatus(200);
}
}

Expand All @@ -68,7 +69,7 @@ void testRequestRecorded() throws Exception {

Map<String, String> tags = new HashMap<>();
tags.put("http_path", "/servletapi");
tags.put("http_status", "123");
tags.put("http_status", "200");

long cnt = ((AggregationData.CountData) TestUtils.getDataForView("http/in/count", tags)).getCount();
double respSum = ((AggregationData.SumDataDouble) TestUtils.getDataForView("http/in/responsetime/sum", tags))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package rocks.inspectit.ocelot.instrumentation.tracing;

import io.opentelemetry.sdk.trace.data.SpanData;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import rocks.inspectit.ocelot.utils.TestUtils;
Expand Down Expand Up @@ -27,15 +28,36 @@ io.opentelemetry.sdk.trace.data.SpanData getSpanWithName(Collection<? extends io

@Test
void verifyStackTraceSampling() {
System.out.print("Java Vendor: " + System.getProperty("java.vendor"));
instrumentMe();

assertTraceExported((spans) -> {


io.opentelemetry.sdk.trace.data.SpanData root = getSpanWithName(spans, "AutoTracingTest.instrumentMe");
io.opentelemetry.sdk.trace.data.SpanData activeWait = getSpanWithName(spans, "*AutoTracingTest.activeWait");
io.opentelemetry.sdk.trace.data.SpanData passiveWait = getSpanWithName(spans, "*Thread.sleep");
assertThat(activeWait.getParentSpanId()).isEqualTo(root.getSpanId());
assertThat(passiveWait.getParentSpanId()).isEqualTo(root.getSpanId());
io.opentelemetry.sdk.trace.data.SpanData passiveWait;

io.opentelemetry.sdk.trace.data.SpanData compareSpan;

// Thread.sleep method appears as Thread.sleep0 in Java 21
if(System.getProperty("java.version").startsWith("21")) {
// In Java 21 the root span AutoTracingTest.instrumentMe is followed by a child-span *AutoTracingTest.instrumentMe
compareSpan = getSpanWithName(spans, "*AutoTracingTest.instrumentMe");
passiveWait = getSpanWithName(spans, "*Thread.sleep0");

}
else if(System.getProperty("java.vendor").startsWith("IBM")){
compareSpan = root;
passiveWait = getSpanWithName(spans, "*Thread.sleepImpl");
}
else {
compareSpan = root;
passiveWait = getSpanWithName(spans, "*Thread.sleep");
}

assertThat(activeWait.getParentSpanId()).isEqualTo(compareSpan.getSpanId());
assertThat(passiveWait.getParentSpanId()).isEqualTo(compareSpan.getSpanId());

assertThat(activeWait.getEndEpochNanos()).isLessThan(passiveWait.getEndEpochNanos());
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ void assertTraceExported(Consumer<? super List<? extends SpanData>> assertions)
await().atMost(15, TimeUnit.SECONDS).untilAsserted(() -> {
Map<String, List<io.opentelemetry.sdk.trace.data.SpanData>> traces = getExportedSpans().stream()
.collect(Collectors.groupingBy(s -> s.getSpanContext().getTraceId(), Collectors.toList()));
// Print all traces for debugging
// traces.forEach((traceId, spans) -> {
// System.out.println("----------------- Trace Start ---------------");
// System.out.println("Trace " + traceId);
// spans.forEach(span -> System.out.println(" " + span.getName()));
// spans.forEach(span -> System.out.println(" Span ID: " + span.getSpanId()));
// spans.forEach(span -> System.out.println("Parent Span ID: " + span.getParentSpanId()));
// System.out.println("----------------- Trace End -----------------");
// });
assertThat(traces.values()).anySatisfy(assertions);
assertThat(traces.values()).filteredOnAssertions(assertions).hasSize(1);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class SpringConfiguration {

private ScheduledExecutorService activeExecutor = null;

@Bean
@Bean(destroyMethod = "shutdown")
public ScheduledExecutorService getScheduledExecutorService(@Value("#{#inspectit.threadPoolSize}") int poolSize) {
AtomicInteger threadCount = new AtomicInteger();
activeExecutor = Executors.newScheduledThreadPool(poolSize, (runnable) -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ private boolean isHiddenTop(StackTraceElement element) {

private boolean isLambda(StackTraceElement element) {
String className = element.getClassName();
return className.contains("$Lambda$");
return className.contains("$Lambda");
}

public StackTraceElement get(int indexFromRoot) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ boolean isIgnoredClass(TypeDescriptionWithClassLoader typeWithLoader, Instrument
return true;
}

if (config.getSource().isExcludeLambdas() && type.getName().contains("$$Lambda$")) {
if (config.getSource().isExcludeLambdas() && type.getName().contains("$$Lambda")) {
return true;
}
return isClassFromIgnoredPackage(config.getSource(), type.getName(), loader);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ private static class ExecutorAdvice {
@Advice.OnMethodEnter
public static void enter(@Advice.Argument(value = 0, readOnly = false) Runnable runnable) {
if (Instances.contextManager.enterCorrelation()) {
if (runnable.getClass().getName().contains("$$Lambda$")) {
if (runnable.getClass().getName().contains("$$Lambda")) {
// order is important because the log-correlator requires the restored context, thus, have to be
// called after the context wrapper (needs to be nested by it)
runnable = Instances.logTraceCorrelator.wrap(runnable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public class ScheduledExecutorContextPropagationSensor implements SpecialSensor
/**
* Identifier for lambda classes.
*/
private static final String LAMBDA = "$$Lambda$";
private static final String LAMBDA = "$$Lambda";

private static final ElementMatcher<TypeDescription> CLASSES_MATCHER = isSubTypeOf(ScheduledExecutorService.class);

Expand Down
2 changes: 1 addition & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ if(JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_17)) {
}
}
}
}
}

0 comments on commit f3ec22b

Please sign in to comment.