Skip to content

Commit f84bcc9

Browse files
dmealingclaude
andcommitted
fix(maven-plugin): a relative <sourceDir> resolved against the shell's working directory, not the module
AbstractMetaDataMojo.getSourceDir() did new File(<sourceDir>), which resolves against the JVM's working directory. Maven keeps the reactor root as the working directory for every module, so the documented <sourceDir>src/main/metaobjects</sourceDir> failed "SourceDir [...] does not exist" in any multi-module build run from the parent, and under mvn -f <module>/pom.xml. A relative <sourceDir> now resolves against ${project.basedir}, as every relative path in a pom does; an absolute one is unchanged. The resolved path is what reaches the loader, so <sources> entries under it resolve correctly too. The plugin's own test had recorded the old behavior in a comment ("paths here are ABSOLUTE on purpose") instead of fixing it. New test pins the relative case (red before, green after); maven-plugin suite 46/0. Found building an adopter estate's Java port with mvn -f from its root; that build now passes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent 5825f05 commit f84bcc9

3 files changed

Lines changed: 45 additions & 5 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,15 @@ edit (two registered `description` strings) and was ruled a hold, as 1.0.4's was
292292
reject both; the answers are truthful, and an adopter who wants the 400 owns that generator.
293293
**Adopters with committed generated code should run `mvn metaobjects:generate`.**
294294

295+
- **Maven plugin: a relative `<sourceDir>` resolved against the shell's working directory,
296+
not the module.** The documented `<sourceDir>src/main/metaobjects</sourceDir>` therefore
297+
failed `SourceDir [src/main/metaobjects] does not exist` in any multi-module reactor build
298+
run from the parent (Maven keeps the root as the working directory for every module) and
299+
under `mvn -f <module>/pom.xml`. It now resolves against `${project.basedir}`, as every
300+
relative path in a pom does; an absolute `<sourceDir>` is unchanged. The plugin's own test
301+
had pinned the old behavior in a comment ("paths here are ABSOLUTE on purpose") instead of
302+
fixing it. Nothing to do on upgrade.
303+
295304
- **TypeScript: two `@metaobjectsdev/runtime-ts` writable mounts answered `PUT` with a 404.**
296305
The cross-port REST contract (FR-008) makes the update verb reachable via BOTH `PATCH`
297306
and `PUT`, routed to one handler, and every other port's controller maps both. The

‎server/java/maven-plugin/src/main/java/com/metaobjects/mojo/AbstractMetaDataMojo.java‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ protected MetaDataLoader createLoader(ClassLoader projectClassLoader) {
278278
String sourceDir = null;
279279
File srcDir = getSourceDir();
280280
if (srcDir != null) {
281-
sourceDir = loaderConfig.getSourceDir();
281+
sourceDir = srcDir.getPath(); // basedir-resolved, not the pom's raw string
282282
}
283283

284284
// Precedence ladder (spec §5): when the pom names neither <sourceDir> nor
@@ -532,11 +532,21 @@ protected void addDirIfExists(List<String> classpathElements, String s) {
532532
if ( f.exists() ) classpathElements.add( f.getPath() );
533533
}
534534

535+
/**
536+
* The pom's {@code <sourceDir>}, a relative one resolved against the module basedir the
537+
* way every relative path in a pom is. {@code new File(relative)} alone resolves against
538+
* the JVM's working directory, which in a reactor build is the PARENT for every module —
539+
* so the documented {@code <sourceDir>src/main/metaobjects</sourceDir>} failed "does not
540+
* exist" from the root, and under {@code mvn -f <module>/pom.xml}.
541+
*/
535542
protected File getSourceDir() {
536543
String srcDir = loaderConfig.getSourceDir();
537544
File sourceDir = null;
538545
if ( srcDir != null ) {
539-
sourceDir = new File( loaderConfig.getSourceDir() );
546+
sourceDir = new File( srcDir );
547+
if ( !sourceDir.isAbsolute() && project != null && project.getBasedir() != null ) {
548+
sourceDir = new File( project.getBasedir(), srcDir );
549+
}
540550
if ( !sourceDir.exists() ) {
541551
getLog().error( "SourceDir ["+srcDir+"] did not exist: "+sourceDir.getPath() );
542552
throw new IllegalArgumentException( "SourceDir [" + srcDir + "] does not exist" );

‎server/java/maven-plugin/src/test/java/com/metaobjects/mojo/SourceDirWithoutSourcesTest.java‎

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,11 @@
3939
* that does not exist (already loud, an {@code IllegalArgumentException} naming the
4040
* path), and one that exists but holds no metadata at all.
4141
*
42-
* <p>Paths here are ABSOLUTE on purpose — {@code <sourceDir>} resolves against the
43-
* process working directory, not the module basedir, so a relative path in a test
44-
* would be measuring the runner's cwd rather than the mojo.
42+
* <p>A RELATIVE {@code <sourceDir>} resolves against the module basedir, as every
43+
* relative path in a pom does. It used to resolve against the process working
44+
* directory, so the documented {@code src/main/metaobjects} failed with "does not
45+
* exist" in any reactor build run from the parent — {@code mvn} keeps the root as the
46+
* working directory for every module — and under {@code mvn -f <module>/pom.xml}.
4547
*/
4648
public class SourceDirWithoutSourcesTest {
4749

@@ -93,6 +95,25 @@ public void sourceDirAloneLoadsThatDirectorysMetadata() throws IOException {
9395
}
9496
}
9597

98+
@Test
99+
public void aRelativeSourceDirResolvesAgainstTheModuleBasedirNotTheWorkingDirectory() throws IOException {
100+
Path root = Files.createTempDirectory("mo-mojo-srcdir-relative-").toAbsolutePath().normalize();
101+
try {
102+
Path metaDir = root.resolve("src/main/metaobjects");
103+
Files.createDirectories(metaDir);
104+
Files.write(metaDir.resolve("meta.widget.json"), WIDGET_JSON.getBytes(StandardCharsets.UTF_8));
105+
106+
// The test JVM's working directory is this plugin module, never `root`.
107+
MetaDataGeneratorMojo mojo = mojoWithSourceDirOnly(root, "src/main/metaobjects");
108+
MetaDataLoader loaded = mojo.createLoader(mojo.createProjectClassLoader());
109+
110+
assertEquals(1, loaded.getMetaObjects().size());
111+
assertEquals("Widget", loaded.getMetaObjects().get(0).getShortName());
112+
} finally {
113+
deleteRecursive(root);
114+
}
115+
}
116+
96117
@Test
97118
public void aSourceDirThatDoesNotExistFailsRatherThanLoadingNothing() throws IOException {
98119
Path root = Files.createTempDirectory("mo-mojo-srcdir-missing-").toAbsolutePath().normalize();

0 commit comments

Comments
 (0)