java 是否可以在 javac(JDK 9)中混合使用 --class-path 和 --module-path?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/46288170/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is it possible to mix --class-path and --module-path in javac (JDK 9)?
提问by malloc4k
When I compile a module that depends on other modules I've compiled previously I have to specify the --module-path <directory>
option. This makes modules I depend on visible.
当我编译一个依赖于我之前编译过的其他模块的模块时,我必须指定该--module-path <directory>
选项。这使我依赖的模块可见。
But at the same time I would also like to make some non-modular Jar files visible. However if don't make them automatic modules and just specify the --class-path some.jar
right next to --module-path <directory>
, then javacseems to ignore the claspath and throws "package yyy not found" and other "not found" errors.
但同时我也想让一些非模块化的 Jar 文件可见。但是,如果不使它们成为自动模块,而只是在--class-path some.jar
旁边指定右侧--module-path <directory>
,那么javac似乎会忽略 claspath 并抛出“未找到包 yyy”和其他“未找到”错误。
I can understand that using --class-path
and --module-path
at the same (compile) time is illegal, but javacdoes not warn me against it in any way.
我可以理解在同一(编译)时使用--class-path
和--module-path
是非法的,但javac不会以任何方式警告我。
回答by Nicolai
You can use class path and module path in parallel, but there are a few details to consider.
您可以并行使用类路径和模块路径,但需要考虑一些细节。
Dependency Module Path ~> Class Path
依赖模块路径 ~> 类路径
Explicit modules (JARs with a module descriptor on the module path) can not read the unnamed module (JARs on the class path) - that was done on purpose to prevent modular JARs from depending on "the chaos of the class path".
显式模块(模块路径上带有模块描述符的 JAR)无法读取未命名的模块(类路径上的 JAR)——这样做是为了防止模块化 JAR 依赖于“类路径的混乱”。
Since a module must require all of its dependencies and those can only be fulfilled by other named modules (i.e. not JARs on the class path) all dependencies of a modular JAR must be placed on the module path. Yes, even non-modular JARs, which will then get turned into automatic modules.
由于一个模块必须需要它的所有依赖项,而且这些依赖项只能由其他命名模块(即不是类路径上的 JAR)来实现,因此模块化 JAR 的所有依赖项都必须放在模块路径上。是的,即使是非模块化 JAR,也会变成自动模块。
The interesting thing is that automatic modules canread the unnamed module, so theirdependencies can go on the class path.
有趣的是,自动模块可以读取未命名的模块,因此它们的依赖项可以放在类路径上。
Dependency Class Path ~> Module Path
依赖类路径 ~> 模块路径
If you compile non-modular code or launch an application from a non-modular JAR, the module system is still in play and because non-modular code does not express any dependencies, it will not resolve modules from the module path.
如果您编译非模块化代码或从非模块化 JAR 启动应用程序,则模块系统仍在运行,并且由于非模块化代码不表示任何依赖项,因此不会从模块路径解析模块。
So if non-modular code depends on artifacts on the module path, you need to add them manually with the --add-modules
option. Not necessarily all of them, just those that you directly depend on (the module system will pull in transitive dependencies) - or you can use ALL-MODULE-PATH
(check the linked post, it explains this in more detail).
因此,如果非模块化的代码依赖于模块路径上的文物,你需要用手动添加的--add-modules
选项。不一定是所有的,只是你直接依赖的那些(模块系统将引入传递依赖) - 或者你可以使用ALL-MODULE-PATH
(查看链接的帖子,它更详细地解释了这一点)。
回答by Naman
I believe using the --classpath
and --module-path
options at the same time is not illegal. It's possible to use both at the same time as even when you don't explicitly specify a classpath it defaultsto the current directory.
我相信同时使用--classpath
和--module-path
选项并不违法。即使您没有明确指定默认为当前目录的类路径,也可以同时使用两者。
Details from the javac -help
message and javac tools docs-
javac -help
消息和javac 工具文档中的详细信息-
--module-path <path>, -p <path>
Specify where to find application modules
指定在哪里可以找到应用程序模块
--class-path <path>, -classpath <path>, -cp <path>
Specify where to find user class files and annotation processors
指定在哪里可以找到用户类文件和注释处理器
If
--class-path
,-classpath
, or-cp
aren't specified, then the user class path is the current directory.
如果
--class-path
,-classpath
或者-cp
未指定,则用户类路径是当前目录。
Edit: Thanks to @MouseEvent, I'd probably missed out the part in the question
编辑:感谢@MouseEvent,我可能错过了问题中的部分
However if don't make them automatic modules and just specify the --class-path some.jar right next to --module-path , then javac seems to ignore the claspath and throws "package yyy not found" and other "not found" errors.
但是,如果不使它们成为自动模块,而只是在 --module-path 旁边指定 --class-path some.jar ,那么 javac 似乎忽略了 claspath 并抛出“package yyy not found”和其他“not found” ”的错误。
If you don't make them automatic, it's treated as an Module System's unnamed moduleand -
如果你不让它们自动,它会被视为模块系统的未命名模块并且 -
A named module cannot, in fact, even declare a dependence upon the unnamed module. This restriction is intentional, since allowing named modules to depend upon the arbitrary content of the class path would make reliable configuration impossible.
事实上,命名模块甚至不能声明对未命名模块的依赖。这个限制是有意的,因为允许命名模块依赖于类路径的任意内容会使可靠的配置变得不可能。
Moreover, the unnamedmodule exports all of its packages hence the code in an automaticmodules will be able to access any public type loaded from the classpath.
此外,未命名模块导出其所有包,因此自动模块中的代码将能够访问从类路径加载的任何公共类型。
But an automatic module that makes use of types from the classpath must not expose those types to the explicit modules that depend upon it, since explicit modules cannot declare dependencies upon the unnamed module.
但是使用类路径中的类型的自动模块不能将这些类型暴露给依赖它的显式模块,因为显式模块不能声明对未命名模块的依赖关系。
If code in the explicit module
com.foo.app
refers to a public type incom.foo.bar
, e.g., and the signature of that type refers to a type in one of the JAR files still on the class path, then the code incom.foo.app
will not be able to access that type sincecom.foo.app
cannot depend upon the unnamed module.
例如,如果显式模块中的代码
com.foo.app
引用 中的公共类型com.foo.bar
,并且该类型的签名引用仍位于类路径中的 JAR 文件之一中的类型,则 中的代码com.foo.app
将无法访问该类型,因为com.foo.app
不能依赖于未命名的模块。
This can be remedied by treating com.foo.app
as an automatic module temporarily so that its code can access types from the class path, until such time as the relevant JAR file on the class path can be treated as an automatic module or converted into an explicit module.
这可以通过com.foo.app
暂时将其视为自动模块来解决,以便其代码可以从类路径访问类型,直到类路径上的相关 JAR 文件可以被视为自动模块或转换为显式模块为止。