Skip to content

Commit 53ec72e

Browse files
committed
wip: Refactor and cleanup MavenProjectFactory
1 parent 7be9ab6 commit 53ec72e

File tree

7 files changed

+89
-107
lines changed

7 files changed

+89
-107
lines changed

sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/MavenProjectFactory.java

Lines changed: 26 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,11 @@
1818
import lombok.RequiredArgsConstructor;
1919
import org.apache.maven.artifact.DefaultArtifact;
2020
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
21-
import org.apache.maven.execution.AbstractExecutionListener;
22-
import org.apache.maven.execution.ExecutionEvent;
23-
import org.apache.maven.execution.MavenExecutionRequest;
2421
import org.apache.maven.model.Model;
2522
import org.apache.maven.model.Plugin;
2623
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
2724
import org.apache.maven.project.*;
2825
import org.apache.maven.project.artifact.PluginArtifact;
29-
import org.codehaus.plexus.PlexusContainer;
30-
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
3126
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
3227
import org.springframework.core.io.Resource;
3328
import org.springframework.stereotype.Component;
@@ -42,63 +37,50 @@
4237

4338

4439
/**
40+
* Creates instances of {@link MavenProject}.
41+
*
4542
* @author Fabian Krüger
4643
*/
4744
@Component
4845
@RequiredArgsConstructor
4946
public class MavenProjectFactory {
5047

51-
private final MavenPlexusContainerFactory plexusContainerFactory;
5248
private final MavenExecutor mavenExecutor;
53-
private final MavenExecutionRequestFactory requestFactory;
5449

5550
/**
56-
* Takes a {@code pom.xml} {@link File} and returns the {@link MavenProject} for it.
51+
* Convenience method for {@link #createMavenProject(File)}.
5752
*/
58-
public MavenProject createMavenProject(File file) {
59-
if (!file.isFile() || !"pom.xml".equals(file.getName())) {
60-
throw new IllegalArgumentException("Maven pom.xml file must be provided.");
61-
}
53+
public MavenProject createMavenProject(Resource pom) {
6254
try {
63-
Path baseDir = file.toPath().getParent();
64-
PlexusContainer plexusContainer = plexusContainerFactory.create();
65-
AtomicReference<MavenProject> projectAtomicReference = new AtomicReference<>();
66-
final ProjectBuilder builder = plexusContainer.lookup(ProjectBuilder.class);
67-
MavenExecutionRequest request = requestFactory.createMavenExecutionRequest(plexusContainer, baseDir);
68-
request.setExecutionListener(new AbstractExecutionListener() {
69-
@Override
70-
public void sessionStarted(ExecutionEvent event) {
71-
72-
super.sessionStarted(event);
73-
try {
74-
DefaultProjectBuildingRequest request = new DefaultProjectBuildingRequest();
75-
76-
request.setSystemProperties(System.getProperties());
77-
request.setProcessPlugins(false);
78-
request.setRepositorySession(event.getSession().getRepositorySession());
79-
ProjectBuildingResult buildingResult = builder.build(file, request);
80-
projectAtomicReference.set(buildingResult.getProject());
81-
} catch (ProjectBuildingException e) {
82-
throw new RuntimeException(e);
83-
}
84-
}
85-
});
86-
request.setGoals(List.of("validate"));
87-
mavenExecutor.execute(request);
88-
return projectAtomicReference.get();
89-
} catch (ComponentLookupException e) {
55+
return createMavenProject(pom.getFile());
56+
} catch (IOException e) {
9057
throw new RuntimeException(e);
9158
}
9259
}
9360

94-
public MavenProject createMavenProject(Resource pom) {
95-
try {
96-
return createMavenProject(pom.getFile());
97-
} catch (IOException e) {
98-
throw new RuntimeException(e);
61+
/**
62+
* Creates {@link MavenProject} instance from a given pom file.
63+
* It uses the {@link MavenExecutor} to run `{@code dependency:resolve}` goal
64+
* and provides the {@link MavenProject} received from {@link org.apache.maven.execution.ExecutionEvent}.
65+
* All classpath elements are resolved.
66+
*/
67+
public MavenProject createMavenProject(File file) {
68+
if (!file.isFile() || !"pom.xml".equals(file.getName())) {
69+
throw new IllegalArgumentException("Maven pom.xml file must be provided.");
9970
}
71+
72+
Path baseDir = file.toPath().getParent();
73+
AtomicReference<MavenProject> projectAtomicReference = new AtomicReference<>();
74+
mavenExecutor.onProjectSucceededEvent(baseDir, List.of("dependency:resolve"), event -> {
75+
MavenProject project = event.getProject();
76+
projectAtomicReference.set(project);
77+
});
78+
return projectAtomicReference.get();
10079
}
10180

81+
/**
82+
*
83+
*/
10284
public MavenProject createMavenProject(String s) {
10385
try {
10486

sbm-support-rewrite/src/main/java/org/springframework/sbm/parsers/ProvenanceMarkerFactory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public Map<Path, List<Marker>> generateProvenanceMarkers(Path baseDir, List<Reso
7777
MavenMojoProjectParser helper = getMavenMojoProjectParser(baseDir, runtimeInformation, mavenSession, settingsDecrypter);
7878
Map<Path, List<Marker>> result = new HashMap<>();
7979
pomFileResources.forEach(pom -> {
80+
// FIXME: this results in another Maven execution but the MavenProject could be retrieved from the current execution.
8081
MavenProject mavenProject = createMavenProject(pom);
8182
List<Marker> markers = helper.generateProvenance(mavenProject);
8283
result.put(ResourceUtil.getPath(pom), markers);

sbm-support-rewrite/src/test/java/org/springframework/sbm/parsers/MavenProjectFactoryTest.java

Lines changed: 58 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@
1616
package org.springframework.sbm.parsers;
1717

1818
import org.apache.maven.project.MavenProject;
19+
import org.intellij.lang.annotations.Language;
1920
import org.junit.jupiter.api.DisplayName;
2021
import org.junit.jupiter.api.Test;
2122
import org.junit.jupiter.api.io.TempDir;
2223

2324
import java.nio.file.Files;
2425
import java.nio.file.Path;
26+
import java.util.ArrayList;
27+
import java.util.List;
28+
29+
import static org.assertj.core.api.Assertions.assertThat;
2530

2631
/**
2732
* @author Fabian Krüger
@@ -31,23 +36,19 @@ class MavenProjectFactoryTest {
3136
@Test
3237
@DisplayName("Factory should create fully initialized MavenProject")
3338
void factoryShouldCreateFullyInitializedMavenProject(@TempDir Path tempDir) throws Exception {
39+
@Language("xml")
3440
String pomXml = """
3541
<?xml version="1.0" encoding="UTF-8"?>
3642
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3743
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
3844
<modelVersion>4.0.0</modelVersion>
39-
<parent>
40-
<groupId>org.springframework.boot</groupId>
41-
<artifactId>spring-boot-starter-parent</artifactId>
42-
<version>2.7.1</version>
43-
<relativePath/> <!-- lookup parent from repository -->
44-
</parent>
4545
<groupId>com.example</groupId>
46-
<artifactId>demo-spring-song-app</artifactId>
46+
<artifactId>the-example</artifactId>
4747
<version>0.0.1-SNAPSHOT</version>
48+
<name>the-name</name>
4849
<properties>
4950
<java.version>11</java.version>
50-
<spring-cloud.version>2021.0.4</spring-cloud.version>
51+
<spring-boot.version>3.1.2</spring-boot.version>
5152
</properties>
5253
<repositories>
5354
<repository>
@@ -64,55 +65,24 @@ void factoryShouldCreateFullyInitializedMavenProject(@TempDir Path tempDir) thro
6465
<dependencies>
6566
<dependency>
6667
<groupId>org.springframework.boot</groupId>
67-
<artifactId>spring-boot-starter-web</artifactId>
68-
</dependency>
69-
<dependency>
70-
<groupId>org.ehcache</groupId>
71-
<artifactId>ehcache</artifactId>
68+
<artifactId>spring-boot-starter</artifactId>
7269
</dependency>
7370
<dependency>
74-
<groupId>org.springframework.boot</groupId>
75-
<artifactId>spring-boot-starter-data-jpa</artifactId>
76-
</dependency>
77-
<dependency>
78-
<groupId>com.h2database</groupId>
79-
<artifactId>h2</artifactId>
80-
<scope>runtime</scope>
81-
</dependency>
82-
<dependency>
83-
<groupId>org.hibernate.validator</groupId>
84-
<artifactId>hibernate-validator</artifactId>
85-
</dependency>
86-
87-
88-
<dependency>
89-
<groupId>com.github.tomakehurst</groupId>
90-
<artifactId>wiremock-jre8</artifactId>
91-
<version>2.35.0</version>
92-
</dependency>
93-
<dependency>
94-
<groupId>org.apache.johnzon</groupId>
95-
<artifactId>johnzon-core</artifactId>
96-
</dependency>
97-
<dependency>
98-
<groupId>org.projectlombok</groupId>
99-
<artifactId>lombok</artifactId>
100-
</dependency>
101-
<dependency>
102-
<groupId>org.springframework.boot</groupId>
103-
<artifactId>spring-boot-starter-test</artifactId>
71+
<groupId>javax.validation</groupId>
72+
<artifactId>validation-api</artifactId>
73+
<version>2.0.1.Final</version>
10474
<scope>test</scope>
10575
</dependency>
10676
</dependencies>
10777
<dependencyManagement>
10878
<dependencies>
10979
<dependency>
110-
<groupId>org.springframework.cloud</groupId>
111-
<artifactId>spring-cloud-dependencies</artifactId>
112-
<version>${spring-cloud.version}</version>
80+
<groupId>org.springframework.boot</groupId>
81+
<artifactId>spring-boot-dependencies</artifactId>
82+
<version>${spring-boot.version}</version>
11383
<type>pom</type>
11484
<scope>import</scope>
115-
</dependency>
85+
</dependency>
11686
</dependencies>
11787
</dependencyManagement>
11888
<build>
@@ -123,25 +93,56 @@ void factoryShouldCreateFullyInitializedMavenProject(@TempDir Path tempDir) thro
12393
</plugin>
12494
</plugins>
12595
</build>
126-
12796
</project>
12897
""";
12998

13099
MavenPlexusContainerFactory plexusContainerFactory = new MavenPlexusContainerFactory();
131-
MavenExecutionRequestFactory requestFactory = new MavenExecutionRequestFactory(
132-
new MavenConfigFileParser()
133-
);
100+
MavenExecutionRequestFactory requestFactory = new MavenExecutionRequestFactory(new MavenConfigFileParser());
101+
MavenExecutor mavenExecutor = new MavenExecutor(requestFactory, plexusContainerFactory);
134102
MavenProjectFactory sut = new MavenProjectFactory(
135-
plexusContainerFactory,
136-
new MavenExecutor(
137-
requestFactory,
138-
plexusContainerFactory
139-
),
140-
requestFactory
103+
mavenExecutor
141104
);
105+
142106
Path pomFile = tempDir.resolve("pom.xml");
143107
Files.writeString(pomFile, pomXml);
144108
MavenProject mavenProject = sut.createMavenProject(pomFile.toFile());
109+
assertThat(mavenProject.getName()).isEqualTo("the-name");
110+
assertThat(mavenProject.getArtifactId()).isEqualTo("the-example");
111+
assertThat(mavenProject.getGroupId()).isEqualTo("com.example");
112+
113+
List<String> mainDeps = List.of(
114+
tempDir.resolve("target/classes").toString(),
115+
dep("org/springframework/boot/spring-boot-starter/3.1.2/spring-boot-starter-3.1.2.jar"),
116+
dep("org/springframework/boot/spring-boot/3.1.2/spring-boot-3.1.2.jar"),
117+
dep("org/springframework/spring-context/6.0.11/spring-context-6.0.11.jar"),
118+
dep("org/springframework/spring-aop/6.0.11/spring-aop-6.0.11.jar"),
119+
dep("org/springframework/spring-beans/6.0.11/spring-beans-6.0.11.jar"),
120+
dep("org/springframework/spring-expression/6.0.11/spring-expression-6.0.11.jar"),
121+
dep("org/springframework/boot/spring-boot-autoconfigure/3.1.2/spring-boot-autoconfigure-3.1.2.jar"),
122+
dep("org/springframework/boot/spring-boot-starter-logging/3.1.2/spring-boot-starter-logging-3.1.2.jar"),
123+
dep("ch/qos/logback/logback-classic/1.4.8/logback-classic-1.4.8.jar"),
124+
dep("ch/qos/logback/logback-core/1.4.8/logback-core-1.4.8.jar"),
125+
dep("org/slf4j/slf4j-api/2.0.7/slf4j-api-2.0.7.jar"),
126+
dep("org/apache/logging/log4j/log4j-to-slf4j/2.20.0/log4j-to-slf4j-2.20.0.jar"),
127+
dep("org/apache/logging/log4j/log4j-api/2.20.0/log4j-api-2.20.0.jar"),
128+
dep("org/slf4j/jul-to-slf4j/2.0.7/jul-to-slf4j-2.0.7.jar"),
129+
dep("jakarta/annotation/jakarta.annotation-api/2.1.1/jakarta.annotation-api-2.1.1.jar"),
130+
dep("org/springframework/spring-core/6.0.11/spring-core-6.0.11.jar"),
131+
dep("org/springframework/spring-jcl/6.0.11/spring-jcl-6.0.11.jar"),
132+
dep("org/yaml/snakeyaml/1.33/snakeyaml-1.33.jar")
133+
);
134+
assertThat(mavenProject.getCompileClasspathElements()).containsExactlyInAnyOrder(mainDeps.toArray(new String[]{}));
135+
136+
List<String> testDeps = new ArrayList<>();
137+
testDeps.addAll(mainDeps);
138+
testDeps.add(tempDir.resolve("target/test-classes").toString());
139+
testDeps.add(dep("javax/validation/validation-api/2.0.1.Final/validation-api-2.0.1.Final.jar"));
140+
assertThat(mavenProject.getTestClasspathElements()).containsExactlyInAnyOrder(testDeps.toArray(new String[]{}));
141+
}
142+
143+
private String dep(String s) {
144+
Path m2Repo = Path.of(System.getProperty("user.home")).resolve(".m2/repository/").resolve(s);
145+
return m2Repo.toString();
145146
}
146147

147148

sbm-support-rewrite/src/test/java/org/springframework/sbm/parsers/ProvenanceMarkerFactoryTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ void shouldCreateProvenanceMarkers(@TempDir Path tempDir) {
137137
MavenExecutionRequestFactory requestFactory = new MavenExecutionRequestFactory(new MavenConfigFileParser());
138138
ProvenanceMarkerFactory sut = new ProvenanceMarkerFactory(
139139
parserSettings,
140-
new MavenProjectFactory(containerFactory, new MavenExecutor(requestFactory, containerFactory), requestFactory),
140+
new MavenProjectFactory(new MavenExecutor(requestFactory, containerFactory)),
141141
new MavenMojoProjectParserFactory(parserSettings)
142142
);
143143
Path baseDir = Path.of(".").toAbsolutePath().normalize();

sbm-support-rewrite/src/test/java/org/springframework/sbm/parsers/RewriteMavenProjectParserTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -412,7 +412,7 @@ void parseMultiModule1_WithCustomParser() {
412412
MavenMojoProjectParserPrivateMethods mavenMojoParserPrivateMethods = new MavenMojoProjectParserPrivateMethods(mavenMojoProjectParserFactory, new RewriteMavenArtifactDownloader());
413413
MavenPlexusContainerFactory plexusContainerFactory = new MavenPlexusContainerFactory();
414414
MavenExecutionRequestFactory requestFactory = new MavenExecutionRequestFactory(new MavenConfigFileParser());
415-
MavenProjectFactory mavenProjectFactory = new MavenProjectFactory(plexusContainerFactory, new MavenExecutor(requestFactory, plexusContainerFactory), requestFactory);
415+
MavenProjectFactory mavenProjectFactory = new MavenProjectFactory(new MavenExecutor(requestFactory, plexusContainerFactory));
416416

417417
RewriteProjectParser rpp = new RewriteProjectParser(
418418
new ProvenanceMarkerFactory(parserSettings, mavenProjectFactory, mavenMojoProjectParserFactory),

sbm-support-rewrite/src/test/java/org/springframework/sbm/parsers/RewriteProjectParserTest.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,10 @@ void parseComplexMavenReactorProject2(@TempDir Path tempDir) {
101101
new ProvenanceMarkerFactory(
102102
parserSettings,
103103
new MavenProjectFactory(
104-
containerFactory,
105104
new MavenExecutor(
106105
requestFactory,
107106
containerFactory
108-
),
109-
requestFactory
107+
)
110108
), mavenMojoProjectParserFactory),
111109
new BuildFileParser(parserSettings),
112110
new SourceFileParser(mavenModelReader, parserSettings, mavenMojoParserPrivateMethods),

sbm-support-rewrite/src/test/java/org/springframework/sbm/parsers/RewriteRecipeDiscoveryTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,6 @@ private static Optional<Recipe> getRecipeByDisplayName(List<Recipe> recipes, Str
271271
private static RewriteRecipeDiscovery buildRecipeDiscovery() {
272272
MavenPlexusContainerFactory plexusContainerFactory = new MavenPlexusContainerFactory();
273273
MavenExecutionRequestFactory requestFactory = new MavenExecutionRequestFactory(new MavenConfigFileParser());
274-
return new RewriteRecipeDiscovery(new ParserSettings(), new MavenProjectFactory(plexusContainerFactory, new MavenExecutor(requestFactory, plexusContainerFactory), requestFactory));
274+
return new RewriteRecipeDiscovery(new ParserSettings(), new MavenProjectFactory(new MavenExecutor(requestFactory, plexusContainerFactory)));
275275
}
276276
}

0 commit comments

Comments
 (0)