diff --git a/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java b/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java
index 47342ce8a7ec..219e21f2469b 100644
--- a/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java
+++ b/api/maven-api-core/src/main/java/org/apache/maven/api/Project.java
@@ -224,6 +224,13 @@ default String getId() {
/**
* Returns project parent project, if any.
+ *
+ * Note that the model may have a parent defined, but an empty parent
+ * project may be returned if the parent comes from a remote repository,
+ * as a {@code Project} must refer to a buildable project.
+ *
+ * @return an optional containing the parent project
+ * @see Model#getParent()
*/
@Nonnull
Optional getParent();
diff --git a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/Utils.java b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/Utils.java
index 0d0d43c32f93..2fb4ad3d338c 100644
--- a/maven-api-impl/src/main/java/org/apache/maven/internal/impl/Utils.java
+++ b/maven-api-impl/src/main/java/org/apache/maven/internal/impl/Utils.java
@@ -20,6 +20,7 @@
import java.util.Collection;
import java.util.List;
+import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -49,6 +50,6 @@ static T cast(Class clazz, Object o, String name) {
}
static List map(Collection list, Function mapper) {
- return list.stream().map(mapper).collect(Collectors.toList());
+ return list.stream().map(mapper).filter(Objects::nonNull).collect(Collectors.toList());
}
}
diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultEvent.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultEvent.java
index 2f4cf648c832..2f03e6654333 100644
--- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultEvent.java
+++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultEvent.java
@@ -48,7 +48,7 @@ public Session getSession() {
@Override
public Optional getProject() {
- return Optional.ofNullable(delegate.getProject()).map(session::getProject);
+ return Optional.ofNullable(session.getProject(delegate.getProject()));
}
@Override
diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java
index ba1c6d708fc8..359f84094a12 100644
--- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java
+++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProject.java
@@ -159,7 +159,7 @@ public Path getRootDirectory() {
@Override
public Optional getParent() {
MavenProject parent = project.getParent();
- return parent != null ? Optional.of(session.getProject(parent)) : Optional.empty();
+ return Optional.ofNullable(session.getProject(parent));
}
@Nonnull
diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectBuilder.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectBuilder.java
index a446f63b26ee..efc6d3e7855a 100644
--- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectBuilder.java
+++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultProjectBuilder.java
@@ -100,7 +100,7 @@ public Optional getPomFile() {
@Nonnull
@Override
public Optional getProject() {
- return Optional.ofNullable(res.getProject()).map(session::getProject);
+ return Optional.ofNullable(session.getProject(res.getProject()));
}
@Nonnull
diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java
index cd83f7c44921..a931b9874ba7 100644
--- a/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java
+++ b/maven-core/src/main/java/org/apache/maven/internal/impl/DefaultSession.java
@@ -93,7 +93,9 @@ public List getProjects(List projects) {
@Override
public Project getProject(MavenProject project) {
- return allProjects.computeIfAbsent(project.getId(), id -> new DefaultProject(this, project));
+ return project != null && project.getBasedir() != null
+ ? allProjects.computeIfAbsent(project.getId(), id -> new DefaultProject(this, project))
+ : null;
}
@Override
diff --git a/maven-core/src/main/java/org/apache/maven/internal/impl/InternalMavenSession.java b/maven-core/src/main/java/org/apache/maven/internal/impl/InternalMavenSession.java
index 1ee399c6c040..4df67943e8ea 100644
--- a/maven-core/src/main/java/org/apache/maven/internal/impl/InternalMavenSession.java
+++ b/maven-core/src/main/java/org/apache/maven/internal/impl/InternalMavenSession.java
@@ -23,6 +23,7 @@
import org.apache.maven.api.Project;
import org.apache.maven.api.RemoteRepository;
import org.apache.maven.api.Session;
+import org.apache.maven.api.annotations.Nullable;
import org.apache.maven.execution.MavenSession;
import static org.apache.maven.internal.impl.Utils.cast;
@@ -35,6 +36,10 @@ static InternalMavenSession from(Session session) {
List getProjects(List projects);
+ /**
+ * May return null if the input projcet is null or is not part of the reactor.
+ */
+ @Nullable
Project getProject(org.apache.maven.project.MavenProject project);
List toArtifactRepositories(
diff --git a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
index f840bc4dbb8a..4c8c9080dc0b 100644
--- a/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
+++ b/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java
@@ -692,7 +692,9 @@ private InterimResult build(
// In case the model is using CI friendly versions, at this point, it will contain uninterpolated version
// such as ${revision}${changelist}, so we need to take care of it now
Model modelWithVersion = getModelWithInterpolatedVersion(model, result.getProblems()::add);
- modelPool.put(model.getPomFile(), modelWithVersion);
+ if (model.getPomFile() != null) {
+ modelPool.put(model.getPomFile(), modelWithVersion);
+ }
InterimResult interimResult = new InterimResult(pomFile, modelBuildingRequest, result, project, isRoot);