【问题标题】:Optional dependency using modular programming in Java 9 not working with provided module path在 Java 9 中使用模块化编程的可选依赖项不适用于提供的模块路径
【发布时间】:2018-01-26 10:46:31
【问题描述】:

我在~/Desktop/src目录下写了两个模块的源码

模块myModuleA的代码

M1.java

package myPack1;
import myPack2.M2;
public class M1
{   
   public static void main(String[] args)   
   {    
     System.out.println("I am M1"); 
     M2.print(); 
     System.out.println("I am M1 Again");
   }
}

模块信息.java

module myModuleA
{
      requires myModuleB;
}

模块myModuleB的代码

M2.java

package myPack2;
public class M2
{   
   public static void print()   
   {    
     System.out.println("I am M2"); 
   }
}

模块信息.java

module myModuleB
{
      exports myPack2;
}

我将这两个模块编译为:

gyan@#ns:~/Desktop$ javac --module-source-path src -d out -m myModuleA,myModuleB

在桌面上创建目录out,这是我当前的目录。

此后,我在桌面上创建了另一个名为 OtherModule 的目录。将myModuleB的编译模块目录从目录中剪切并粘贴到OtherModule目录下。从目录 src 中删除了模块 myModuleB 的源目录。把目录删了。

我再次将模块 myModuleA 与模块 myModuleB 的编译代码编译为:

gyan@#ns:~/Desktop$ javac --module-source-path src --module-path OtherModule -d out -m myModuleA

并成功执行代码为:

gyan@#ns:~/Desktop$ java --module-path out/:OtherModule/ -m myModuleA/myPack1.M1
I am M1
I am M2
I am M1 Again
gyan@#ns:~/Desktop$ 

但是后来我把模块myModuleA的module-info.java文件改成了:

module myModuleA
{
    requires static myModuleB;
}

我再次删除了目录并将代码编译为:

gyan@#ns:~/Desktop$ javac --module-source-path src --module-path OtherModule -d out -m myModuleA

代码编译成功。然后我尝试将代码执行为:

gyan@#ns:~/Desktop$ java --module-path out/:OtherModule/ -m myModuleA/myPack1.M1
I am M1
Exception in thread "main" java.lang.NoClassDefFoundError: myPack2/M2
    at myModuleA/myPack1.M1.main(M1.java:8)
Caused by: java.lang.ClassNotFoundException: myPack2.M2
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:185)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:496)
    ... 1 more
gyan@#ns:~/Desktop$ 

这个错误背后的原因是什么,即使我提供了两个编译模块的路径。

【问题讨论】:

  • --upgrade-module-path 用于您的示例的目的是什么?如果你只是让它成为--module-path,会发生什么?
  • myModuleB 是可观察的,但除非某些模块需要它,否则它不会被解析。如果 myModuleB 已解析,则 myModuleA 将读取它)。所以将--add-module myModuleB 添加到命令行,我认为它会起作用。顺便说一句:在这些示例中使用 --upgrade-module-path 的原因是什么?您覆盖了哪些 JDK 模块。
  • @nullpointer 这个问题怎么重复?那个问“X 存在吗?”,这个“当做 X 时,为什么 Y 不工作?”。尽管他们的答案可能部分重叠,但这些是完全不同的角度,没有人遇到 OP 的问题会认为答案隐藏在“X 存在吗?”中。
  • @AlanBateman 是的,它有效。并且无需使用--upgrade-module-path。我们可以使用 --module-path 代替。这是存储在我的终端中的命令,所以我正在重用它。我将更改我的问题并使用--module-path 而不是--upgrade-module-path。谢谢。
  • @nullpointer 正如 Nicolai 所说,这是完全不同的问题。在写这篇文章之前我已经看过这个问题了。

标签: java java-9 modularity


【解决方案1】:

Optional dependencies are not resolved on their own - 即使它们存在于模块路径中。如果它们没有被解决,它们就不会进入readability graph,因此它们在运行时不可用 - 因此会出现错误消息。

对于在运行时可用的可选依赖项,它必须是第三模块非可选要求的、在服务绑定期间解决的,或者added manually with --add-modules

【讨论】:

  • 真的--add-exports?链接的锚点提示 --add-module,这更有意义(尽管当我点击链接时,锚点似乎不存在)。
  • @StephanHerrmann,感谢您指出这些错误,我已修复它们。
猜你喜欢
  • 2019-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多