diff --git a/apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-plugin/pom.xml b/apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-plugin/pom.xml
index d50747f701..14fc5539a6 100644
--- a/apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-plugin/pom.xml
+++ b/apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-plugin/pom.xml
@@ -13,13 +13,26 @@
${project.basedir}/../../..
+ true
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ 3.0.5
+ pom
+ import
+
+
+
+
org.springframework
spring-webmvc
- ${version.spring}
provided
@@ -38,7 +51,6 @@
com.squareup.okhttp3
okhttp
- ${version.okhttp}
test
@@ -48,9 +60,8 @@
test
- org.apache.httpcomponents
- httpclient
- 4.3.6
+ org.apache.httpcomponents.client5
+ httpclient5
test
diff --git a/apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-plugin/src/test/java/co/elastic/apm/agent/resttemplate/SpringRestTemplateInstrumentationTest.java b/apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-plugin/src/test/java/co/elastic/apm/agent/resttemplate/SpringRestTemplateInstrumentationTest.java
index 9bc79292ad..29bc51f423 100644
--- a/apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-plugin/src/test/java/co/elastic/apm/agent/resttemplate/SpringRestTemplateInstrumentationTest.java
+++ b/apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-plugin/src/test/java/co/elastic/apm/agent/resttemplate/SpringRestTemplateInstrumentationTest.java
@@ -18,6 +18,7 @@
*/
package co.elastic.apm.agent.resttemplate;
+import co.elastic.apm.agent.common.JvmRuntimeInfo;
import co.elastic.apm.agent.httpclient.AbstractHttpClientInstrumentationTest;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -27,29 +28,52 @@
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
-import java.util.Arrays;
+import java.util.List;
import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
@RunWith(Parameterized.class)
public class SpringRestTemplateInstrumentationTest extends AbstractHttpClientInstrumentationTest {
- private final RestTemplate restTemplate;
+ // Cannot directly reference RestTemplate here because it is compiled with Java 17
+ private final Object restTemplate;
- public SpringRestTemplateInstrumentationTest(Supplier supplier) {
- restTemplate = new RestTemplate(supplier.get());
+ public SpringRestTemplateInstrumentationTest(Supplier supplier) {
+ restTemplate = supplier.get();
}
@Parameterized.Parameters()
- public static Iterable> data() {
- return Arrays.asList(
- SimpleClientHttpRequestFactory::new,
- OkHttp3ClientHttpRequestFactory::new,
- HttpComponentsClientHttpRequestFactory::new);
+ public static Iterable> data() {
+ if (JvmRuntimeInfo.ofCurrentVM().getMajorVersion() >= 17) {
+ return Java17Code.getRestTemplateFactories();
+ } else {
+ return List.of();
+ }
}
@Override
protected void performGet(String path) {
- // note: getForEntity is only available as of Spring-web 3.0.2
- restTemplate.getForEntity(path, String.class);
+ Java17Code.performGet(restTemplate, path);
+ }
+
+ /**
+ * The code is compiled with java 17 but potentially run with java 11.
+ * JUnit will inspect the test class, therefore it must not contain any references to java 17 code.
+ */
+ private static class Java17Code {
+ public static void performGet(Object restTemplate, String path) {
+ // note: getForEntity is only available as of Spring-web 3.0.2
+ ((RestTemplate) restTemplate).getForEntity(path, String.class);
+ }
+
+ public static Iterable> getRestTemplateFactories() {
+ return Stream.>of(
+ SimpleClientHttpRequestFactory::new,
+ OkHttp3ClientHttpRequestFactory::new,
+ HttpComponentsClientHttpRequestFactory::new)
+ .map(fac -> (Supplier) (() -> new RestTemplate(fac.get())))
+ .collect(Collectors.toList());
+ }
}
}
diff --git a/apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-test/src/test/java/co/elastic/apm/agent/resttemplate/SpringRestTemplateVersionsIT.java b/apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-test/src/test/java/co/elastic/apm/agent/resttemplate/SpringRestTemplateVersionsIT.java
index c26a569233..cbbf5dc06c 100644
--- a/apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-test/src/test/java/co/elastic/apm/agent/resttemplate/SpringRestTemplateVersionsIT.java
+++ b/apm-agent-plugins/apm-spring-resttemplate/apm-spring-resttemplate-test/src/test/java/co/elastic/apm/agent/resttemplate/SpringRestTemplateVersionsIT.java
@@ -83,7 +83,7 @@ void testVersion5(String version) throws Exception {
@ParameterizedTest
@ValueSource(strings = {
- "[6.0.0,7.0.0)" // using ivy range specifier to make test against later versions
+ "6.0.5"
})
@EnabledForJreRange(min = JRE.JAVA_17, disabledReason = "Spring 6 requires JDK 17")
void testVersion6(String version) throws Exception {
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 4aba510eaa..26369d2aee 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -28,6 +28,7 @@
runtime-attach
jakartaee-jsf-app
main-app-test
+ spring-boot-3
aws-lambda-test
diff --git a/integration-tests/spring-boot-2/pom.xml b/integration-tests/spring-boot-2/pom.xml
index 50a480e04a..e02355e2cc 100644
--- a/integration-tests/spring-boot-2/pom.xml
+++ b/integration-tests/spring-boot-2/pom.xml
@@ -21,10 +21,23 @@
- 2.1.8.RELEASE
${project.basedir}/../..
+ true
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ 2.7.10
+ pom
+ import
+
+
+
+
${project.groupId}
@@ -57,4 +70,19 @@
+
+
+
+ maven-jar-plugin
+
+
+
+ test-jar
+
+
+
+
+
+
+
diff --git a/integration-tests/spring-boot-2/spring-boot-2-base/pom.xml b/integration-tests/spring-boot-2/spring-boot-2-base/pom.xml
index 96205fba37..e24073ae92 100644
--- a/integration-tests/spring-boot-2/spring-boot-2-base/pom.xml
+++ b/integration-tests/spring-boot-2/spring-boot-2-base/pom.xml
@@ -16,26 +16,10 @@
${project.basedir}/../../..
-
-
-
- maven-jar-plugin
-
-
-
- test-jar
-
-
-
-
-
-
-
org.springframework.boot
spring-boot-starter-web
- ${version.spring-boot}
@@ -47,17 +31,14 @@
org.springframework.boot
spring-boot-starter-log4j2
- ${version.spring-boot}
org.springframework.boot
spring-boot-starter-security
- ${version.spring-boot}
org.springframework.boot
spring-boot-starter-test
- ${version.spring-boot}
diff --git a/integration-tests/spring-boot-2/spring-boot-2-base/src/test/java/co/elastic/apm/spring/boot/AbstractSpringBootTest.java b/integration-tests/spring-boot-2/spring-boot-2-base/src/test/java/co/elastic/apm/spring/boot/AbstractSpringBootTest.java
index a5b5a7e5cd..3551cf1957 100644
--- a/integration-tests/spring-boot-2/spring-boot-2-base/src/test/java/co/elastic/apm/spring/boot/AbstractSpringBootTest.java
+++ b/integration-tests/spring-boot-2/spring-boot-2-base/src/test/java/co/elastic/apm/spring/boot/AbstractSpringBootTest.java
@@ -35,21 +35,21 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
+import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.boot.web.client.RestTemplateBuilder;
-import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
-import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
+import org.springframework.security.web.SecurityFilterChain;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.stagemonitor.configuration.ConfigurationRegistry;
+import java.time.Duration;
import java.util.Collections;
import static org.assertj.core.api.Java6Assertions.assertThat;
@@ -78,9 +78,9 @@ public static void beforeClass() {
public void setUp() {
doReturn(true).when(config.getConfig(ReporterConfiguration.class)).isReportSynchronously();
restTemplate = new TestRestTemplate(new RestTemplateBuilder()
- .setConnectTimeout(0)
- .setReadTimeout(0)
- .basicAuthorization("username", "password"));
+ .setConnectTimeout(Duration.ZERO)
+ .setReadTimeout(Duration.ZERO)
+ .basicAuthentication("username", "password"));
reporter.reset();
}
@@ -106,7 +106,11 @@ public void greetingShouldReturnDefaultMessage() throws Exception {
// the service.name will not be overwritten for the webapp class loader based on spring.application.name
assertThat(transaction.getTraceContext().getServiceName()).isNull();
assertThat(transaction.getFrameworkName()).isEqualTo("Spring Web MVC");
- assertThat(transaction.getFrameworkVersion()).isEqualTo("5.1.9.RELEASE");
+ assertThat(transaction.getFrameworkVersion()).matches(getExpectedSpringVersionRegex());
+ }
+
+ protected String getExpectedSpringVersionRegex() {
+ return "5\\.[0-9]+\\.[0-9]+";
}
@Test
@@ -122,6 +126,7 @@ public void testStaticFile() {
@RestController
@SpringBootApplication
+ @EnableWebSecurity
public static class TestApp {
public static void main(String[] args) {
@@ -134,26 +139,22 @@ public String greeting() {
return "Hello World";
}
- @Configuration
- @EnableWebSecurity
- public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
- @Override
- protected void configure(HttpSecurity http) throws Exception {
- http.authorizeRequests()
- .anyRequest().authenticated()
- .and()
- .httpBasic();
- }
-
- @Bean
- @Override
- public UserDetailsService userDetailsService() {
- return new InMemoryUserDetailsManager(User.withDefaultPasswordEncoder()
- .username("username")
- .password("password")
- .roles("USER")
- .build());
- }
+ @Bean
+ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
+ http.authorizeRequests()
+ .anyRequest().authenticated()
+ .and()
+ .httpBasic();
+ return http.build();
+ }
+
+ @Bean
+ public UserDetailsService userDetailsService() {
+ return new InMemoryUserDetailsManager(User.withDefaultPasswordEncoder()
+ .username("username")
+ .password("password")
+ .roles("USER")
+ .build());
}
}
diff --git a/integration-tests/spring-boot-2/spring-boot-2-jetty/pom.xml b/integration-tests/spring-boot-2/spring-boot-2-jetty/pom.xml
index 08b16d03ef..0dd5a5d042 100644
--- a/integration-tests/spring-boot-2/spring-boot-2-jetty/pom.xml
+++ b/integration-tests/spring-boot-2/spring-boot-2-jetty/pom.xml
@@ -34,7 +34,6 @@
org.springframework.boot
spring-boot-starter-jetty
- ${version.spring-boot}
diff --git a/integration-tests/spring-boot-2/spring-boot-2-undertow/pom.xml b/integration-tests/spring-boot-2/spring-boot-2-undertow/pom.xml
index d7af2b6c85..bda6b56e52 100644
--- a/integration-tests/spring-boot-2/spring-boot-2-undertow/pom.xml
+++ b/integration-tests/spring-boot-2/spring-boot-2-undertow/pom.xml
@@ -34,7 +34,6 @@
org.springframework.boot
spring-boot-starter-undertow
- ${version.spring-boot}
diff --git a/integration-tests/spring-boot-3/pom.xml b/integration-tests/spring-boot-3/pom.xml
new file mode 100644
index 0000000000..cb414d037e
--- /dev/null
+++ b/integration-tests/spring-boot-3/pom.xml
@@ -0,0 +1,72 @@
+
+
+ 4.0.0
+
+
+ integration-tests
+ co.elastic.apm
+ 1.38.1-SNAPSHOT
+
+
+ spring-boot-3
+ pom
+
+ ${project.groupId}:${project.artifactId}
+
+
+ spring-boot-3-jetty
+ spring-boot-3-tomcat
+ spring-boot-3-undertow
+
+
+
+ ${project.basedir}/../..
+ true
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-dependencies
+ 3.0.5
+ pom
+ import
+
+
+
+
+
+
+ ${project.groupId}
+ apm-agent-core
+ test-jar
+ ${project.version}
+ test
+
+
+
+ ${project.groupId}
+ apm-spring-webmvc-plugin
+ ${project.version}
+
+
+ ${project.groupId}
+ apm-servlet-plugin
+ ${project.version}
+
+
+ ${project.groupId}
+ apm-api-plugin
+ ${project.version}
+
+
+ ${project.groupId}
+ apm-agent-api
+ ${project.version}
+ test
+
+
+
diff --git a/integration-tests/spring-boot-3/spring-boot-3-jetty/pom.xml b/integration-tests/spring-boot-3/spring-boot-3-jetty/pom.xml
new file mode 100644
index 0000000000..9a96c587f5
--- /dev/null
+++ b/integration-tests/spring-boot-3/spring-boot-3-jetty/pom.xml
@@ -0,0 +1,49 @@
+
+
+
+ spring-boot-3
+ co.elastic.apm
+ 1.38.1-SNAPSHOT
+
+ 4.0.0
+
+ spring-boot-3-jetty
+
+ ${project.groupId}:${project.artifactId}
+
+
+ ${project.basedir}/../../..
+
+
+
+
+ jakarta.servlet
+ jakarta.servlet-api
+ 5.0.0
+
+
+ ${project.groupId}
+ spring-boot-2-base
+ ${project.version}
+ test-jar
+ test
+
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+
+
+
+
+ ${project.groupId}
+ spring-boot-2-jetty
+ ${project.version}
+ test-jar
+ test
+
+
+
+
diff --git a/integration-tests/spring-boot-3/spring-boot-3-jetty/src/test/java/co/elastic/apm/spring/boot/SpringBoot3JettyIT.java b/integration-tests/spring-boot-3/spring-boot-3-jetty/src/test/java/co/elastic/apm/spring/boot/SpringBoot3JettyIT.java
new file mode 100644
index 0000000000..fb5fdc0c30
--- /dev/null
+++ b/integration-tests/spring-boot-3/spring-boot-3-jetty/src/test/java/co/elastic/apm/spring/boot/SpringBoot3JettyIT.java
@@ -0,0 +1,27 @@
+/*
+ * 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.spring.boot;
+
+public class SpringBoot3JettyIT extends SpringBootJettyIT {
+
+ @Override
+ protected String getExpectedSpringVersionRegex() {
+ return "6\\.[0-9]+\\.[0-9]+";
+ }
+}
diff --git a/integration-tests/spring-boot-3/spring-boot-3-tomcat/pom.xml b/integration-tests/spring-boot-3/spring-boot-3-tomcat/pom.xml
new file mode 100644
index 0000000000..8db3b92a24
--- /dev/null
+++ b/integration-tests/spring-boot-3/spring-boot-3-tomcat/pom.xml
@@ -0,0 +1,37 @@
+
+
+
+ spring-boot-3
+ co.elastic.apm
+ 1.38.1-SNAPSHOT
+
+ 4.0.0
+
+ spring-boot-3-tomcat
+
+ ${project.groupId}:${project.artifactId}
+
+
+ ${project.basedir}/../../..
+
+
+
+
+ ${project.groupId}
+ spring-boot-2-base
+ ${project.version}
+ test-jar
+ test
+
+
+ ${project.groupId}
+ spring-boot-2-tomcat
+ ${project.version}
+ test-jar
+ test
+
+
+
+
diff --git a/integration-tests/spring-boot-3/spring-boot-3-tomcat/src/test/java/co/elastic/apm/spring/boot/SpringBoot3TomcatIT.java b/integration-tests/spring-boot-3/spring-boot-3-tomcat/src/test/java/co/elastic/apm/spring/boot/SpringBoot3TomcatIT.java
new file mode 100644
index 0000000000..dc0798243b
--- /dev/null
+++ b/integration-tests/spring-boot-3/spring-boot-3-tomcat/src/test/java/co/elastic/apm/spring/boot/SpringBoot3TomcatIT.java
@@ -0,0 +1,27 @@
+/*
+ * 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.spring.boot;
+
+public class SpringBoot3TomcatIT extends SpringBootTomcatIT {
+
+ @Override
+ protected String getExpectedSpringVersionRegex() {
+ return "6\\.[0-9]+\\.[0-9]+";
+ }
+}
diff --git a/integration-tests/spring-boot-3/spring-boot-3-undertow/pom.xml b/integration-tests/spring-boot-3/spring-boot-3-undertow/pom.xml
new file mode 100644
index 0000000000..edde6f8d79
--- /dev/null
+++ b/integration-tests/spring-boot-3/spring-boot-3-undertow/pom.xml
@@ -0,0 +1,44 @@
+
+
+
+ spring-boot-3
+ co.elastic.apm
+ 1.38.1-SNAPSHOT
+
+ 4.0.0
+
+ spring-boot-3-undertow
+
+ ${project.groupId}:${project.artifactId}
+
+
+ ${project.basedir}/../../..
+
+
+
+
+ ${project.groupId}
+ spring-boot-2-base
+ ${project.version}
+ test-jar
+ test
+
+
+
+ org.springframework.boot
+ spring-boot-starter-tomcat
+
+
+
+
+ ${project.groupId}
+ spring-boot-2-undertow
+ ${project.version}
+ test-jar
+ test
+
+
+
+
diff --git a/integration-tests/spring-boot-3/spring-boot-3-undertow/src/test/java/co/elastic/apm/spring/boot/SpringBoot3UndertowIT.java b/integration-tests/spring-boot-3/spring-boot-3-undertow/src/test/java/co/elastic/apm/spring/boot/SpringBoot3UndertowIT.java
new file mode 100644
index 0000000000..41320c3a5c
--- /dev/null
+++ b/integration-tests/spring-boot-3/spring-boot-3-undertow/src/test/java/co/elastic/apm/spring/boot/SpringBoot3UndertowIT.java
@@ -0,0 +1,27 @@
+/*
+ * 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.spring.boot;
+
+public class SpringBoot3UndertowIT extends SpringBootUndertowIT {
+
+ @Override
+ protected String getExpectedSpringVersionRegex() {
+ return "6\\.[0-9]+\\.[0-9]+";
+ }
+}