Skip to content

maven.multiModuleProjectDirectory system property not set — breaks projects using it in POM #3760

@chagong

Description

@chagong

Problem

Projects that reference ${maven.multiModuleProjectDirectory} in their POM (e.g., Apache Dubbo, Google Guava) fail to import. The Maven CLI launcher (mvn) normally sets this as a JVM system property via -Dmaven.multiModuleProjectDirectory=..., but JDTLS does not replicate this behavior.

m2e computes the value per-project via MavenProperties.computeMultiModuleProjectDirectory() and calls request.setMultiModuleProjectDirectory(File), but this does not add it to request.getSystemProperties(). Maven's model interpolator uses system properties to resolve POM expressions, so ${maven.multiModuleProjectDirectory} remains unresolved in the MavenProject model.

Steps to Reproduce

  1. Open Apache Dubbo (git clone https://github.com/apache/dubbo) in VS Code with JDTLS
  2. Wait for project import to complete
  3. dubbo-common fails to configure

Error

org.eclipse.core.runtime.CoreException: Could not update project dubbo-common configuration
Caused by: java.lang.IllegalArgumentException: Path must include project and resource name: /
    at org.eclipse.core.runtime.Assert.isLegal(Assert.java:68)
    at org.eclipse.core.internal.resources.Workspace.newResource(Workspace.java:2274)
    at org.eclipse.core.internal.resources.Container.getFolder(Container.java:211)
    at org.eclipse.m2e.jdt.internal.AbstractJavaProjectConfigurator.getFolder(AbstractJavaProjectConfigurator.java:1007)
    at org.eclipse.m2e.jdt.internal.AbstractJavaProjectConfigurator.addResourceDirs(AbstractJavaProjectConfigurator.java:639)
    at org.eclipse.m2e.jdt.internal.AbstractJavaProjectConfigurator.addProjectSourceFolders(AbstractJavaProjectConfigurator.java:431)
    at org.eclipse.m2e.jdt.internal.AbstractJavaProjectConfigurator.configure(AbstractJavaProjectConfigurator.java:170)
    at org.eclipse.m2e.core.project.configurator.AbstractLifecycleMapping.configure(AbstractLifecycleMapping.java:127)
    at org.eclipse.m2e.core.internal.project.ProjectConfigurationManager.lambda$6(ProjectConfigurationManager.java:506)
    ...
    at org.eclipse.jdt.ls.core.internal.managers.MavenProjectImporter.importToWorkspace(MavenProjectImporter.java:249)
    at org.eclipse.jdt.ls.core.internal.managers.ProjectsManager.importProjects(ProjectsManager.java:169)
    at org.eclipse.jdt.ls.core.internal.managers.ProjectsManager.initializeProjects(ProjectsManager.java:126)

The result is that dubbo-common has no .classpath and loses Java nature entirely:

The 'dubbo-common' project has no .classpath. Removing Java nature and builder.

Root Cause

Dubbo's parent POM declares resource directories using ${maven.multiModuleProjectDirectory}:

<resources>
    <resource>
        <directory>${maven.multiModuleProjectDirectory}</directory>
        <includes>
            <include>NOTICE</include>
            <include>LICENSE</include>
        </includes>
    </resource>
</resources>

Since JDTLS never sets maven.multiModuleProjectDirectory as a system property, the Maven model builder cannot interpolate it. The literal ${maven.multiModuleProjectDirectory} string flows into m2e's AbstractJavaProjectConfigurator.getFolder() which crashes.

Proposed Fix

In StandardPreferenceManager, walk root paths for .mvn/ directories and call System.setProperty("maven.multiModuleProjectDirectory", ...) to mirror the mvn launcher behavior.

Note: This is necessary but not sufficient. m2e also has a bug in AbstractJavaProjectConfigurator.getFolder() that crashes when the resolved resource directory is an ancestor of the project directory — see eclipse-m2e/m2e-core#1790 and fix PR eclipse-m2e/m2e-core#2160.

Environment

  • JDTLS 1.58.0-SNAPSHOT
  • m2e 2.11.0 (bundled)
  • Java 25.0.2 (Eclipse Adoptium)
  • Windows 10, x86_64

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions