2017-09-18 126 views
9

当我编译一个依赖于我以前编译的其他模块的模块时,我必须指定--module-path <directory>选项。这使得我依赖的模块可见。是否可以在javac(JDK 9)中混合使用--class-path和--module-path?

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

我可以理解,使用--class-path--module-path在同一(编译)时间是非法的,但的javac不提醒我反对以任何方式。

+0

有可能混合两者,你可以分享一个我们可以验证的最小例子吗? –

+0

*我可以理解,在同一(编译)时间使用--class-path和--module-path是非法的,*为什么会这样呢? – nullpointer

+5

混合是绝对合法的。但是,模块化jar无法在类路径中引用非模块化jar。自动模块(模块路径上的非模块化jar)充当桥接器:模块化jars_can_引用它们,自动模块可以读取类路径。 –

回答

14

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

依赖模块路径〜>类路径

显式模块(与模块路径上的模块描述符的JAR)不能读取无名模块(类路径上的JAR) - 这是故意以防止模块化做JAR取决于“班级路径的混乱”。

由于模块必须要求其所有依赖关系,并且只能由其他命名模块(即类路径上不包含JAR)来实现,因此必须将模块JAR的所有依赖关系置于模块路径上。是的,即使是非模块化的JAR,它也会变成automatic modules

有趣的是,自动模块可以阅读无名模块,所以他们依赖性可以去在类路径上。

依赖类路径〜>模块路径

如果您编译非模块化的代码或从非模块化的JAR启动一个应用程序,该模块系统仍然在发挥作用,并因为非模块化的代码不表达任何依赖关系,它不会从模块路径解析模块。

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

+5

Nicolai - 你的回答是正确的,但我认为可以扩展指出'--add-modules'选项可能需要确保类路径代码所需的模块得到解决。原始问题问为什么javac失败,我认为这是因为他/她正在编译类路径上的代码,并引用模块路径中的模块中的类,只需要'--add-modules'来确保模块已解析。 –

+0

我认为OP正在尝试编译带有非模块化依赖项的模块化代码 - 无论哪种方式,我都会添加其他方向,以确保正确性。 – Nicolai

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并抛出了“未找到包yyy” 和其他“未找到”错误。

如果你没有让他们自动的,它视为一个Module System's unnamed module和 -

命名模块不能,其实连申报于 无名模块依赖。这种限制是有意的,因为允许命名为 的模块依赖于类路径的任意内容,因此 不可能进行可靠的配置。

此外,无名模块导出所有包,因此在一个自动模块的代码将能够访问来自类路径加载的任何公开的类型。

但是,使用来自类路径的类型的自动模块不能将这些类型暴露给依赖它的显式模块,因为显式模块无法声明对未命名模块的依赖关系。

如果显式模块com.foo.app代码是指一个公共型 在com.foo.bar,例如,以及该类型的签名是指 类型的JAR文件仍然类路径上一个,然后com.foo.app中的代码 将无法​​访问该类型,因为 com.foo.app不能依赖未命名的模块。

这可以通过处理com.foo.app作为自动模块暂时使得其代码可以从类路径访问的类型,直到这样的时间作为类路径上的相关的JAR文件来补救可以被视为一种自动模块或转换为显式模块。

+1

更不用说如果它是合法的......未命名模块的整个概念是针对classpath中的jar,并且明确的模块不能访问它们。 – Mordechai

+0

@MouseEvent这是真的。我相信我错过了那部分问题,虽然以前只是回答了标题。编辑以包括这一点。谢谢:) – nullpointer

相关问题