我得到一个试图调用java方法的java.lang.NoSuchMethodError。据我所知,类路径在编译时和运行时是相同的,因此不应发生此错误。
复制步骤:
创建4个Maven项目:
我的图书馆
扩展显示
延伸导弹
用户代码
modulesExtensionPresentExtensionMissing导出相同的模块名。
ExtensionMissing出口:

package dummy;

public class Extension {}

ExtensionPresent出口:
package dummy;

public class Extension {

    public static void present() {
        System.out.println("Extension present!");
    }
}

MyLibrary声明ExtensionMissing为依赖项。
UserCode声明MyLibrary为依赖项。
UserCode.main()调用Extension.present()。这会触发编译时错误,因为ExtensionMissing不包含此方法。
有趣的是…在UserCode项目中,在ExtensionPresent之后添加MyLibrary作为依赖项。
我不再得到编译器错误(该方法现在在编译时出现)。
当我尝试调用UserCode.main()时,我得到:
--- exec-maven-plugin:1.6.0:exec (default-cli) @ mavenproject3 ---
Exception in thread "main" java.lang.NoSuchMethodError: dummy.Extension.present()V

这是我的项目配置、Maven的实现还是JDK工具中的一个bug?
(另一方面,我这样做是为了解决:Implementing a (compile-time) plugin architecture without split packages
更新:这里是一个可执行的测试用例:https://github.com/cowwoc/exec-maven-plugin-class-shadowing

最佳答案

当我启用调试日志记录时,我看到插件启动以下命令:
compiler-maven-plugin正在调用:javac -d ~/UserCode/target/classes -classpath ~/UserCode/target/classes: --module-path ~/.m2/repository/ExtensionPresent/1.0-SNAPSHOT/ExtensionPresent-1.0-SNAPSHOT.jar:~/.m2/repository/MyLibrary/1.0-SNAPSHOT/MyLibrary-1.0-SNAPSHOT.jar:~/.m2/repository/ExtensionMissing/1.0-SNAPSHOT/ExtensionMissing-1.0-SNAPSHOT.jar: -sourcepath ~/UserCode/src/main/java:~/UserCode/target/generated-sources/annotations: -s ~/UserCode/target/generated-sources/annotations -g -nowarn -target 9 -source 9 -encoding UTF-8
maven-exec-plugin正在调用java, --module-path, ~/UserCode/target/classes:~/.m2/repository/MyLibrary/1.0-SNAPSHOT/MyLibrary-1.0-SNAPSHOT.jar:~/.m2/repository/ExtensionMissing/1.0-SNAPSHOT/ExtensionMissing-1.0-SNAPSHOT.jar:~/.m2/repository/ExtensionPresent/1.0-SNAPSHOT/ExtensionPresent-1.0-SNAPSHOT.jar, -m, UserCode/com.usercode.Main]
这使我相信maven-exec-plugin以错误的顺序列出依赖项。我尝试手动调用应用程序,交换依赖项的顺序,并确保程序运行正常。
我对maven exec插件提交了bug report
我针对maven编译器插件提交了第二个bug report文件,因为它似乎还根据项目目录的名称(奇怪但正确)将错误的顺序传递给了javac

10-08 14:44