Skip to content

Commit 9792e32

Browse files
timtebeekTim te Beek
andauthored
Skip unresolved property placeholders when determining charset (#1105)
* Add failing tests for property placeholder in encoding configuration When the maven-compiler-plugin encoding is configured with a property placeholder like ${java.encoding}, getCharset() throws IllegalCharsetNameException because Charset.forName() receives the unresolved placeholder string. * Skip unresolved property placeholders when determining charset When the maven-compiler-plugin encoding is configured with a property placeholder like ${java.encoding}, getCharset() would throw IllegalCharsetNameException because Charset.forName() received the unresolved placeholder string. This follows the same pattern used elsewhere in this class for handling unresolved properties (e.g., release, source, target settings) - skip values containing "${" and let the method return Optional.empty() instead. Also fixed a potential NPE when getPluginManagement() returns null. Fixes #1104 * Resolve property placeholders from Maven properties Instead of just skipping unresolved property placeholders, attempt to resolve them from MavenProject.getProperties(). This allows configurations like ${java.encoding} to work when the property is defined in the project. --------- Co-authored-by: Tim te Beek <[email protected]>
1 parent 27684e2 commit 9792e32

2 files changed

Lines changed: 130 additions & 4 deletions

File tree

src/main/java/org/openrewrite/maven/MavenMojoProjectParser.java

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.apache.maven.execution.MavenExecutionRequest;
2121
import org.apache.maven.execution.MavenSession;
2222
import org.apache.maven.model.Plugin;
23+
import org.apache.maven.model.PluginManagement;
2324
import org.apache.maven.model.PluginExecution;
2425
import org.apache.maven.model.Repository;
2526
import org.apache.maven.model.Resource;
@@ -280,24 +281,45 @@ public enum MavenScope {
280281
TEST
281282
}
282283

283-
private static Optional<Charset> getCharset(MavenProject mavenProject) {
284+
static Optional<Charset> getCharset(MavenProject mavenProject) {
284285
String compilerPluginKey = MAVEN_COMPILER_PLUGIN;
285286
Plugin plugin = Optional.ofNullable(mavenProject.getPlugin(compilerPluginKey))
286-
.orElseGet(() -> mavenProject.getPluginManagement().getPluginsAsMap().get(compilerPluginKey));
287+
.orElseGet(() -> {
288+
PluginManagement pluginManagement = mavenProject.getPluginManagement();
289+
return pluginManagement != null ? pluginManagement.getPluginsAsMap().get(compilerPluginKey) : null;
290+
});
287291
if (plugin != null && plugin.getConfiguration() instanceof Xpp3Dom) {
288292
Xpp3Dom encoding = ((Xpp3Dom) plugin.getConfiguration()).getChild("encoding");
289293
if (encoding != null && StringUtils.isNotEmpty(encoding.getValue())) {
290-
return Optional.of(Charset.forName(encoding.getValue()));
294+
String resolved = resolveProperty(encoding.getValue(), mavenProject);
295+
if (resolved != null) {
296+
return Optional.of(Charset.forName(resolved));
297+
}
291298
}
292299
}
293300

294301
Object mavenSourceEncoding = mavenProject.getProperties().get("project.build.sourceEncoding");
295302
if (mavenSourceEncoding != null) {
296-
return Optional.of(Charset.forName(mavenSourceEncoding.toString()));
303+
String resolved = resolveProperty(mavenSourceEncoding.toString(), mavenProject);
304+
if (resolved != null) {
305+
return Optional.of(Charset.forName(resolved));
306+
}
297307
}
298308
return Optional.empty();
299309
}
300310

311+
private static @Nullable String resolveProperty(String value, MavenProject mavenProject) {
312+
if (value.startsWith("${") && value.endsWith("}")) {
313+
String propertyName = value.substring(2, value.length() - 1);
314+
String resolved = mavenProject.getProperties().getProperty(propertyName);
315+
if (resolved != null && !resolved.contains("${")) {
316+
return resolved;
317+
}
318+
return null;
319+
}
320+
return value.contains("${") ? null : value;
321+
}
322+
301323
static org.openrewrite.jgit.lib.@Nullable Repository getRepository(Path rootDir) {
302324
try (Git git = Git.open(rootDir.toFile())) {
303325
return git.getRepository();

src/test/java/org/openrewrite/maven/MavenMojoProjectParserTest.java

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,19 @@
1515
*/
1616
package org.openrewrite.maven;
1717

18+
import org.apache.maven.model.Build;
19+
import org.apache.maven.model.Plugin;
1820
import org.apache.maven.project.MavenProject;
21+
import org.codehaus.plexus.util.xml.Xpp3Dom;
1922
import org.junit.jupiter.api.DisplayName;
2023
import org.junit.jupiter.api.Test;
2124
import org.openrewrite.java.marker.JavaVersion;
2225

26+
import java.nio.charset.Charset;
27+
import java.util.Optional;
28+
2329
import static org.assertj.core.api.Assertions.assertThat;
30+
import static org.assertj.core.api.Assertions.assertThatCode;
2431

2532
/**
2633
* @author Fabian Krüger
@@ -33,4 +40,101 @@ void givenNoJavaVersionInformationExistsInMavenThenJavaSpecificationVersionShoul
3340
assertThat(marker.getSourceCompatibility()).isEqualTo(System.getProperty("java.specification.version"));
3441
assertThat(marker.getTargetCompatibility()).isEqualTo(System.getProperty("java.specification.version"));
3542
}
43+
44+
@DisplayName("getCharset should resolve encoding from property placeholder")
45+
@Test
46+
void getCharsetShouldResolveEncodingFromPropertyPlaceholder() {
47+
MavenProject mavenProject = new MavenProject();
48+
mavenProject.getProperties().setProperty("java.encoding", "UTF-8");
49+
50+
// Set up maven-compiler-plugin with encoding as property placeholder
51+
Plugin compilerPlugin = new Plugin();
52+
compilerPlugin.setGroupId("org.apache.maven.plugins");
53+
compilerPlugin.setArtifactId("maven-compiler-plugin");
54+
55+
Xpp3Dom configuration = new Xpp3Dom("configuration");
56+
Xpp3Dom encoding = new Xpp3Dom("encoding");
57+
encoding.setValue("${java.encoding}");
58+
configuration.addChild(encoding);
59+
compilerPlugin.setConfiguration(configuration);
60+
61+
Build build = new Build();
62+
build.addPlugin(compilerPlugin);
63+
mavenProject.setBuild(build);
64+
65+
// Should resolve the property and return the charset
66+
Optional<Charset> charset = MavenMojoProjectParser.getCharset(mavenProject);
67+
assertThat(charset).isPresent();
68+
assertThat(charset.get().name()).isEqualTo("UTF-8");
69+
}
70+
71+
@DisplayName("getCharset should return empty when property placeholder is unresolved")
72+
@Test
73+
void getCharsetShouldReturnEmptyWhenPropertyPlaceholderIsUnresolved() {
74+
MavenProject mavenProject = new MavenProject();
75+
76+
// Set up maven-compiler-plugin with encoding as property placeholder (not defined)
77+
Plugin compilerPlugin = new Plugin();
78+
compilerPlugin.setGroupId("org.apache.maven.plugins");
79+
compilerPlugin.setArtifactId("maven-compiler-plugin");
80+
81+
Xpp3Dom configuration = new Xpp3Dom("configuration");
82+
Xpp3Dom encoding = new Xpp3Dom("encoding");
83+
encoding.setValue("${java.encoding}");
84+
configuration.addChild(encoding);
85+
compilerPlugin.setConfiguration(configuration);
86+
87+
Build build = new Build();
88+
build.addPlugin(compilerPlugin);
89+
mavenProject.setBuild(build);
90+
91+
// Should not throw IllegalCharsetNameException
92+
assertThatCode(() -> MavenMojoProjectParser.getCharset(mavenProject))
93+
.doesNotThrowAnyException();
94+
95+
// Should return empty when encoding is unresolved placeholder
96+
Optional<Charset> charset = MavenMojoProjectParser.getCharset(mavenProject);
97+
assertThat(charset).isEmpty();
98+
}
99+
100+
@DisplayName("getCharset should not throw when project.build.sourceEncoding is a property placeholder")
101+
@Test
102+
void getCharsetShouldNotThrowWhenSourceEncodingIsPropertyPlaceholder() {
103+
MavenProject mavenProject = new MavenProject();
104+
mavenProject.setBuild(new Build());
105+
mavenProject.getProperties().setProperty("project.build.sourceEncoding", "${java.encoding}");
106+
107+
// Should not throw IllegalCharsetNameException
108+
assertThatCode(() -> MavenMojoProjectParser.getCharset(mavenProject))
109+
.doesNotThrowAnyException();
110+
111+
// Should return empty when encoding is unresolved placeholder
112+
Optional<Charset> charset = MavenMojoProjectParser.getCharset(mavenProject);
113+
assertThat(charset).isEmpty();
114+
}
115+
116+
@DisplayName("getCharset should return charset when encoding is valid")
117+
@Test
118+
void getCharsetShouldReturnCharsetWhenEncodingIsValid() {
119+
MavenProject mavenProject = new MavenProject();
120+
121+
// Set up maven-compiler-plugin with valid encoding
122+
Plugin compilerPlugin = new Plugin();
123+
compilerPlugin.setGroupId("org.apache.maven.plugins");
124+
compilerPlugin.setArtifactId("maven-compiler-plugin");
125+
126+
Xpp3Dom configuration = new Xpp3Dom("configuration");
127+
Xpp3Dom encoding = new Xpp3Dom("encoding");
128+
encoding.setValue("UTF-8");
129+
configuration.addChild(encoding);
130+
compilerPlugin.setConfiguration(configuration);
131+
132+
Build build = new Build();
133+
build.addPlugin(compilerPlugin);
134+
mavenProject.setBuild(build);
135+
136+
Optional<Charset> charset = MavenMojoProjectParser.getCharset(mavenProject);
137+
assertThat(charset).isPresent();
138+
assertThat(charset.get().name()).isEqualTo("UTF-8");
139+
}
36140
}

0 commit comments

Comments
 (0)