是否可以在javac(JDK 9)中混合使用--class-path和--module-path?

时间:2017-09-18 21:02:57

标签: java classpath java-9 module-path

当我编译依赖于我之前编译的其他模块的模块时,我必须指定--module-path <directory>选项。这使我依赖的模块可见。

但与此同时,我还想让一些非模块化的Jar文件可见。但是,如果不使它们成为自动模块,只需在--class-path some.jar旁指定--module-path <directory>,那么 javac 似乎忽略了claspath并抛出“yyy not found”和其他“未找到”的错误。

我可以理解在相同(编译)时使用--class-path--module-path是非法的,但 javac 并不以任何方式警告我。

2 个答案:

答案 0 :(得分:25)

您可以并行使用类路径和模块路径,但需要考虑一些细节。

依赖模块路径〜&gt;类路径

显式模块(模块路径上带有模块描述符的JAR)无法读取未命名的模块(类路径上的JAR) - 这是为了防止模块化JAR依赖于&#34;混乱课程路径&#34;。

由于模块必须要求其所有依赖项,并且那些只能由其他命名模块(即类路径上不是JAR)来实现,因此模块化JAR的所有依赖项必须放在模块路径上。是的,即使是非模块化的JAR,也会变成automatic modules

有趣的是,自动模块可以读取未命名的模块,因此他们的依赖关系可以进入类路径。

依赖类路径〜&gt;模块路径

如果您编译非模块化代码或从非模块化JAR启动应用程序,则模块系统仍在运行,并且由于非模块化代码不表示任何依赖性,因此它不会从模块路径解析模块。

因此,如果非模块化代码依赖于模块路径上的工件,则需要使用the --add-modules option手动添加它们。不一定是所有这些,只是那些你直接依赖的(模块系统会引入传递依赖) - 或者你可以使用ALL-MODULE-PATH(查看链接的帖子,它会更详细地解释这一点)。

答案 1 :(得分:9)

我认为同时使用--classpath--module-path选项 不违法 。即使您没有明确指定默认到当前目录的类路径,也可以同时使用它们。

javac -help消息和javac tools docs -

中的详细信息
--module-path <path>, -p <path>

指定查找应用程序模块的位置

--class-path <path>, -classpath <path>, -cp <path>

指定查找用户类文件和注释处理器的位置

  

如果未指定--class-path-classpath-cp ,则该用户   类路径是当前目录

编辑 :感谢@MouseEvent,我可能错过了问题中的部分

  

但是,如果不让它们成为自动模块,只需指定   --class-path some.jar就在--module-path旁边,然后javac似乎忽略了claspath并且抛出了&#34;包yyy not found&#34;   和其他&#34;未找到&#34;错误。

如果您不自动制作,则将其视为Module System's unnamed module和 -

  实际上,命名模块甚至不能声明对它的依赖   未命名的模块。这种限制是有意的,因为允许命名   模块依赖于类路径的任意内容   使可靠的配置变得不可能。

此外,未命名模块导出其所有包,因此自动模块中的代码将能够访问从类路径加载的任何公共类型。

但是,使用类路径中的类型的自动模块不得将这些类型公开给依赖它的显式模块,因为显式模块不能声明对未命名模块的依赖性。

  

如果显式模块com.foo.app中的代码引用了公共类型   例如,在com.foo.bar中,该类型的签名指的是a   键入仍在类路径上的其中一个JAR文件,然后输入代码   因此,com.foo.app中的com.foo.app将无法访问该类型   com.foo.app不能依赖于未命名的模块。

这可以通过暂时将UploadedFiles视为自动模块来解决,以便其代码可以从类路径访问类型,直到类路径上的相关JAR文件可以被视为自动模块为止或转换为显式模块。