Question 1
The directory mods holds three compiled modules. Two of them contain the same package, com.shared:
module com.first { exports com.shared; } // contains com.shared.Alpha
module com.second { exports com.shared; } // contains com.shared.Beta
module com.app {
requires com.first; // note: com.second is NOT required
}
package com.app;
import com.shared.Alpha;
public class Main {
public static void main(String[] args) {
System.out.println(Alpha.who()); // Alpha.who() returns "alpha from com.first"
}
}
All three modules were compiled successfully, com.app with --module-path mods. You now run:
java --module-path mods -m com.app/com.app.Main
What happens?
A. It prints
alpha from com.first— com.second is observable but is never resolved, so the module graph that gets built contains no split package.Correct answerCorrect: com.app requires only com.first, so com.second is observable but never resolved and never joins the module graph. The built graph therefore contains no split package and the program prints alpha from com.first.
B. It fails at run time with
NoClassDefFoundError: com/shared/Alpha, because the duplicate package makescom.sharedambiguous to the class loader.Wrong: this imagines the duplicate package is detected lazily at class load. Split packages are checked eagerly when the layer is constructed, and here there is no conflict at all because com.second is never resolved.
C. It fails at startup with
LayerInstantiationException: Package com.shared in both module com.first and module com.second— a split package anywhere on the module path is fatal.Wrong: this names the right exception for the wrong trigger. LayerInstantiationException only fires if com.second is actually resolved (for example via --add-modules); merely sitting on the module path is not enough.
D. It prints
beta from com.second, because when two modules on the module path contain the same package the one found later wins.Wrong: this invents a last-one-wins rule. JPMS has no such precedence; a genuine split-package conflict is an error, never a silent pick, and here com.second is never even resolved.
Explanation
The split-package rule is a constraint on the module graph, not on the module path. It says: no two modules in the same layer may contain the same package. Modules only enter that layer if they are resolved, and resolution starts from the root — here com.app, named by -m — and follows requires edges. com.app requires only com.first, so the resolved graph is {com.app, com.first, java.base}. com.second is observable (it sits on the module path, ready to be found) but nothing pulls it in, so it never joins the graph, and there is no conflict to report. The program runs and prints alpha from com.first.
Why the others are wrong:
It fails at startup with LayerInstantiationException... names the right exception for the wrong trigger — this is the single most instructive distractor here. That exception is exactly what you get if com.second is resolved: java --module-path mods --add-modules com.second -m com.app/com.app.Main dies before main with Error occurred during initialization of boot layer / a java.lang.LayerInstantiationException reporting Package com.shared in both module ... (the JVM names the two modules in an unspecified order). Merely sitting on the module path is not enough.
It prints beta from com.second... invents a last-one-wins rule. There is no such precedence in JPMS; a genuine conflict is an error, never a silent pick.
It fails at run time with NoClassDefFoundError... imagines the conflict is detected lazily, at class load. Split packages are checked eagerly, when the layer is constructed, precisely so that this class of ambiguity can never reach a class loader.
Exam tip: hold observable and resolved apart — it is the distinction this whole question turns on, and it is the same one that makes requires static fail at run time. Also note the compile-time face of the rule: had com.app declared requires com.second; as well, javac would have refused it up front with error: module com.app reads package com.shared from both com.first and com.second.