From 15ab020468cb0da6648047225f628188c3e32bb7 Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Sun, 25 Dec 2022 17:22:46 +0200 Subject: [PATCH 01/21] Avoid dependency on return type incompatible with spring-web 6.x --- .../elastic/apm/agent/springwebflux/WebfluxHelper.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java index 1c0e31f72b..59b4f00c3b 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java @@ -37,7 +37,6 @@ import org.reactivestreams.Publisher; import org.springframework.http.HttpCookie; import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.http.server.reactive.ServerHttpResponse; import org.springframework.util.MultiValueMap; @@ -270,8 +269,13 @@ private static void fillRequest(Transaction transaction, ServerWebExchange excha private static void fillResponse(Transaction transaction, ServerWebExchange exchange) { ServerHttpResponse serverResponse = exchange.getResponse(); - HttpStatus statusCode = serverResponse.getStatusCode(); - int status = statusCode != null ? statusCode.value() : 200; + + int status; + if (serverResponse.getStatusCode() != null) { + status = serverResponse.getStatusCode().value(); + } else { + status = 200; + } transaction.withResultIfUnset(ResultUtil.getResultByHttpStatus(status)); From 6e14086c846ceebd01f82ef3e5b1a21558db17ea Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Mon, 26 Dec 2022 16:33:46 +0200 Subject: [PATCH 02/21] Adding separate module for each spring-web version --- .../apm-spring-web-6/pom.xml | 42 +++++++++++++++ .../agent/springwebflux/SpringWeb6Utils.java | 34 +++++++++++++ .../springwebflux/SpringWeb6UtilsTest.java | 44 ++++++++++++++++ .../apm-spring-webflux-common/pom.xml | 37 ++++++++++++++ .../agent/springwebflux/SpringWeb5Utils.java | 30 +++++++++++ .../springwebflux/SpringWebUtilsFactory.java | 51 +++++++++++++++++++ .../springwebflux/SpringWebVersionUtils.java | 25 +++++++++ .../SpringWebUtilsFactoryTest.java | 44 ++++++++++++++++ .../apm-spring-webflux-plugin/pom.xml | 6 +++ .../agent/springwebflux/WebfluxHelper.java | 10 ++-- apm-agent-plugins/apm-spring-webflux/pom.xml | 2 + apm-agent/pom.xml | 10 ++++ 12 files changed, 328 insertions(+), 7 deletions(-) create mode 100755 apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml create mode 100644 apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb6Utils.java create mode 100644 apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb6UtilsTest.java create mode 100755 apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/pom.xml create mode 100644 apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb5Utils.java create mode 100644 apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactory.java create mode 100644 apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtils.java create mode 100644 apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactoryTest.java diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml b/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml new file mode 100755 index 0000000000..a0b49b13a6 --- /dev/null +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml @@ -0,0 +1,42 @@ + + + 4.0.0 + + + co.elastic.apm + apm-spring-webflux + 1.35.1-SNAPSHOT + + + apm-spring-web-6 + ${project.groupId}:${project.artifactId} + + + ${project.basedir}/../../.. + + 8 + ${maven.compiler.target} + + true + + + + + org.springframework + spring-web + 6.0.1 + provided + + + ${project.groupId} + apm-spring-webflux-common + ${project.version} + + + io.projectreactor + reactor-core + 3.2.0.RELEASE + test + + + diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb6Utils.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb6Utils.java new file mode 100644 index 0000000000..0bb4b30200 --- /dev/null +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb6Utils.java @@ -0,0 +1,34 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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. + */ +package co.elastic.apm.agent.springwebflux; + +import org.springframework.http.HttpStatusCode; +import org.springframework.http.server.reactive.ServerHttpResponse; + +/** + * This class is compiled with spring-web 6.x, as it relies on {@link HttpStatusCode} and an API that was introduced in 6.0.0. + * Therefore, it is only loaded through its class name through {@link SpringWebUtilsFactory} + */ +public class SpringWeb6Utils implements SpringWebVersionUtils { + @Override + public int getStatusCode(ServerHttpResponse response) { + HttpStatusCode statusCode = response.getStatusCode(); + return statusCode != null ? statusCode.value() : 200; + } +} diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb6UtilsTest.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb6UtilsTest.java new file mode 100644 index 0000000000..49ff2f4e9e --- /dev/null +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb6UtilsTest.java @@ -0,0 +1,44 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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. + */ +package co.elastic.apm.agent.springwebflux; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.server.reactive.ServerHttpResponse; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +public class SpringWeb6UtilsTest { + + private final SpringWebVersionUtils springWebVersionUtils = SpringWebUtilsFactory.getImplementation(); + + @Test + void testSpringWebUtilsVersion() { + assertThat(springWebVersionUtils).isInstanceOf(SpringWeb6Utils.class); + } + + @Test + void testGetStatusCode() { + ServerHttpResponse mockResponse = mock(ServerHttpResponse.class); + doReturn(HttpStatusCode.valueOf(222)).when(mockResponse).getStatusCode(); + assertThat(springWebVersionUtils.getStatusCode(mockResponse)).isEqualTo(222); + } +} diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/pom.xml b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/pom.xml new file mode 100755 index 0000000000..1018374f57 --- /dev/null +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/pom.xml @@ -0,0 +1,37 @@ + + + 4.0.0 + + + co.elastic.apm + apm-spring-webflux + 1.35.1-SNAPSHOT + + + apm-spring-webflux-common + ${project.groupId}:${project.artifactId} + + + ${project.basedir}/../../.. + + 8 + ${maven.compiler.target} + + true + + + + + org.springframework + spring-web + ${version.spring} + provided + + + io.projectreactor + reactor-core + 3.2.0.RELEASE + test + + + diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb5Utils.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb5Utils.java new file mode 100644 index 0000000000..bd387fd569 --- /dev/null +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb5Utils.java @@ -0,0 +1,30 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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. + */ +package co.elastic.apm.agent.springwebflux; + +import org.springframework.http.HttpStatus; +import org.springframework.http.server.reactive.ServerHttpResponse; + +public class SpringWeb5Utils implements SpringWebVersionUtils { + @Override + public int getStatusCode(ServerHttpResponse response) { + HttpStatus statusCode = response.getStatusCode(); + return statusCode != null ? statusCode.value() : 200; + } +} diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactory.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactory.java new file mode 100644 index 0000000000..68aebf5798 --- /dev/null +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactory.java @@ -0,0 +1,51 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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. + */ +package co.elastic.apm.agent.springwebflux; + +import co.elastic.apm.agent.sdk.logging.Logger; +import co.elastic.apm.agent.sdk.logging.LoggerFactory; + +public class SpringWebUtilsFactory { + + private static final String SPRING_WEB_6_UTILS_CLASS_NAME = "co.elastic.apm.agent.springwebflux.SpringWeb6Utils"; + + private static final Logger logger = LoggerFactory.getLogger(SpringWebUtilsFactory.class); + private static SpringWebVersionUtils instance; + + static { + try { + Class springWeb6Class = Class.forName("org.springframework.http.HttpStatusCode"); + try { + // loading class by name sot to avoid linkage attempt when spring-web 6 is unavailable + instance = (SpringWebVersionUtils) Class.forName(SPRING_WEB_6_UTILS_CLASS_NAME).getDeclaredConstructor().newInstance(); + logger.debug("Spring-web 6.x+ identified"); + } catch (Exception e) { + logger.error("Spring-web 6.x+ identified, but failed to load related utility class", e); + instance = new SpringWeb5Utils(); + } + } catch (Exception e) { + logger.debug("Spring-web < 6.x identified"); + instance = new SpringWeb5Utils(); + } + } + + public static SpringWebVersionUtils getImplementation() { + return instance; + } +} diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtils.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtils.java new file mode 100644 index 0000000000..a448da5617 --- /dev/null +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtils.java @@ -0,0 +1,25 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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. + */ +package co.elastic.apm.agent.springwebflux; + +import org.springframework.http.server.reactive.ServerHttpResponse; + +public interface SpringWebVersionUtils { + int getStatusCode(ServerHttpResponse response); +} diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactoryTest.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactoryTest.java new file mode 100644 index 0000000000..861f2a3a15 --- /dev/null +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactoryTest.java @@ -0,0 +1,44 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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. + */ +package co.elastic.apm.agent.springwebflux; + +import org.junit.jupiter.api.Test; +import org.springframework.http.HttpStatus; +import org.springframework.http.server.reactive.ServerHttpResponse; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; + +class SpringWebUtilsFactoryTest { + + private final SpringWebVersionUtils springWebVersionUtils = SpringWebUtilsFactory.getImplementation(); + + @Test + void testSpringWebUtilsVersion() { + assertThat(springWebVersionUtils).isInstanceOf(SpringWeb5Utils.class); + } + + @Test + void testGetStatusCode() { + ServerHttpResponse mockResponse = mock(ServerHttpResponse.class); + doReturn(HttpStatus.IM_USED).when(mockResponse).getStatusCode(); + assertThat(springWebVersionUtils.getStatusCode(mockResponse)).isEqualTo(226); + } +} diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/pom.xml b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/pom.xml index 8091850618..3b1ebe278b 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/pom.xml +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/pom.xml @@ -46,6 +46,12 @@ ${project.version} + + ${project.groupId} + apm-spring-webflux-common + ${project.version} + + co.elastic.apm diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java index 59b4f00c3b..abd2e453f9 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java @@ -72,6 +72,8 @@ public class WebfluxHelper { private static final HeaderGetter HEADER_GETTER = new HeaderGetter(); + private static final SpringWebVersionUtils springWebVersionUtils = SpringWebUtilsFactory.getImplementation(); + private static final CoreConfiguration coreConfig; private static final WebConfiguration webConfig; private static final HttpServerHelper serverHelper; @@ -269,13 +271,7 @@ private static void fillRequest(Transaction transaction, ServerWebExchange excha private static void fillResponse(Transaction transaction, ServerWebExchange exchange) { ServerHttpResponse serverResponse = exchange.getResponse(); - - int status; - if (serverResponse.getStatusCode() != null) { - status = serverResponse.getStatusCode().value(); - } else { - status = 200; - } + int status = springWebVersionUtils.getStatusCode(serverResponse); transaction.withResultIfUnset(ResultUtil.getResultByHttpStatus(status)); diff --git a/apm-agent-plugins/apm-spring-webflux/pom.xml b/apm-agent-plugins/apm-spring-webflux/pom.xml index e520a1ed55..68167985b7 100644 --- a/apm-agent-plugins/apm-spring-webflux/pom.xml +++ b/apm-agent-plugins/apm-spring-webflux/pom.xml @@ -31,5 +31,7 @@ apm-spring-webflux-plugin apm-spring-webclient-plugin apm-spring-webflux-testapp + apm-spring-web-6 + apm-spring-webflux-common diff --git a/apm-agent/pom.xml b/apm-agent/pom.xml index 8e036b4b09..69330ab13b 100644 --- a/apm-agent/pom.xml +++ b/apm-agent/pom.xml @@ -321,6 +321,16 @@ apm-spring-webflux-plugin ${project.version} + + ${project.groupId} + apm-spring-web-6 + ${project.version} + + + ${project.groupId} + apm-spring-webflux-common + ${project.version} + ${project.groupId} apm-spring-webmvc-plugin From 2c06834e4b3cb1e50a33e4fda87145abcbda31c0 Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Mon, 26 Dec 2022 17:10:55 +0200 Subject: [PATCH 03/21] Loading spring-web 5 class also only by name when necessary --- .../springwebflux/SpringWeb6UtilsTest.java | 4 ++- .../agent/springwebflux/SpringWeb5Utils.java | 5 ++++ .../springwebflux/SpringWebUtilsFactory.java | 25 +++++++++++++------ .../SpringWebUtilsFactoryTest.java | 4 ++- .../agent/springwebflux/WebfluxHelper.java | 3 ++- 5 files changed, 31 insertions(+), 10 deletions(-) diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb6UtilsTest.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb6UtilsTest.java index 49ff2f4e9e..21edaf7de2 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb6UtilsTest.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb6UtilsTest.java @@ -22,13 +22,15 @@ import org.springframework.http.HttpStatusCode; import org.springframework.http.server.reactive.ServerHttpResponse; +import java.util.Objects; + import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; public class SpringWeb6UtilsTest { - private final SpringWebVersionUtils springWebVersionUtils = SpringWebUtilsFactory.getImplementation(); + private final SpringWebVersionUtils springWebVersionUtils = Objects.requireNonNull(SpringWebUtilsFactory.getImplementation()); @Test void testSpringWebUtilsVersion() { diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb5Utils.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb5Utils.java index bd387fd569..c3cbed706a 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb5Utils.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb5Utils.java @@ -21,7 +21,12 @@ import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpResponse; +/** + * This class is compiled with spring-web 5.x, relying on the {@link ServerHttpResponse#getStatusCode()}, which changed in 6.0.0. + * Therefore, it MUST only be loaded through its class name through {@link SpringWebUtilsFactory}. + */ public class SpringWeb5Utils implements SpringWebVersionUtils { + @Override public int getStatusCode(ServerHttpResponse response) { HttpStatus statusCode = response.getStatusCode(); diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactory.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactory.java index 68aebf5798..622f10f35d 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactory.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactory.java @@ -21,30 +21,41 @@ import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; +import javax.annotation.Nullable; + public class SpringWebUtilsFactory { + private static final String SPRING_WEB_5_UTILS_CLASS_NAME = "co.elastic.apm.agent.springwebflux.SpringWeb5Utils"; private static final String SPRING_WEB_6_UTILS_CLASS_NAME = "co.elastic.apm.agent.springwebflux.SpringWeb6Utils"; private static final Logger logger = LoggerFactory.getLogger(SpringWebUtilsFactory.class); - private static SpringWebVersionUtils instance; + + @Nullable + private static SpringWebVersionUtils instance = null; static { try { - Class springWeb6Class = Class.forName("org.springframework.http.HttpStatusCode"); + Class.forName("org.springframework.http.HttpStatusCode"); try { - // loading class by name sot to avoid linkage attempt when spring-web 6 is unavailable + // loading class by name so to avoid linkage attempt when spring-web 6 is unavailable instance = (SpringWebVersionUtils) Class.forName(SPRING_WEB_6_UTILS_CLASS_NAME).getDeclaredConstructor().newInstance(); logger.debug("Spring-web 6.x+ identified"); } catch (Exception e) { logger.error("Spring-web 6.x+ identified, but failed to load related utility class", e); - instance = new SpringWeb5Utils(); } - } catch (Exception e) { - logger.debug("Spring-web < 6.x identified"); - instance = new SpringWeb5Utils(); + } catch (ClassNotFoundException ignored) { + // assuming spring-web < 6.x + try { + // loading class by name so to avoid linkage attempt on spring-web 6, where the getStatusCode API has changed + instance = (SpringWebVersionUtils) Class.forName(SPRING_WEB_5_UTILS_CLASS_NAME).getDeclaredConstructor().newInstance(); + logger.debug("Spring-web < 6.x identified"); + } catch (Exception e) { + logger.error("Spring-web < 6.x identified, but failed to load related utility class", e); + } } } + @Nullable public static SpringWebVersionUtils getImplementation() { return instance; } diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactoryTest.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactoryTest.java index 861f2a3a15..6b11157d01 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactoryTest.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactoryTest.java @@ -22,13 +22,15 @@ import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpResponse; +import java.util.Objects; + import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; class SpringWebUtilsFactoryTest { - private final SpringWebVersionUtils springWebVersionUtils = SpringWebUtilsFactory.getImplementation(); + private final SpringWebVersionUtils springWebVersionUtils = Objects.requireNonNull(SpringWebUtilsFactory.getImplementation()); @Test void testSpringWebUtilsVersion() { diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java index abd2e453f9..5c667ec5f5 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java @@ -72,6 +72,7 @@ public class WebfluxHelper { private static final HeaderGetter HEADER_GETTER = new HeaderGetter(); + @Nullable private static final SpringWebVersionUtils springWebVersionUtils = SpringWebUtilsFactory.getImplementation(); private static final CoreConfiguration coreConfig; @@ -271,7 +272,7 @@ private static void fillRequest(Transaction transaction, ServerWebExchange excha private static void fillResponse(Transaction transaction, ServerWebExchange exchange) { ServerHttpResponse serverResponse = exchange.getResponse(); - int status = springWebVersionUtils.getStatusCode(serverResponse); + int status = springWebVersionUtils != null ? springWebVersionUtils.getStatusCode(serverResponse) : 200; transaction.withResultIfUnset(ResultUtil.getResultByHttpStatus(status)); From a1bb0e1070011622003b7c8700d31e5fa2076e66 Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Tue, 27 Dec 2022 08:38:38 +0200 Subject: [PATCH 04/21] Removing specific java version directives --- .../apm-spring-webflux/apm-spring-web-6/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml b/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml index a0b49b13a6..0af2f5d6d6 100755 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml @@ -13,11 +13,6 @@ ${project.basedir}/../../.. - - 8 - ${maven.compiler.target} - - true From c418c136359f638c713ee36322ed56599789a693 Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Tue, 27 Dec 2022 09:05:34 +0200 Subject: [PATCH 05/21] Compile Spring 6.x module with Java 17 --- .../apm-spring-webflux/apm-spring-web-6/pom.xml | 6 ++++++ .../external-plugin-test/external-plugin/pom.xml | 2 +- pom.xml | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml b/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml index 0af2f5d6d6..87ee5afafa 100755 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml @@ -13,6 +13,12 @@ ${project.basedir}/../../.. + + + 17 + ${maven.compiler.target} + + true diff --git a/integration-tests/external-plugin-test/external-plugin/pom.xml b/integration-tests/external-plugin-test/external-plugin/pom.xml index 212c395074..688221c67b 100644 --- a/integration-tests/external-plugin-test/external-plugin/pom.xml +++ b/integration-tests/external-plugin-test/external-plugin/pom.xml @@ -87,7 +87,7 @@ --> maven-shade-plugin - 3.2.4 + 3.3.0 package diff --git a/pom.xml b/pom.xml index a3180fa818..15f84d6f04 100644 --- a/pom.xml +++ b/pom.xml @@ -540,7 +540,7 @@ maven-shade-plugin - 3.2.4 + 3.3.0 maven-clean-plugin From 8cdf630b942e926d8b0e7627c037f34a59f332a9 Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Tue, 27 Dec 2022 09:37:31 +0200 Subject: [PATCH 06/21] Restoring defaults --- .../apm-spring-webflux/apm-spring-web-6/pom.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml b/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml index 87ee5afafa..0af2f5d6d6 100755 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml @@ -13,12 +13,6 @@ ${project.basedir}/../../.. - - - 17 - ${maven.compiler.target} - - true From 5eb4cbca44f508e4a5205d5051bd96006b4113f3 Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Tue, 27 Dec 2022 12:25:59 +0200 Subject: [PATCH 07/21] Upgrade animal-sniffer plugin --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 15f84d6f04..e9412d6b12 100644 --- a/pom.xml +++ b/pom.xml @@ -125,7 +125,7 @@ 5.4.0 - 1.17 + 1.22 1.16.3 From 16621b44990a818866b4f44c614d6acfb0f65a3e Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Tue, 27 Dec 2022 12:43:32 +0200 Subject: [PATCH 08/21] Switching to Java 17 on CI --- .ci/load/Jenkinsfile | 5 +++-- .ci/packer_cache.sh | 2 +- .ci/release/Jenkinsfile | 2 +- Jenkinsfile | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.ci/load/Jenkinsfile b/.ci/load/Jenkinsfile index 1f40d81292..a98b6c8f36 100644 --- a/.ci/load/Jenkinsfile +++ b/.ci/load/Jenkinsfile @@ -81,8 +81,9 @@ pipeline { echo "Switch to requested agent version = ${params.apm_version}" sh(script: "git checkout ${params.apm_version}") - echo 'Building agent with Java 11' - sh(script: "JAVA_HOME=${env.HUDSON_HOME}/.java/java11 ./mvnw --batch-mode clean package -DskipTests=true -Dmaven.javadoc.skip=true -Dmaven.sources.skip=true") + echo 'Building agent with Java 17' + sh(script: "JAVA_HOME=${env.HUDSON_HOME}/.java/jdk17 ./mvnw --batch-mode clean package -DskipTests=true -Dmaven.javadoc + .skip=true -Dmaven.sources.skip=true") // copy agent jar to a known filename that don't change with version sh(script: "cp -v \$(find ./elastic-apm-agent/target -name '*.jar' | grep -v sources | grep -v original | grep -v javadoc) ${WORKSPACE}/elastic-apm-agent.jar") diff --git a/.ci/packer_cache.sh b/.ci/packer_cache.sh index b37b6f9b0b..5fe042b881 100755 --- a/.ci/packer_cache.sh +++ b/.ci/packer_cache.sh @@ -3,7 +3,7 @@ set +e source /usr/local/bin/bash_standard_lib.sh -retry 3 JAVA_HOME=$HOME/.java/java11 \ +retry 3 JAVA_HOME=$HOME/.java/jdk17 \ ./mvnw clean package \ -q -B \ -DskipTests=true \ diff --git a/.ci/release/Jenkinsfile b/.ci/release/Jenkinsfile index deb3259002..c2883860a4 100644 --- a/.ci/release/Jenkinsfile +++ b/.ci/release/Jenkinsfile @@ -11,7 +11,7 @@ pipeline { NEXUS_SECRET = 'secret/apm-team/ci/nexus' MAVEN_CONFIG = '-B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Dmaven.repo.local=.m2' HOME = "${env.WORKSPACE}" - JAVA_HOME = "${env.HUDSON_HOME}/.java/java10" + JAVA_HOME = "${env.HUDSON_HOME}/.java/jdk17" PATH = "${env.JAVA_HOME}/bin:${env.PATH}" SLACK_CHANNEL = '#apm-agent-java' NOTIFY_TO = 'build-apm+apm-agent-java@elastic.co' diff --git a/Jenkinsfile b/Jenkinsfile index e50f7ffe4c..de879e2819 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -31,7 +31,7 @@ pipeline { issueCommentTrigger("(${obltGitHubComments()}|^run (jdk compatibility|benchmark|integration|windows) tests)") } parameters { - string(name: 'JAVA_VERSION', defaultValue: 'java11', description: 'Java version to build & test') + string(name: 'JAVA_VERSION', defaultValue: 'jdk17', description: 'Java version to build & test') string(name: 'MAVEN_CONFIG', defaultValue: '-V -B -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn -Dhttps.protocols=TLSv1.2 -Dmaven.wagon.http.retryHandler.count=3 -Dmaven.wagon.httpconnectionManager.ttlSeconds=25', description: 'Additional maven options.') // Note about GH checks and optional steps From 705aee20f041aa9866ca99029f68c1da03496dfe Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Tue, 27 Dec 2022 13:01:57 +0200 Subject: [PATCH 09/21] Restore older animal-sniffer version --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e9412d6b12..15f84d6f04 100644 --- a/pom.xml +++ b/pom.xml @@ -125,7 +125,7 @@ 5.4.0 - 1.22 + 1.17 1.16.3 From 5eccbe825913fbf3e04ff8b3bbccf0c6a391b17d Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Tue, 27 Dec 2022 13:04:29 +0200 Subject: [PATCH 10/21] Disabled animal-sniffer for module --- apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml b/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml index 0af2f5d6d6..ce0739f464 100755 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml @@ -13,6 +13,9 @@ ${project.basedir}/../../.. + + + true From e5750127c779edb808ccb254551d1cbb1ab42cc2 Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Wed, 28 Dec 2022 13:15:19 +0200 Subject: [PATCH 11/21] Compatibility tests with JDKs 11 and 19 --- Jenkinsfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index de879e2819..1dbec4a52f 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -371,8 +371,7 @@ pipeline { axis { // the list of support java versions can be found in the infra repo (ansible/roles/java/defaults/main.yml) name 'JDK_VERSION' - // 'openjdk18' disabled for now see https://github.com/elastic/apm-agent-java/issues/2328 - values 'openjdk17' + values 'jdk11', "jdk19" } } stages { From 4e6fa892eb13760c3ebd3595df173b175fd83906 Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Thu, 29 Dec 2022 18:58:00 +0200 Subject: [PATCH 12/21] Using a separate module and profiles for Java 17 --- Jenkinsfile | 3 +- .../springwebflux/SpringWebVersionUtils.java | 98 +++++++++++++++++++ .../apm/agent/springwebflux/package-info.java | 26 +++++ .../SpringWebVersionUtilsTest.java | 12 ++- .../apm-agent-spring-6}/pom.xml | 20 ++-- .../agent/springwebflux/SpringWeb6Utils.java | 8 +- .../springwebflux/SpringWeb6UtilsTest.java | 17 ++-- apm-agent-java-17/pom.xml | 27 +++++ .../apm-spring-webflux-common/pom.xml | 37 ------- .../springwebflux/SpringWebUtilsFactory.java | 62 ------------ .../apm-spring-webflux-plugin/pom.xml | 7 -- .../agent/springwebflux/SpringWeb5Utils.java | 8 +- .../agent/springwebflux/WebfluxHelper.java | 10 +- .../springwebflux/SpringWeb5UtilsTest.java} | 19 ++-- apm-agent-plugins/apm-spring-webflux/pom.xml | 2 - apm-agent/pom.xml | 27 ++--- pom.xml | 11 +++ 17 files changed, 227 insertions(+), 167 deletions(-) create mode 100644 apm-agent-core/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtils.java create mode 100644 apm-agent-core/src/main/java/co/elastic/apm/agent/springwebflux/package-info.java rename apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtils.java => apm-agent-core/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtilsTest.java (72%) rename {apm-agent-plugins/apm-spring-webflux/apm-spring-web-6 => apm-agent-java-17/apm-agent-spring-6}/pom.xml (76%) rename {apm-agent-plugins/apm-spring-webflux/apm-spring-web-6 => apm-agent-java-17/apm-agent-spring-6}/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb6Utils.java (78%) rename {apm-agent-plugins/apm-spring-webflux/apm-spring-web-6 => apm-agent-java-17/apm-agent-spring-6}/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb6UtilsTest.java (78%) create mode 100644 apm-agent-java-17/pom.xml delete mode 100755 apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/pom.xml delete mode 100644 apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactory.java rename apm-agent-plugins/apm-spring-webflux/{apm-spring-webflux-common => apm-spring-webflux-plugin}/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb5Utils.java (83%) rename apm-agent-plugins/apm-spring-webflux/{apm-spring-webflux-common/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactoryTest.java => apm-spring-webflux-plugin/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb5UtilsTest.java} (76%) diff --git a/Jenkinsfile b/Jenkinsfile index 1dbec4a52f..98e0d9eea0 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -371,7 +371,8 @@ pipeline { axis { // the list of support java versions can be found in the infra repo (ansible/roles/java/defaults/main.yml) name 'JDK_VERSION' - values 'jdk11', "jdk19" + // todo: upgrade jacoco and try adding "jdk19" + values 'jdk11' } } stages { diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtils.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtils.java new file mode 100644 index 0000000000..2451029042 --- /dev/null +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtils.java @@ -0,0 +1,98 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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. + */ +package co.elastic.apm.agent.springwebflux; + +import javax.annotation.Nullable; + +/** + * This class must be located within the same package as used by the WebFlux instrumentation, otherwise it will be loaded by the + * agent class loader, rather than the WebFlux plugin class loader. If the {@link ISpringWebVersionUtils} implementations are loaded + * anywhere other than the WebFlux plugin class loader, their loading will cause a {@link LinkageError}. + */ +public class SpringWebVersionUtils { + + private static final String SPRING_WEB_5_UTILS_CLASS_NAME = "co.elastic.apm.agent.springwebflux.SpringWeb5Utils"; + private static final String SPRING_WEB_6_UTILS_CLASS_NAME = "co.elastic.apm.agent.springwebflux.SpringWeb6Utils"; + + @Nullable + private static ISpringWebVersionUtils instance = null; + + private static volatile boolean initialized = false; + + private static synchronized void initialize() throws Exception { + if (initialized) { + return; + } + try { + // check if using spring 6.0.0 or higher + Class.forName("org.springframework.http.HttpStatusCode"); + try { + // loading class by name so to avoid linkage attempt when spring-web 6 is unavailable + instance = (ISpringWebVersionUtils) Class.forName(SPRING_WEB_6_UTILS_CLASS_NAME).getDeclaredConstructor().newInstance(); + } catch (Exception e) { + throw new IllegalStateException("Spring-web 6.x+ identified, but failed to load related utility class", e); + } + } catch (ClassNotFoundException ignored) { + // assuming spring-web < 6.x + try { + // loading class by name so to avoid linkage attempt on spring-web 6, where the getStatusCode API has changed + instance = (ISpringWebVersionUtils) Class.forName(SPRING_WEB_5_UTILS_CLASS_NAME).getDeclaredConstructor().newInstance(); + } catch (Exception e) { + throw new IllegalStateException("Spring-web < 6.x identified, but failed to load related utility class", e); + } + } finally { + initialized = true; + } + } + + @Nullable + private static ISpringWebVersionUtils getImplementation() throws Exception { + if (!initialized) { + initialize(); + } + return instance; + } + + /** + * A utility method to get the status code of a {@code org.springframework.http.server.reactive.ServerHttpResponse} from any version + * of Spring framework. + * + * @param response must be of type {@code org.springframework.http.server.reactive.ServerHttpResponse}, otherwise an Exception is + * expected + * @return the status code of the provided response + */ + public static int getStatusCode(Object response) throws Exception { + ISpringWebVersionUtils implementation = getImplementation(); + if (implementation != null) { + return implementation.getStatusCode(response); + } + return 200; + } + + public interface ISpringWebVersionUtils { + /** + * A utility method to get the status code of a {@code org.springframework.http.server.reactive.ServerHttpResponse} from any version + * of Spring framework. + * + * @param response must be of type {@code org.springframework.http.server.reactive.ServerHttpResponse} + * @return the corresponding status code + */ + int getStatusCode(Object response); + } +} diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/springwebflux/package-info.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/springwebflux/package-info.java new file mode 100644 index 0000000000..86685638b7 --- /dev/null +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/springwebflux/package-info.java @@ -0,0 +1,26 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. 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 package is common as it needs to be used by Spring WebFlux instrumentations from different modules (compiled by different Java + * versions). It must have the same package name as used by the WebFlux instrumentation, as it is expected to be loaded by the same + * plugin class loader that loads the WebFlux advice and helper classes. + */ +package co.elastic.apm.agent.springwebflux; + diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtils.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtilsTest.java similarity index 72% rename from apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtils.java rename to apm-agent-core/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtilsTest.java index a448da5617..6aef87cea1 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtils.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtilsTest.java @@ -18,8 +18,14 @@ */ package co.elastic.apm.agent.springwebflux; -import org.springframework.http.server.reactive.ServerHttpResponse; +import org.junit.jupiter.api.Test; -public interface SpringWebVersionUtils { - int getStatusCode(ServerHttpResponse response); +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +class SpringWebVersionUtilsTest { + + @Test + void testWrongResponseType() { + assertThatThrownBy(() -> SpringWebVersionUtils.getStatusCode(new Object())).isInstanceOf(IllegalStateException.class); + } } diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml b/apm-agent-java-17/apm-agent-spring-6/pom.xml similarity index 76% rename from apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml rename to apm-agent-java-17/apm-agent-spring-6/pom.xml index ce0739f464..14f40051e2 100755 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/pom.xml +++ b/apm-agent-java-17/apm-agent-spring-6/pom.xml @@ -4,32 +4,30 @@ co.elastic.apm - apm-spring-webflux + apm-agent-java-17 1.35.1-SNAPSHOT - apm-spring-web-6 + apm-agent-spring-6 ${project.groupId}:${project.artifactId} - ${project.basedir}/../../.. - - - true + ${project.basedir}/../.. + + ${project.groupId} + apm-agent-core + ${project.version} + org.springframework spring-web 6.0.1 provided - - ${project.groupId} - apm-spring-webflux-common - ${project.version} - + io.projectreactor reactor-core diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb6Utils.java b/apm-agent-java-17/apm-agent-spring-6/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb6Utils.java similarity index 78% rename from apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb6Utils.java rename to apm-agent-java-17/apm-agent-spring-6/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb6Utils.java index 0bb4b30200..86ed8487d6 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb6Utils.java +++ b/apm-agent-java-17/apm-agent-spring-6/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb6Utils.java @@ -23,12 +23,12 @@ /** * This class is compiled with spring-web 6.x, as it relies on {@link HttpStatusCode} and an API that was introduced in 6.0.0. - * Therefore, it is only loaded through its class name through {@link SpringWebUtilsFactory} + * Therefore, it MUST only be loaded through its class name through {@link SpringWebVersionUtils}. */ -public class SpringWeb6Utils implements SpringWebVersionUtils { +public class SpringWeb6Utils implements SpringWebVersionUtils.ISpringWebVersionUtils { @Override - public int getStatusCode(ServerHttpResponse response) { - HttpStatusCode statusCode = response.getStatusCode(); + public int getStatusCode(Object response) { + HttpStatusCode statusCode = ((ServerHttpResponse) response).getStatusCode(); return statusCode != null ? statusCode.value() : 200; } } diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb6UtilsTest.java b/apm-agent-java-17/apm-agent-spring-6/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb6UtilsTest.java similarity index 78% rename from apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb6UtilsTest.java rename to apm-agent-java-17/apm-agent-spring-6/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb6UtilsTest.java index 21edaf7de2..ab6bff651f 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-web-6/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb6UtilsTest.java +++ b/apm-agent-java-17/apm-agent-spring-6/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb6UtilsTest.java @@ -22,25 +22,22 @@ import org.springframework.http.HttpStatusCode; import org.springframework.http.server.reactive.ServerHttpResponse; -import java.util.Objects; - import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; public class SpringWeb6UtilsTest { - private final SpringWebVersionUtils springWebVersionUtils = Objects.requireNonNull(SpringWebUtilsFactory.getImplementation()); - @Test - void testSpringWebUtilsVersion() { - assertThat(springWebVersionUtils).isInstanceOf(SpringWeb6Utils.class); + void testGetStatusCode() throws Exception { + ServerHttpResponse mockResponse = mock(ServerHttpResponse.class); + doReturn(HttpStatusCode.valueOf(222)).when(mockResponse).getStatusCode(); + assertThat(SpringWebVersionUtils.getStatusCode(mockResponse)).isEqualTo(222); } @Test - void testGetStatusCode() { - ServerHttpResponse mockResponse = mock(ServerHttpResponse.class); - doReturn(HttpStatusCode.valueOf(222)).when(mockResponse).getStatusCode(); - assertThat(springWebVersionUtils.getStatusCode(mockResponse)).isEqualTo(222); + void testWrongResponseType() { + assertThatThrownBy(() -> SpringWebVersionUtils.getStatusCode(new Object())).isInstanceOf(ClassCastException.class); } } diff --git a/apm-agent-java-17/pom.xml b/apm-agent-java-17/pom.xml new file mode 100644 index 0000000000..ceaac15c5f --- /dev/null +++ b/apm-agent-java-17/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + + + apm-agent-parent + co.elastic.apm + 1.35.1-SNAPSHOT + + + apm-agent-java-17 + pom + ${project.groupId}:${project.artifactId} + + + apm-agent-spring-6 + + + + + ${project.basedir}/.. + + + true + + + diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/pom.xml b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/pom.xml deleted file mode 100755 index 1018374f57..0000000000 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/pom.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - 4.0.0 - - - co.elastic.apm - apm-spring-webflux - 1.35.1-SNAPSHOT - - - apm-spring-webflux-common - ${project.groupId}:${project.artifactId} - - - ${project.basedir}/../../.. - - 8 - ${maven.compiler.target} - - true - - - - - org.springframework - spring-web - ${version.spring} - provided - - - io.projectreactor - reactor-core - 3.2.0.RELEASE - test - - - diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactory.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactory.java deleted file mode 100644 index 622f10f35d..0000000000 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactory.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. 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. - */ -package co.elastic.apm.agent.springwebflux; - -import co.elastic.apm.agent.sdk.logging.Logger; -import co.elastic.apm.agent.sdk.logging.LoggerFactory; - -import javax.annotation.Nullable; - -public class SpringWebUtilsFactory { - - private static final String SPRING_WEB_5_UTILS_CLASS_NAME = "co.elastic.apm.agent.springwebflux.SpringWeb5Utils"; - private static final String SPRING_WEB_6_UTILS_CLASS_NAME = "co.elastic.apm.agent.springwebflux.SpringWeb6Utils"; - - private static final Logger logger = LoggerFactory.getLogger(SpringWebUtilsFactory.class); - - @Nullable - private static SpringWebVersionUtils instance = null; - - static { - try { - Class.forName("org.springframework.http.HttpStatusCode"); - try { - // loading class by name so to avoid linkage attempt when spring-web 6 is unavailable - instance = (SpringWebVersionUtils) Class.forName(SPRING_WEB_6_UTILS_CLASS_NAME).getDeclaredConstructor().newInstance(); - logger.debug("Spring-web 6.x+ identified"); - } catch (Exception e) { - logger.error("Spring-web 6.x+ identified, but failed to load related utility class", e); - } - } catch (ClassNotFoundException ignored) { - // assuming spring-web < 6.x - try { - // loading class by name so to avoid linkage attempt on spring-web 6, where the getStatusCode API has changed - instance = (SpringWebVersionUtils) Class.forName(SPRING_WEB_5_UTILS_CLASS_NAME).getDeclaredConstructor().newInstance(); - logger.debug("Spring-web < 6.x identified"); - } catch (Exception e) { - logger.error("Spring-web < 6.x identified, but failed to load related utility class", e); - } - } - } - - @Nullable - public static SpringWebVersionUtils getImplementation() { - return instance; - } -} diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/pom.xml b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/pom.xml index 3b1ebe278b..dbe54a411b 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/pom.xml +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/pom.xml @@ -46,12 +46,6 @@ ${project.version} - - ${project.groupId} - apm-spring-webflux-common - ${project.version} - - co.elastic.apm @@ -98,7 +92,6 @@ test - diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb5Utils.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb5Utils.java similarity index 83% rename from apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb5Utils.java rename to apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb5Utils.java index c3cbed706a..4acda6f375 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb5Utils.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/SpringWeb5Utils.java @@ -23,13 +23,13 @@ /** * This class is compiled with spring-web 5.x, relying on the {@link ServerHttpResponse#getStatusCode()}, which changed in 6.0.0. - * Therefore, it MUST only be loaded through its class name through {@link SpringWebUtilsFactory}. + * Therefore, it MUST only be loaded through its class name through {@link SpringWebVersionUtils}. */ -public class SpringWeb5Utils implements SpringWebVersionUtils { +public class SpringWeb5Utils implements SpringWebVersionUtils.ISpringWebVersionUtils { @Override - public int getStatusCode(ServerHttpResponse response) { - HttpStatus statusCode = response.getStatusCode(); + public int getStatusCode(Object response) { + HttpStatus statusCode = ((ServerHttpResponse) response).getStatusCode(); return statusCode != null ? statusCode.value() : 200; } } diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java index 5c667ec5f5..4b2a31c037 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java @@ -72,9 +72,6 @@ public class WebfluxHelper { private static final HeaderGetter HEADER_GETTER = new HeaderGetter(); - @Nullable - private static final SpringWebVersionUtils springWebVersionUtils = SpringWebUtilsFactory.getImplementation(); - private static final CoreConfiguration coreConfig; private static final WebConfiguration webConfig; private static final HttpServerHelper serverHelper; @@ -272,7 +269,12 @@ private static void fillRequest(Transaction transaction, ServerWebExchange excha private static void fillResponse(Transaction transaction, ServerWebExchange exchange) { ServerHttpResponse serverResponse = exchange.getResponse(); - int status = springWebVersionUtils != null ? springWebVersionUtils.getStatusCode(serverResponse) : 200; + int status = 0; + try { + status = SpringWebVersionUtils.getStatusCode(serverResponse); + } catch (Exception e) { + // todo : log + } transaction.withResultIfUnset(ResultUtil.getResultByHttpStatus(status)); diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactoryTest.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb5UtilsTest.java similarity index 76% rename from apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactoryTest.java rename to apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb5UtilsTest.java index 6b11157d01..f0fb189b42 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-common/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebUtilsFactoryTest.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/test/java/co/elastic/apm/agent/springwebflux/SpringWeb5UtilsTest.java @@ -22,25 +22,22 @@ import org.springframework.http.HttpStatus; import org.springframework.http.server.reactive.ServerHttpResponse; -import java.util.Objects; - import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.mock; -class SpringWebUtilsFactoryTest { - - private final SpringWebVersionUtils springWebVersionUtils = Objects.requireNonNull(SpringWebUtilsFactory.getImplementation()); +class SpringWeb5UtilsTest { @Test - void testSpringWebUtilsVersion() { - assertThat(springWebVersionUtils).isInstanceOf(SpringWeb5Utils.class); + void testGetStatusCode() throws Exception { + ServerHttpResponse mockResponse = mock(ServerHttpResponse.class); + doReturn(HttpStatus.IM_USED).when(mockResponse).getStatusCode(); + assertThat(SpringWebVersionUtils.getStatusCode(mockResponse)).isEqualTo(226); } @Test - void testGetStatusCode() { - ServerHttpResponse mockResponse = mock(ServerHttpResponse.class); - doReturn(HttpStatus.IM_USED).when(mockResponse).getStatusCode(); - assertThat(springWebVersionUtils.getStatusCode(mockResponse)).isEqualTo(226); + void testWrongResponseType() { + assertThatThrownBy(() -> SpringWebVersionUtils.getStatusCode(new Object())).isInstanceOf(ClassCastException.class); } } diff --git a/apm-agent-plugins/apm-spring-webflux/pom.xml b/apm-agent-plugins/apm-spring-webflux/pom.xml index 68167985b7..e520a1ed55 100644 --- a/apm-agent-plugins/apm-spring-webflux/pom.xml +++ b/apm-agent-plugins/apm-spring-webflux/pom.xml @@ -31,7 +31,5 @@ apm-spring-webflux-plugin apm-spring-webclient-plugin apm-spring-webflux-testapp - apm-spring-web-6 - apm-spring-webflux-common diff --git a/apm-agent/pom.xml b/apm-agent/pom.xml index 69330ab13b..1fc768b25f 100644 --- a/apm-agent/pom.xml +++ b/apm-agent/pom.xml @@ -20,7 +20,6 @@ ${project.basedir}/.. - @@ -321,16 +320,6 @@ apm-spring-webflux-plugin ${project.version} - - ${project.groupId} - apm-spring-web-6 - ${project.version} - - - ${project.groupId} - apm-spring-webflux-common - ${project.version} - ${project.groupId} apm-spring-webmvc-plugin @@ -412,6 +401,22 @@ + + + non-java-11 + + !11 + + + + ${project.groupId} + apm-agent-spring-6 + ${project.version} + + + + + diff --git a/pom.xml b/pom.xml index 15f84d6f04..1c50647f6f 100644 --- a/pom.xml +++ b/pom.xml @@ -222,6 +222,17 @@ + + + non-java-11 + + !11 + + + apm-agent-java-17 + + no-errorprone From c18becd4343600c08bdffbd11947ca1a12420913 Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Fri, 30 Dec 2022 08:54:07 +0200 Subject: [PATCH 13/21] Removing a test which is dependent on build order --- .../SpringWebVersionUtilsTest.java | 31 ------------------- 1 file changed, 31 deletions(-) delete mode 100644 apm-agent-core/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtilsTest.java diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtilsTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtilsTest.java deleted file mode 100644 index 6aef87cea1..0000000000 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/springwebflux/SpringWebVersionUtilsTest.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. 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. - */ -package co.elastic.apm.agent.springwebflux; - -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -class SpringWebVersionUtilsTest { - - @Test - void testWrongResponseType() { - assertThatThrownBy(() -> SpringWebVersionUtils.getStatusCode(new Object())).isInstanceOf(IllegalStateException.class); - } -} From 1cecd1d74e4b59ab309c63c2e681d082b6b2be25 Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Tue, 3 Jan 2023 11:37:28 +0200 Subject: [PATCH 14/21] Move Version.class to the proper package --- .../src/main/java/co/elastic/apm/attach/AgentDownloader.java | 2 +- .../test/java/co/elastic/apm/attach/AgentDownloaderTest.java | 2 +- .../java/co/elastic/apm/agent/{ => common}/util/Version.java | 2 +- .../src/test/java/co/elastic/apm/agent/util/VersionTest.java | 1 + .../elastic/apm/agent/bci/bytebuddy/CustomElementMatchers.java | 2 +- .../main/java/co/elastic/apm/agent/report/ApmServerClient.java | 2 +- .../co/elastic/apm/agent/report/ApmServerHealthChecker.java | 2 +- .../src/test/java/co/elastic/apm/agent/MockTracer.java | 2 +- .../java/co/elastic/apm/agent/report/ApmServerClientTest.java | 2 +- .../co/elastic/apm/agent/report/ApmServerHealthCheckerTest.java | 2 +- .../java/co/elastic/apm/agent/mongodb/v4/Mongo4VersionIT.java | 2 +- .../apm/agent/okhttp/OkHttp3ClientAsyncInstrumentationTest.java | 2 +- .../apm/agent/okhttp/OkHttp3ClientInstrumentationTest.java | 2 +- 13 files changed, 13 insertions(+), 12 deletions(-) rename apm-agent-common/src/main/java/co/elastic/apm/agent/{ => common}/util/Version.java (98%) diff --git a/apm-agent-attach-cli/src/main/java/co/elastic/apm/attach/AgentDownloader.java b/apm-agent-attach-cli/src/main/java/co/elastic/apm/attach/AgentDownloader.java index bf6c435f53..a1e7c7e66e 100644 --- a/apm-agent-attach-cli/src/main/java/co/elastic/apm/attach/AgentDownloader.java +++ b/apm-agent-attach-cli/src/main/java/co/elastic/apm/attach/AgentDownloader.java @@ -18,7 +18,7 @@ */ package co.elastic.apm.attach; -import co.elastic.apm.agent.util.Version; +import co.elastic.apm.agent.common.util.Version; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; diff --git a/apm-agent-attach-cli/src/test/java/co/elastic/apm/attach/AgentDownloaderTest.java b/apm-agent-attach-cli/src/test/java/co/elastic/apm/attach/AgentDownloaderTest.java index ac9a08fa21..6b4b2c0271 100644 --- a/apm-agent-attach-cli/src/test/java/co/elastic/apm/attach/AgentDownloaderTest.java +++ b/apm-agent-attach-cli/src/test/java/co/elastic/apm/attach/AgentDownloaderTest.java @@ -18,7 +18,7 @@ */ package co.elastic.apm.attach; -import co.elastic.apm.agent.util.Version; +import co.elastic.apm.agent.common.util.Version; import co.elastic.apm.attach.bouncycastle.BouncyCastleVerifier; import org.junit.jupiter.api.Test; diff --git a/apm-agent-common/src/main/java/co/elastic/apm/agent/util/Version.java b/apm-agent-common/src/main/java/co/elastic/apm/agent/common/util/Version.java similarity index 98% rename from apm-agent-common/src/main/java/co/elastic/apm/agent/util/Version.java rename to apm-agent-common/src/main/java/co/elastic/apm/agent/common/util/Version.java index 49436f1f9e..ac92153e2d 100644 --- a/apm-agent-common/src/main/java/co/elastic/apm/agent/util/Version.java +++ b/apm-agent-common/src/main/java/co/elastic/apm/agent/common/util/Version.java @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -package co.elastic.apm.agent.util; +package co.elastic.apm.agent.common.util; import java.util.Arrays; import java.util.Objects; diff --git a/apm-agent-common/src/test/java/co/elastic/apm/agent/util/VersionTest.java b/apm-agent-common/src/test/java/co/elastic/apm/agent/util/VersionTest.java index 5c5e79b620..baf7011db9 100644 --- a/apm-agent-common/src/test/java/co/elastic/apm/agent/util/VersionTest.java +++ b/apm-agent-common/src/test/java/co/elastic/apm/agent/util/VersionTest.java @@ -18,6 +18,7 @@ */ package co.elastic.apm.agent.util; +import co.elastic.apm.agent.common.util.Version; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.CsvSource; diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/bytebuddy/CustomElementMatchers.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/bytebuddy/CustomElementMatchers.java index 27b023cf17..113322d130 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/bytebuddy/CustomElementMatchers.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/bci/bytebuddy/CustomElementMatchers.java @@ -23,7 +23,7 @@ import co.elastic.apm.agent.sdk.weakconcurrent.WeakConcurrent; import co.elastic.apm.agent.sdk.weakconcurrent.WeakMap; import co.elastic.apm.agent.util.ClassLoaderUtils; -import co.elastic.apm.agent.util.Version; +import co.elastic.apm.agent.common.util.Version; import net.bytebuddy.description.NamedElement; import net.bytebuddy.description.annotation.AnnotationSource; import net.bytebuddy.description.method.MethodDescription; diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/ApmServerClient.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/ApmServerClient.java index e218009679..c781ddfb31 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/ApmServerClient.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/ApmServerClient.java @@ -21,7 +21,7 @@ import co.elastic.apm.agent.configuration.CoreConfiguration; import co.elastic.apm.agent.report.ssl.SslUtils; import co.elastic.apm.agent.util.UrlConnectionUtils; -import co.elastic.apm.agent.util.Version; +import co.elastic.apm.agent.common.util.Version; import co.elastic.apm.agent.util.VersionUtils; import co.elastic.apm.agent.sdk.logging.Logger; import co.elastic.apm.agent.sdk.logging.LoggerFactory; diff --git a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/ApmServerHealthChecker.java b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/ApmServerHealthChecker.java index f0f3213800..275ebd07d1 100644 --- a/apm-agent-core/src/main/java/co/elastic/apm/agent/report/ApmServerHealthChecker.java +++ b/apm-agent-core/src/main/java/co/elastic/apm/agent/report/ApmServerHealthChecker.java @@ -19,7 +19,7 @@ package co.elastic.apm.agent.report; import co.elastic.apm.agent.util.ExecutorUtils; -import co.elastic.apm.agent.util.Version; +import co.elastic.apm.agent.common.util.Version; import com.dslplatform.json.DslJson; import com.dslplatform.json.JsonReader; import com.dslplatform.json.Nullable; diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/MockTracer.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/MockTracer.java index 5af6fc9d5e..f8f68d9b75 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/MockTracer.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/MockTracer.java @@ -25,7 +25,7 @@ import co.elastic.apm.agent.objectpool.TestObjectPoolFactory; import co.elastic.apm.agent.report.ApmServerClient; import co.elastic.apm.agent.report.Reporter; -import co.elastic.apm.agent.util.Version; +import co.elastic.apm.agent.common.util.Version; import org.stagemonitor.configuration.ConfigurationRegistry; import static org.mockito.ArgumentMatchers.any; diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/report/ApmServerClientTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/report/ApmServerClientTest.java index c93cca079d..27efb39e60 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/report/ApmServerClientTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/report/ApmServerClientTest.java @@ -29,7 +29,7 @@ import co.elastic.apm.agent.impl.transaction.Transaction; import co.elastic.apm.agent.objectpool.TestObjectPoolFactory; import co.elastic.apm.agent.objectpool.impl.BookkeeperObjectPool; -import co.elastic.apm.agent.util.Version; +import co.elastic.apm.agent.common.util.Version; import com.github.tomakehurst.wiremock.core.WireMockConfiguration; import com.github.tomakehurst.wiremock.junit.WireMockRule; import org.assertj.core.util.Lists; diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/report/ApmServerHealthCheckerTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/report/ApmServerHealthCheckerTest.java index 9056e66241..51e5ef978e 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/report/ApmServerHealthCheckerTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/report/ApmServerHealthCheckerTest.java @@ -18,7 +18,7 @@ */ package co.elastic.apm.agent.report; -import co.elastic.apm.agent.util.Version; +import co.elastic.apm.agent.common.util.Version; import org.junit.jupiter.api.Test; import java.io.IOException; diff --git a/apm-agent-plugins/apm-mongodb/apm-mongodb4-plugin/src/test/java/co/elastic/apm/agent/mongodb/v4/Mongo4VersionIT.java b/apm-agent-plugins/apm-mongodb/apm-mongodb4-plugin/src/test/java/co/elastic/apm/agent/mongodb/v4/Mongo4VersionIT.java index 9e1f31e8cd..fb5fa23490 100644 --- a/apm-agent-plugins/apm-mongodb/apm-mongodb4-plugin/src/test/java/co/elastic/apm/agent/mongodb/v4/Mongo4VersionIT.java +++ b/apm-agent-plugins/apm-mongodb/apm-mongodb4-plugin/src/test/java/co/elastic/apm/agent/mongodb/v4/Mongo4VersionIT.java @@ -20,7 +20,7 @@ import co.elastic.apm.agent.TestClassWithDependencyRunner; import co.elastic.apm.agent.mongodb.AbstractMongoClientInstrumentationIT; -import co.elastic.apm.agent.util.Version; +import co.elastic.apm.agent.common.util.Version; import org.junit.After; import org.junit.Test; import org.junit.runner.RunWith; diff --git a/apm-agent-plugins/apm-okhttp-plugin/src/test/java/co/elastic/apm/agent/okhttp/OkHttp3ClientAsyncInstrumentationTest.java b/apm-agent-plugins/apm-okhttp-plugin/src/test/java/co/elastic/apm/agent/okhttp/OkHttp3ClientAsyncInstrumentationTest.java index 9ad9677662..45a3463e70 100644 --- a/apm-agent-plugins/apm-okhttp-plugin/src/test/java/co/elastic/apm/agent/okhttp/OkHttp3ClientAsyncInstrumentationTest.java +++ b/apm-agent-plugins/apm-okhttp-plugin/src/test/java/co/elastic/apm/agent/okhttp/OkHttp3ClientAsyncInstrumentationTest.java @@ -19,7 +19,7 @@ package co.elastic.apm.agent.okhttp; import co.elastic.apm.agent.httpclient.AbstractHttpClientInstrumentationTest; -import co.elastic.apm.agent.util.Version; +import co.elastic.apm.agent.common.util.Version; import co.elastic.apm.agent.util.VersionUtils; import okhttp3.Call; import okhttp3.Callback; diff --git a/apm-agent-plugins/apm-okhttp-plugin/src/test/java/co/elastic/apm/agent/okhttp/OkHttp3ClientInstrumentationTest.java b/apm-agent-plugins/apm-okhttp-plugin/src/test/java/co/elastic/apm/agent/okhttp/OkHttp3ClientInstrumentationTest.java index ab4281c688..3608f1f142 100644 --- a/apm-agent-plugins/apm-okhttp-plugin/src/test/java/co/elastic/apm/agent/okhttp/OkHttp3ClientInstrumentationTest.java +++ b/apm-agent-plugins/apm-okhttp-plugin/src/test/java/co/elastic/apm/agent/okhttp/OkHttp3ClientInstrumentationTest.java @@ -19,7 +19,7 @@ package co.elastic.apm.agent.okhttp; import co.elastic.apm.agent.httpclient.AbstractHttpClientInstrumentationTest; -import co.elastic.apm.agent.util.Version; +import co.elastic.apm.agent.common.util.Version; import co.elastic.apm.agent.util.VersionUtils; import okhttp3.OkHttpClient; import okhttp3.Request; From 38e1602668b820ad41f5ca60b087e0cb5db97122 Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Tue, 3 Jan 2023 11:46:59 +0200 Subject: [PATCH 15/21] Fix Compatibility JDKs stage --- Jenkinsfile | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 98e0d9eea0..6f50135603 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -362,9 +362,6 @@ pipeline { } } } - environment { - PATH = "${env.JAVA_HOME}/bin:${env.PATH}" - } matrix { agent { label 'linux && immutable' } axes { @@ -377,6 +374,10 @@ pipeline { } stages { stage('JDK Unit Tests') { + environment { + JAVA_HOME = "${env.HUDSON_HOME}/.java/${env.JDK_VERSION}" + PATH = "${env.JAVA_HOME}/bin:${env.PATH}" + } steps { withGithubNotify(context: "${STAGE_NAME} ${JDK_VERSION}", tab: 'tests') { deleteDir() From c8c83ab5c46b1cd154278b38d7bdfa3bb489c9c3 Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Tue, 3 Jan 2023 14:43:46 +0200 Subject: [PATCH 16/21] Restore single line in Jenkinsfile --- .ci/load/Jenkinsfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.ci/load/Jenkinsfile b/.ci/load/Jenkinsfile index a98b6c8f36..8aa328a5fb 100644 --- a/.ci/load/Jenkinsfile +++ b/.ci/load/Jenkinsfile @@ -82,8 +82,7 @@ pipeline { sh(script: "git checkout ${params.apm_version}") echo 'Building agent with Java 17' - sh(script: "JAVA_HOME=${env.HUDSON_HOME}/.java/jdk17 ./mvnw --batch-mode clean package -DskipTests=true -Dmaven.javadoc - .skip=true -Dmaven.sources.skip=true") + sh(script: "JAVA_HOME=${env.HUDSON_HOME}/.java/jdk17 ./mvnw --batch-mode clean package -DskipTests=true -Dmaven.javadoc.skip=true -Dmaven.sources.skip=true") // copy agent jar to a known filename that don't change with version sh(script: "cp -v \$(find ./elastic-apm-agent/target -name '*.jar' | grep -v sources | grep -v original | grep -v javadoc) ${WORKSPACE}/elastic-apm-agent.jar") From 5c475f962797004f1a392e7b59deb739c7ebe66f Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Tue, 3 Jan 2023 14:51:36 +0200 Subject: [PATCH 17/21] Use Oracle instead of OpenJDK for Java 11 test --- Jenkinsfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Jenkinsfile b/Jenkinsfile index 6f50135603..eee6c76bdf 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -369,7 +369,7 @@ pipeline { // the list of support java versions can be found in the infra repo (ansible/roles/java/defaults/main.yml) name 'JDK_VERSION' // todo: upgrade jacoco and try adding "jdk19" - values 'jdk11' + values 'java11' } } stages { From 5a434e74b15bd865c564609aca136deb60073c34 Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Wed, 4 Jan 2023 08:04:49 +0200 Subject: [PATCH 18/21] Enable build on JDK 19 --- Jenkinsfile | 5 ++--- .../apm/agent/util/PrivilegedActionUtilsTest.java | 4 +++- apm-agent-plugins/apm-dubbo-plugin/pom.xml | 13 +++++++++++++ apm-agent-plugins/apm-javalin-plugin/pom.xml | 12 ++++++++++++ pom.xml | 2 +- 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index eee6c76bdf..a9b3388e71 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -366,10 +366,9 @@ pipeline { agent { label 'linux && immutable' } axes { axis { - // the list of support java versions can be found in the infra repo (ansible/roles/java/defaults/main.yml) + // the list of supported java versions can be found in the infra repo (ansible/roles/java/defaults/main.yml) name 'JDK_VERSION' - // todo: upgrade jacoco and try adding "jdk19" - values 'java11' + values 'java11', 'jdk19' } } stages { diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/util/PrivilegedActionUtilsTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/util/PrivilegedActionUtilsTest.java index ba7ca695bc..a4dfd53dda 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/util/PrivilegedActionUtilsTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/util/PrivilegedActionUtilsTest.java @@ -19,12 +19,13 @@ package co.elastic.apm.agent.util; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledForJreRange; +import org.junit.jupiter.api.condition.JRE; import org.junit.jupiter.api.io.TempDir; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.nio.file.FileAlreadyExistsException; import java.nio.file.Files; import java.nio.file.Path; import java.security.AccessController; @@ -37,6 +38,7 @@ import static co.elastic.apm.agent.testutils.assertions.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +@EnabledForJreRange(max = JRE.JAVA_17, disabledReason = "SecurityManager is not supported anymore") class PrivilegedActionUtilsTest { private static final AtomicBoolean enabled = new AtomicBoolean(false); diff --git a/apm-agent-plugins/apm-dubbo-plugin/pom.xml b/apm-agent-plugins/apm-dubbo-plugin/pom.xml index 8600daf4aa..7baa24ffa3 100644 --- a/apm-agent-plugins/apm-dubbo-plugin/pom.xml +++ b/apm-agent-plugins/apm-dubbo-plugin/pom.xml @@ -55,4 +55,17 @@ test + + + + + maven-surefire-plugin + + + --add-opens java.base/java.lang=ALL-UNNAMED + + + + + diff --git a/apm-agent-plugins/apm-javalin-plugin/pom.xml b/apm-agent-plugins/apm-javalin-plugin/pom.xml index 6c566756fb..1226310543 100644 --- a/apm-agent-plugins/apm-javalin-plugin/pom.xml +++ b/apm-agent-plugins/apm-javalin-plugin/pom.xml @@ -57,4 +57,16 @@ + + + + maven-surefire-plugin + + + --enable-preview + + + + + diff --git a/pom.xml b/pom.xml index 1c50647f6f..26b316a029 100644 --- a/pom.xml +++ b/pom.xml @@ -532,7 +532,7 @@ org.jacoco jacoco-maven-plugin - 0.8.7 + 0.8.8 org.codehaus.mojo From 31ab68814f0aff33f0f36af3b887a9d66ad8f5de Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Mon, 23 Jan 2023 17:02:07 +0200 Subject: [PATCH 19/21] Logging response code fetch error --- .../co/elastic/apm/agent/springwebflux/WebfluxHelper.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java index 4b2a31c037..aaeba84ea1 100644 --- a/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java +++ b/apm-agent-plugins/apm-spring-webflux/apm-spring-webflux-plugin/src/main/java/co/elastic/apm/agent/springwebflux/WebfluxHelper.java @@ -31,6 +31,7 @@ import co.elastic.apm.agent.sdk.logging.LoggerFactory; import co.elastic.apm.agent.sdk.weakconcurrent.WeakConcurrent; import co.elastic.apm.agent.sdk.weakconcurrent.WeakMap; +import co.elastic.apm.agent.util.LoggerUtils; import co.elastic.apm.agent.util.PotentiallyMultiValuedMap; import co.elastic.apm.agent.util.PrivilegedActionUtils; import co.elastic.apm.agent.util.TransactionNameUtils; @@ -63,6 +64,7 @@ public class WebfluxHelper { private static final Logger log = LoggerFactory.getLogger(WebfluxHelper.class); + private static final Logger oneTimeResponseCodeErrorLogger = LoggerUtils.logOnce(log); public static final String TRANSACTION_ATTRIBUTE = WebfluxHelper.class.getName() + ".transaction"; private static final String SUBSCRIBER_ATTRIBUTE = WebfluxHelper.class.getName() + ".wrapped_subscriber"; @@ -273,7 +275,7 @@ private static void fillResponse(Transaction transaction, ServerWebExchange exch try { status = SpringWebVersionUtils.getStatusCode(serverResponse); } catch (Exception e) { - // todo : log + oneTimeResponseCodeErrorLogger.error("Failed to get response code", e); } transaction.withResultIfUnset(ResultUtil.getResultByHttpStatus(status)); From a68fe5af016985e7848f38a752ae52ef88f4cc01 Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Mon, 23 Jan 2023 17:07:33 +0200 Subject: [PATCH 20/21] Add to CHANGELOG --- CHANGELOG.asciidoc | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc index d353a36928..b439e5fb93 100644 --- a/CHANGELOG.asciidoc +++ b/CHANGELOG.asciidoc @@ -34,6 +34,7 @@ endif::[] * Fix some span-compression concurrency issues - {pull}2865[#2865] * Add warning when agent is accidentally started on a JVM/JDK command-line tool - {pull}2924[#2924] * Fix `NullPointerException` caused by the Elasticsearch REST client instrumentation when collecting dropped span metrics - {pull}2959[#2959] +* Fix `java.lang.NoSuchMethodError` when using the agent with WebFlux and Spring 6.x/Spring Boot 3.x - {pull}2935[#2935] ===== Potentially breaking changes From 8ef82a6db7fcbf9326ac0f76d1a653a93d02e234 Mon Sep 17 00:00:00 2001 From: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Date: Mon, 23 Jan 2023 17:41:58 +0200 Subject: [PATCH 21/21] fix wrong import from merging --- .../apm/agent/report/IntakeV2ReportingEventHandlerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apm-agent-core/src/test/java/co/elastic/apm/agent/report/IntakeV2ReportingEventHandlerTest.java b/apm-agent-core/src/test/java/co/elastic/apm/agent/report/IntakeV2ReportingEventHandlerTest.java index dcb2285dd1..9da16bce93 100644 --- a/apm-agent-core/src/test/java/co/elastic/apm/agent/report/IntakeV2ReportingEventHandlerTest.java +++ b/apm-agent-core/src/test/java/co/elastic/apm/agent/report/IntakeV2ReportingEventHandlerTest.java @@ -31,7 +31,7 @@ import co.elastic.apm.agent.impl.transaction.Transaction; import co.elastic.apm.agent.report.processor.ProcessorEventHandler; import co.elastic.apm.agent.report.serialize.DslJsonSerializer; -import co.elastic.apm.agent.util.Version; +import co.elastic.apm.agent.common.util.Version; import com.dslplatform.json.DslJson; import com.dslplatform.json.JsonWriter; import com.fasterxml.jackson.databind.JsonNode;