Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
a760dac
chore(deps): update Spring Boot and Spring Cloud versions to RC releases
SteKoe Nov 14, 2025
a45ea34
chore: update imported package names
SteKoe Nov 14, 2025
ccbff6c
chore: update dependencies and refactor imports for Jackson library a…
SteKoe Nov 14, 2025
0b09364
chore: compile ready
SteKoe Nov 14, 2025
52fe51a
chore: fix code style
SteKoe Nov 14, 2025
30958e1
chore: fix tests in server module
SteKoe Nov 14, 2025
27c47ff
chore: "fix" tests in server client
SteKoe Nov 15, 2025
14f1d89
chore: update Spring Boot version to 4.0.0
andreasfritz Nov 21, 2025
55867bb
chore: update Spring Cloud version to 2025.1.0
andreasfritz Nov 28, 2025
cb18976
chore: update instance registration in AdminApplicationDiscoveryTest
andreasfritz Nov 28, 2025
a7a05b3
chore: fix InstancesProxyControllerIntegrationTest
SteKoe Nov 28, 2025
b135c4f
fix AdminApplicationDiscoveryTest - instanceProps.setServiceId("Test-…
andreasfritz Dec 5, 2025
a22a280
fix AdminServerDiscoveryAutoConfigurationTest - .withBean(DiscoveryCl…
andreasfritz Dec 5, 2025
d10af3a
test: improve timing in InfoUpdateTriggerTest for event updates
SteKoe Dec 5, 2025
90cd3bc
Fix flaky tests
ulischulte Dec 5, 2025
9470a8a
Fixed flaky IntervalCheckTest by addressing test isolation issues
ulischulte Dec 5, 2025
c487cdc
Configure higher response timeout than 5s default in webTestClient. T…
ulischulte Dec 5, 2025
04e4c29
preventing blocking call deadlocks in thread-constrained CI environme…
ulischulte Dec 5, 2025
9614afe
increased timeout
ulischulte Dec 5, 2025
e40d099
use blockhound to detect blocking calls in reactive threads and work …
ulischulte Dec 5, 2025
6e5c19e
downgrade to 2.1.0 until a compatible version is released
andreasfritz Dec 5, 2025
942ad40
Merge branch 'master' into spring-boot-4
andreasfritz Dec 5, 2025
35e9f52
use blockhound to detect blocking calls in reactive threads in ci pip…
ulischulte Dec 5, 2025
3e998f0
favour StepVerifier when testing potentially blocking calls in reacti…
ulischulte Dec 5, 2025
a7e8c2d
refactor: remove spring-boot-starter-classic and use new modular star…
andreasfritz Dec 12, 2025
40b5e02
refactor: remove optional spring-boot-starter-web dependency from pom…
andreasfritz Dec 12, 2025
4122294
chore: update spring-boot.version to 4.0.1 in pom.xml
andreasfritz Jan 9, 2026
96de4a7
Merge remote-tracking branch 'origin/master' into spring-boot-4
andreasfritz Jan 9, 2026
a6c5502
refactor: replace spring-boot-starter-web with spring-boot-starter-we…
andreasfritz Jan 9, 2026
5545469
refactor: rename objectMapper to jsonMapper in test classes for consi…
andreasfritz Jan 9, 2026
8d91795
refactor: replace ObjectMapper with JsonMapper for JSON serialization…
andreasfritz Jan 9, 2026
a00692a
refactor: update spring-boot dependencies for improved modularity and…
andreasfritz Jan 9, 2026
58ec625
refactor: remove testcontainers dependencies from pom.xml
andreasfritz Jan 16, 2026
9a2e339
refactor: update @AutoConfigureAfter annotation to reference class na…
andreasfritz Jan 16, 2026
0f47707
refactor: remove ReactiveRegistrationClient and BlockingRegistrationC…
hzpz Jan 16, 2026
b08a8f5
refactor: remove spring-boot-starter-json dependency from pom.xml
andreasfritz Jan 16, 2026
f2ed802
refactor: remove optional flag from spring-boot-starter-restclient de…
andreasfritz Jan 16, 2026
8ba059f
refactor: update spring-boot-starter-restclient dependency to test sc…
andreasfritz Jan 16, 2026
51d65ab
Merge remote-tracking branch 'origin/master' into spring-boot-4
ulischulte Jan 16, 2026
3deb45b
refactor: remove RestTemplateAutoConfiguration from test configuratio…
andreasfritz Jan 16, 2026
76e2e5b
chore: Replace deprecated MapAccessor
hzpz Jan 23, 2026
87e6f1a
refactor: replace deprecated Nullable annotation with jspecify's Null…
SteKoe Jan 23, 2026
295f66b
refactor: update button group structure in logger control components
SteKoe Jan 23, 2026
2499556
feat: add availableMetrics property and enhance fetchMetric method fo…
SteKoe Jan 23, 2026
f1e8d4f
chore: update spring-boot.version to 4.0.2 in pom.xml
andreasfritz Jan 23, 2026
16545ae
feat: add mock metrics data for instances in datasource and memory tests
SteKoe Jan 23, 2026
6d13e6b
Merge remote-tracking branch 'origin/master' into spring-boot-4
andreasfritz Jan 23, 2026
fd1aa6d
Merge remote-tracking branch 'origin/master' into spring-boot-4
andreasfritz Jan 23, 2026
f35ba60
refactor: replace deprecated NonNullApi and NonNullFields annotations…
hzpz Jan 23, 2026
ac4187d
Changed revision to SNAPSHOT version
ulischulte Jan 23, 2026
2f3b30d
chore: replace deprecated JsonNode.asText() calls with asString()
hzpz Jan 23, 2026
d73afcc
Merge remote-tracking branch 'origin/master' into spring-boot-4
andreasfritz Jan 30, 2026
03edb97
refactor: replace ObjectMapper with JsonMapper in test classes
andreasfritz Jan 30, 2026
553e1fc
refactor: replace ObjectMapper with JsonMapper in AdminApplicationDis…
andreasfritz Jan 30, 2026
b407629
refactor: update imports to use tools.jackson for improved compatibility
SteKoe Jan 30, 2026
32f7868
chore(deps): update spring-cloud.version to 2025.1.1
andreasfritz Jan 30, 2026
f42f09f
refactor: update Jackson imports to use tools.jackson for improved co…
SteKoe Jan 30, 2026
8df85d7
refactor: reorganize Jackson imports in AbstractAdminApplicationTest …
SteKoe Jan 30, 2026
7f66349
Merge branch 'master' into spring-boot-4
SteKoe Jan 30, 2026
72a3840
feat: a little more condensed accordion views
SteKoe Jan 31, 2026
21f30e3
feat: enhance SBOM handling with optional path and user alerts for no…
SteKoe Jan 31, 2026
ce6ab4f
refactor: remove unused SbaPanel import from index.vue
SteKoe Jan 31, 2026
0059aec
Merge branch 'master' into spring-boot-4
SteKoe Jan 31, 2026
e1fef4c
chore: works on wallboard ui design
SteKoe Jan 31, 2026
cfb9de1
Merge remote-tracking branch 'origin/master' into spring-boot-4
andreasfritz Feb 6, 2026
47e18c4
docs: Update module registration example in Javadoc to use Jackson 3
hzpz Feb 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ ij_java_blank_lines_after_class_header = 0
ij_java_doc_enable_formatting = false
ij_java_class_count_to_use_import_on_demand = 100
ij_java_names_count_to_use_import_on_demand = 100
ij_java_imports_layout = |, java.**, |, jakarta.**, *, |, de.codecentric.boot.admin.**, |, $*
ij_java_imports_layout = |, java.**, |, jakarta.**, *, tools.**, |, de.codecentric.boot.admin.**, |, $*
ij_java_layout_static_imports_separately = true

[*.xml]
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ node/

.DS_Store
mockServiceWorker.js
/.github/agents/
10 changes: 5 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
<url>https://github.com/codecentric/spring-boot-admin/</url>

<properties>
<revision>3.5.8-SNAPSHOT</revision>
<revision>4.0.0-SNAPSHOT</revision>

<java.version>17</java.version>
<node.version>v22.12.0</node.version>
Expand All @@ -47,18 +47,18 @@
<maven.site.skip>true</maven.site.skip>

<!-- used dependencies versions -->
<spring-boot.version>3.5.10</spring-boot.version>
<spring-cloud.version>2025.0.0</spring-cloud.version>
<spring-boot.version>4.0.2</spring-boot.version>
<spring-cloud.version>2025.1.1</spring-cloud.version>

<jolokia-support-spring.version>2.4.3</jolokia-support-spring.version>
<!-- FIXME downgrade to 2.1.0 until a compatible version is released -->
<jolokia-support-spring.version>2.1.0</jolokia-support-spring.version>

<checkstyle.version>12.3.1</checkstyle.version>
<findbugs-jsr305.version>3.0.2</findbugs-jsr305.version>

<wiremock.version>3.13.2</wiremock.version>
<hazelcast.version>5.6.0</hazelcast.version>
<awaitility.version>4.3.0</awaitility.version>
<testcontainers.version>2.0.3</testcontainers.version>
<jetty.version>12.1.6</jetty.version>

<!-- plugin versions -->
Expand Down
12 changes: 0 additions & 12 deletions spring-boot-admin-build/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,6 @@
<version>${awaitility.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-junit-jupiter</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>

Expand Down
19 changes: 7 additions & 12 deletions spring-boot-admin-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,27 +41,27 @@
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-restclient</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<artifactId>spring-boot-starter-webflux</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<artifactId>spring-boot-starter-webmvc</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webflux</artifactId>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
Expand All @@ -74,11 +74,6 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.wiremock</groupId>
<artifactId>wiremock-standalone</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.jspecify.annotations.Nullable;
import org.springframework.boot.cloud.CloudPlatform;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.convert.DurationUnit;
import org.springframework.core.env.Environment;
import org.springframework.lang.Nullable;

@lombok.Data
@ConfigurationProperties(prefix = "spring.boot.admin.client")
Expand Down Expand Up @@ -60,21 +60,18 @@ public class ClientProperties {
/**
* Username for basic authentication on admin server
*/
@Nullable
private String username;
@Nullable private String username;

/**
* Password for basic authentication on admin server
*/
@Nullable
private String password;
@Nullable private String password;

/**
* Enable automatic deregistration on shutdown If not set it defaults to true if an
* active {@link CloudPlatform} is present;
*/
@Nullable
private Boolean autoDeregistration = null;
@Nullable private Boolean autoDeregistration = null;

/**
* Enable automatic registration when the application is ready.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.boot.web.context.WebServerInitializedEvent;
import org.springframework.boot.web.server.context.WebServerInitializedEvent;
import org.springframework.context.annotation.Configuration;

import de.codecentric.boot.admin.client.registration.Application;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,16 @@
import java.util.ArrayList;
import java.util.List;

import org.jspecify.annotations.Nullable;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.lang.Nullable;

@lombok.Data
@ConfigurationProperties("vcap.application")
public class CloudFoundryApplicationProperties {

@Nullable
private String applicationId;
@Nullable private String applicationId;

@Nullable
private String instanceIndex;
@Nullable private String instanceIndex;

private List<String> uris = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
import java.util.LinkedHashMap;
import java.util.Map;

import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.lang.Nullable;

@lombok.Data
@ConfigurationProperties(prefix = "spring.boot.admin.client.instance")
Expand All @@ -31,43 +31,37 @@ public class InstanceProperties {
* Management-url to register with. Inferred at runtime, can be overridden in case the
* reachable URL is different (e.g. Docker).
*/
@Nullable
private String managementUrl;
@Nullable private String managementUrl;

/**
* Base url for computing the management-url to register with. The path is inferred at
* runtime, and appended to the base url.
*/
@Nullable
private String managementBaseUrl;
@Nullable private String managementBaseUrl;

/**
* Client-service-URL register with. Inferred at runtime, can be overridden in case
* the reachable URL is different (e.g. Docker).
*/
@Nullable
private String serviceUrl;
@Nullable private String serviceUrl;

/**
* Base url for computing the service-url to register with. The path is inferred at
* runtime, and appended to the base url.
*/
@Nullable
private String serviceBaseUrl;
@Nullable private String serviceBaseUrl;

/**
* Path for computing the service-url to register with. If not specified, defaults to
* "/"
*/
@Nullable
private String servicePath;
@Nullable private String servicePath;

/**
* Client-health-URL to register with. Inferred at runtime, can be overridden in case
* the reachable URL is different (e.g. Docker). Must be unique all services registry.
*/
@Nullable
private String healthUrl;
@Nullable private String healthUrl;

/**
* Name to register with. Defaults to ${spring.application.name}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,33 +29,29 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.client.RestClientAutoConfiguration;
import org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration;
import org.springframework.boot.autoconfigure.web.reactive.WebFluxProperties;
import org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.DispatcherServletPath;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.http.client.ClientHttpRequestFactoryBuilder;
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.boot.http.client.HttpClientSettings;
import org.springframework.boot.restclient.autoconfigure.RestClientAutoConfiguration;
import org.springframework.boot.web.server.autoconfigure.ServerProperties;
import org.springframework.boot.webflux.autoconfigure.WebFluxProperties;
import org.springframework.boot.webmvc.autoconfigure.DispatcherServletAutoConfiguration;
import org.springframework.boot.webmvc.autoconfigure.DispatcherServletPath;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.core.env.Environment;
import org.springframework.http.client.support.BasicAuthenticationInterceptor;
import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import tools.jackson.databind.json.JsonMapper;

import de.codecentric.boot.admin.client.registration.ApplicationFactory;
import de.codecentric.boot.admin.client.registration.ApplicationRegistrator;
import de.codecentric.boot.admin.client.registration.BlockingRegistrationClient;
import de.codecentric.boot.admin.client.registration.DefaultApplicationRegistrator;
import de.codecentric.boot.admin.client.registration.ReactiveApplicationFactory;
import de.codecentric.boot.admin.client.registration.ReactiveRegistrationClient;
import de.codecentric.boot.admin.client.registration.RegistrationApplicationListener;
import de.codecentric.boot.admin.client.registration.RegistrationClient;
import de.codecentric.boot.admin.client.registration.RestClientRegistrationClient;
Expand All @@ -64,14 +60,10 @@
import de.codecentric.boot.admin.client.registration.metadata.MetadataContributor;
import de.codecentric.boot.admin.client.registration.metadata.StartupDateMetadataContributor;

import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import static org.springframework.web.reactive.function.client.ExchangeFilterFunctions.basicAuthentication;

@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication
@Conditional(SpringBootAdminClientEnabledCondition.class)
@AutoConfigureAfter({ WebEndpointAutoConfiguration.class, RestClientAutoConfiguration.class,
RestTemplateAutoConfiguration.class, WebClientAutoConfiguration.class })
@AutoConfigureAfter({ WebEndpointAutoConfiguration.class, RestClientAutoConfiguration.class })
@EnableConfigurationProperties({ ClientProperties.class, InstanceProperties.class, ServerProperties.class,
ManagementServerProperties.class })
public class SpringBootAdminClientAutoConfiguration {
Expand Down Expand Up @@ -139,59 +131,33 @@ public ApplicationFactory applicationFactory(InstanceProperties instance, Manage
}

@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(RestTemplateBuilder.class)
public static class BlockingRegistrationClientConfig {

@Bean
@ConditionalOnMissingBean
public RegistrationClient registrationClient(ClientProperties client) {
RestTemplateBuilder builder = new RestTemplateBuilder().connectTimeout(client.getConnectTimeout())
.readTimeout(client.getReadTimeout());

if (client.getUsername() != null && client.getPassword() != null) {
builder = builder.basicAuthentication(client.getUsername(), client.getPassword());
}

RestTemplate build = builder.build();
return new BlockingRegistrationClient(build);
}

}

@Configuration(proxyBeanMethods = false)
@ConditionalOnBean({ RestClient.Builder.class, ClientHttpRequestFactoryBuilder.class })
@ConditionalOnBean(RestClient.Builder.class)
public static class RestClientRegistrationClientConfig {

@Bean
@ConditionalOnMissingBean
public RegistrationClient registrationClient(ClientProperties client, RestClient.Builder restClientBuilder,
ClientHttpRequestFactoryBuilder<?> clientHttpRequestFactoryBuilder) {
var factorySettings = ClientHttpRequestFactorySettings.defaults()
ObjectProvider<JsonMapper> objectMapper) {
var factorySettings = HttpClientSettings.defaults()
.withConnectTimeout(client.getConnectTimeout())
.withReadTimeout(client.getReadTimeout());
var clientHttpRequestFactory = clientHttpRequestFactoryBuilder.build(factorySettings);
restClientBuilder = restClientBuilder.requestFactory(clientHttpRequestFactory);
if (client.getUsername() != null && client.getPassword() != null) {
restClientBuilder = restClientBuilder
.requestInterceptor(new BasicAuthenticationInterceptor(client.getUsername(), client.getPassword()));
}
var restClient = restClientBuilder.build();
return new RestClientRegistrationClient(restClient);
}

}
var clientHttpRequestFactory = ClientHttpRequestFactoryBuilder.detect().build(factorySettings);

@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(WebClient.Builder.class)
public static class ReactiveRegistrationClientConfig {
restClientBuilder.requestFactory(clientHttpRequestFactory);

objectMapper.ifAvailable((mapper) -> restClientBuilder.messageConverters((configurer) -> {
configurer.removeIf(JacksonJsonHttpMessageConverter.class::isInstance);
configurer.add(new JacksonJsonHttpMessageConverter(mapper));
}));

@Bean
@ConditionalOnMissingBean
public RegistrationClient registrationClient(ClientProperties client, WebClient.Builder webClient) {
if (client.getUsername() != null && client.getPassword() != null) {
webClient = webClient.filter(basicAuthentication(client.getUsername(), client.getPassword()));
restClientBuilder
.requestInterceptor(new BasicAuthenticationInterceptor(client.getUsername(), client.getPassword()));
}
return new ReactiveRegistrationClient(webClient.build(), client.getReadTimeout());

var restClient = restClientBuilder.build();
return new RestClientRegistrationClient(restClient);
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.cloud.CloudPlatform;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.server.autoconfigure.ServerProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
Expand Down
Loading