Merge branch '3.4.x' into 3.5.x

Closes gh-47166
This commit is contained in:
Moritz Halbritter 2025-09-12 11:10:45 +02:00
commit 700904cfe2
10 changed files with 195 additions and 54 deletions

View File

@ -37,6 +37,7 @@ import static org.assertj.core.api.Assertions.contentOf;
* @author Stephane Nicoll
* @author Andy Wilkinson
* @author Scott Frederick
* @author Moritz Halbritter
*/
@ExtendWith(MavenBuildExtension.class)
class AotTests {
@ -108,6 +109,15 @@ class AotTests {
});
}
@TestTemplate
void whenAotRunsWithSystemPropertiesSourcesAreGenerated(MavenBuild mavenBuild) {
mavenBuild.project("aot-system-properties").goals("package").execute((project) -> {
Path aotDirectory = project.toPath().resolve("target/spring-aot/main");
assertThat(collectRelativePaths(aotDirectory.resolve("sources")))
.contains(Path.of("org", "test", "TestProfileConfiguration__BeanDefinitions.java"));
});
}
@TestTemplate
void whenAotRunsWithJvmArgumentsSourcesAreGenerated(MavenBuild mavenBuild) {
mavenBuild.project("aot-jvm-arguments").goals("package").execute((project) -> {

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.boot.maven.it</groupId>
<artifactId>aot-system-properties</artifactId>
<version>0.0.1.BUILD-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>@java.version@</maven.compiler.source>
<maven.compiler.target>@java.version@</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>@project.groupId@</groupId>
<artifactId>@project.artifactId@</artifactId>
<version>@project.version@</version>
<executions>
<execution>
<goals>
<goal>process-aot</goal>
</goals>
<configuration>
<systemPropertyVariables>
<spring.profiles.active>abc</spring.profiles.active>
</systemPropertyVariables>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>@project.version@</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>@jakarta-servlet.version@</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,31 @@
/*
* Copyright 2012-present the original author or authors.
*
* Licensed 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
*
* https://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 org.test;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration(proxyBeanMethods = false)
@Import(TestProfileConfiguration.class)
public class SampleApplication {
public static void main(String[] args) {
SpringApplication.run(SampleApplication.class, args);
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright 2012-present the original author or authors.
*
* Licensed 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
*
* https://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 org.test;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
@Configuration(proxyBeanMethods = false)
@Profile("abc")
class TestProfileConfiguration {
@Bean
public String abc() {
return "abc";
}
}

View File

@ -25,6 +25,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collectors;
@ -38,6 +39,7 @@ import org.apache.maven.project.MavenProject;
import org.apache.maven.toolchain.ToolchainManager;
import org.springframework.boot.loader.tools.FileUtils;
import org.springframework.util.StringUtils;
/**
* Base class to run a Spring Boot application.
@ -302,17 +304,20 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
* @return a {@link RunArguments} defining the JVM arguments
*/
protected RunArguments resolveJvmArguments() {
StringBuilder stringBuilder = new StringBuilder();
List<String> arguments = new ArrayList<>();
if (this.systemPropertyVariables != null) {
stringBuilder.append(this.systemPropertyVariables.entrySet()
.stream()
.map((e) -> SystemPropertyFormatter.format(e.getKey(), e.getValue()))
.collect(Collectors.joining(" ")));
for (Entry<String, String> systemProperty : this.systemPropertyVariables.entrySet()) {
String argument = SystemPropertyFormatter.format(systemProperty.getKey(), systemProperty.getValue());
if (StringUtils.hasText(argument)) {
arguments.add(argument);
}
}
}
if (this.jvmArguments != null) {
stringBuilder.append(" ").append(this.jvmArguments);
String[] jvmArguments = RunArguments.parseArgs(this.jvmArguments);
arguments.addAll(Arrays.asList(jvmArguments));
}
return new RunArguments(stringBuilder.toString());
return new RunArguments(arguments);
}
private void addJvmArgs(List<String> args) {
@ -419,21 +424,4 @@ public abstract class AbstractRunMojo extends AbstractDependencyFilterMojo {
}
}
/**
* Format System properties.
*/
static class SystemPropertyFormatter {
static String format(String key, String value) {
if (key == null) {
return "";
}
if (value == null || value.isEmpty()) {
return String.format("-D%s", key);
}
return String.format("-D%s=\"%s\"", key, value);
}
}
}

View File

@ -21,8 +21,11 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import org.springframework.util.StringUtils;
/**
* Helper class to build the command-line arguments of a java process.
*
@ -55,10 +58,12 @@ final class CommandLineBuilder {
CommandLineBuilder withSystemProperties(Map<String, String> systemProperties) {
if (systemProperties != null) {
systemProperties.entrySet()
.stream()
.map((e) -> SystemPropertyFormatter.format(e.getKey(), e.getValue()))
.forEach(this.options::add);
for (Entry<String, String> systemProperty : systemProperties.entrySet()) {
String option = SystemPropertyFormatter.format(systemProperty.getKey(), systemProperty.getValue());
if (StringUtils.hasText(option)) {
this.options.add(option);
}
}
}
return this;
}
@ -88,21 +93,4 @@ final class CommandLineBuilder {
return commandLine;
}
/**
* Format System properties.
*/
private static final class SystemPropertyFormatter {
static String format(String key, String value) {
if (key == null) {
return "";
}
if (value == null || value.isEmpty()) {
return String.format("-D%s", key);
}
return String.format("-D%s=\"%s\"", key, value);
}
}
}

View File

@ -19,7 +19,6 @@ package org.springframework.boot.maven;
import java.util.Arrays;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Objects;
import org.codehaus.plexus.util.cli.CommandLineUtils;
@ -39,8 +38,16 @@ class RunArguments {
}
RunArguments(String[] args) {
this((args != null) ? Arrays.asList(args) : null);
}
RunArguments(Iterable<String> args) {
if (args != null) {
Arrays.stream(args).filter(Objects::nonNull).forEach(this.args::add);
for (String arg : args) {
if (arg != null) {
this.args.add(arg);
}
}
}
}
@ -52,7 +59,7 @@ class RunArguments {
return this.args.toArray(new String[0]);
}
private static String[] parseArgs(String arguments) {
static String[] parseArgs(String arguments) {
if (arguments == null || arguments.trim().isEmpty()) {
return NO_ARGS;
}

View File

@ -0,0 +1,40 @@
/*
* Copyright 2012-present the original author or authors.
*
* Licensed 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
*
* https://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 org.springframework.boot.maven;
/**
* Format System properties.
*
* @author Phillip Webb
* @author Stephane Nicoll
*/
final class SystemPropertyFormatter {
private SystemPropertyFormatter() {
}
static String format(String key, String value) {
if (key == null) {
return "";
}
if (value == null || value.isEmpty()) {
return String.format("-D%s", key);
}
return String.format("-D%s=%s", key, value);
}
}

View File

@ -76,7 +76,7 @@ class CommandLineBuilderTests {
@Test
void buildWithSystemProperty() {
assertThat(CommandLineBuilder.forMainClass(CLASS_NAME).withSystemProperties(Map.of("flag", "enabled")).build())
.containsExactly("-Dflag=\"enabled\"", CLASS_NAME);
.containsExactly("-Dflag=enabled", CLASS_NAME);
}
@Test

View File

@ -18,12 +18,10 @@ package org.springframework.boot.maven;
import org.junit.jupiter.api.Test;
import org.springframework.boot.maven.AbstractRunMojo.SystemPropertyFormatter;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for {@link AbstractRunMojo.SystemPropertyFormatter}.
* Tests for {@link SystemPropertyFormatter}.
*/
class SystemPropertyFormatterTests {
@ -39,7 +37,7 @@ class SystemPropertyFormatterTests {
@Test
void parseKeyWithValue() {
assertThat(SystemPropertyFormatter.format("key1", "value1")).isEqualTo("-Dkey1=\"value1\"");
assertThat(SystemPropertyFormatter.format("key1", "value1")).isEqualTo("-Dkey1=value1");
}
@Test
@ -49,7 +47,7 @@ class SystemPropertyFormatterTests {
@Test
void parseKeyWithOnlySpaces() {
assertThat(SystemPropertyFormatter.format("key1", " ")).isEqualTo("-Dkey1=\" \"");
assertThat(SystemPropertyFormatter.format("key1", " ")).isEqualTo("-Dkey1= ");
}
}