You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by gn...@apache.org on 2026/10/15 07:27:53 UTC
(maven) branch master updated: [MNG-8250] Invoke ModelParser#parse when a parser locates the project directory
This is an automated email from the ASF dual-hosted git repository.
gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven.git
The following commit(s) were added to refs/heads/master by this push:
new fdd7fd62ea [MNG-8250] Invoke ModelParser#parse when a parser locates the project directory
fdd7fd62ea is described below
commit fdd7fd62ea1c732ca3cbd090e03e94f7a359947b
Author: Arturo Bernal <ab...@apache.org>
AuthorDate: Thu Oct 15 09:27:46 2026 +0200
[MNG-8250] Invoke ModelParser#parse when a parser locates the project directory
- DefaultModelProcessor#read was searching the parent of the located path for a model
- When a ModelParser returns the project directory itself as its source (as locateExistingPom allows), the processor was asking parsers to locate in the directory above, so parse was never called and the XML reader failed with "Is a directory"
- Fix: use the path itself when it is a directory
- Regression test added to DefaultModelProcessorTest
---
.../maven/impl/model/DefaultModelProcessor.java | 3 +-
.../impl/model/DefaultModelProcessorTest.java | 49 ++++++++++++++++++++++
2 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelProcessor.java b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelProcessor.java
index c2f37654ad..7784211b4a 100644
--- a/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelProcessor.java
+++ b/impl/maven-impl/src/main/java/org/apache/maven/impl/model/DefaultModelProcessor.java
@@ -99,7 +99,8 @@ public Model read(XmlReaderRequest request) throws IOException {
Objects.requireNonNull(request, "source cannot be null");
Path pomFile = request.getPath();
if (pomFile != null) {
- Path projectDirectory = pomFile.getParent();
+ // a parser may locate the project directory itself rather than a file within it
+ Path projectDirectory = Files.isDirectory(pomFile) ? pomFile : pomFile.getParent();
Map<String, ModelParserException> exceptions = new LinkedHashMap<>();
for (Map.Entry<String, ModelParser> parser : modelParsers.entrySet()) {
try {
diff --git a/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelProcessorTest.java b/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelProcessorTest.java
index bcef6ba41d..1e512c3739 100644
--- a/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelProcessorTest.java
+++ b/impl/maven-impl/src/test/java/org/apache/maven/impl/model/DefaultModelProcessorTest.java
@@ -23,8 +23,11 @@
import java.nio.file.Path;
import java.util.Map;
import java.util.Optional;
+import java.util.concurrent.atomic.AtomicInteger;
import org.apache.maven.api.model.Model;
+import org.apache.maven.api.services.Source;
+import org.apache.maven.api.services.Sources;
import org.apache.maven.api.services.xml.ModelXmlFactory;
import org.apache.maven.api.services.xml.XmlReaderException;
import org.apache.maven.api.services.xml.XmlReaderRequest;
@@ -148,4 +151,50 @@ void testSuccessfulParsingDoesNotThrowException() throws Exception {
assertNotNull(result);
verify(xmlFactory, never()).read(any(XmlReaderRequest.class));
}
+
+ @Test
+ void testParserLocatingProjectDirectoryIsInvokedForDirectorySource() throws Exception {
+ // a non-XML syntax whose "pom" is the project directory itself (e.g. a MANIFEST.MF based project)
+ Path projectDir = Files.createDirectories(tempDir.resolve("project"));
+ Files.createDirectories(projectDir.resolve("META-INF"));
+ Files.writeString(projectDir.resolve("META-INF/MANIFEST.MF"), "Bundle-SymbolicName: test");
+
+ Model parsed = Model.newBuilder()
+ .modelVersion("4.0.0")
+ .groupId("g")
+ .artifactId("a")
+ .version("1")
+ .build();
+ AtomicInteger parseCalls = new AtomicInteger();
+ ModelParser parser = new ModelParser() {
+ @Override
+ public Optional<Source> locate(Path dir) {
+ return Files.isRegularFile(dir.resolve("META-INF/MANIFEST.MF"))
+ ? Optional.of(Sources.fromPath(dir))
+ : Optional.empty();
+ }
+
+ @Override
+ public Model parse(Source source, Map<String, ?> options) {
+ parseCalls.incrementAndGet();
+ return parsed;
+ }
+ };
+
+ ModelXmlFactory xmlFactory = mock(ModelXmlFactory.class);
+ when(xmlFactory.read(any(XmlReaderRequest.class)))
+ .thenThrow(new XmlReaderException("Is a directory", null, null));
+ DefaultModelProcessor processor = new DefaultModelProcessor(xmlFactory, Map.of("manifest", parser));
+
+ Path located = processor.locateExistingPom(projectDir);
+ assertEquals(projectDir, located);
+
+ Model result = processor.read(
+ XmlReaderRequest.builder().path(located).strict(true).build());
+
+ assertEquals(1, parseCalls.get(), "ModelParser#parse should be called for the located source");
+ assertEquals("a", result.getArtifactId());
+ assertEquals(located, result.getPomFile());
+ verify(xmlFactory, never()).read(any(XmlReaderRequest.class));
+ }
}