You are a software architect at a financial firm. Your team is developing a modular Java 17 application that comprises several modules: 'com.bank.core' (provides core banking services), 'com.bank.web' (REST API), and 'com.bank.persistence' (database access). The application uses the 'java.sql' module for JDBC and 'java.logging' for logging. The team uses Maven for dependency management. The application has an external dependency on the 'com.fasterxml.jackson.databind' library (Jackson) for JSON processing, which is provided as a non-modular jar. The Jackson jar is placed on the module path. The application modules are all named modules with module-info files. At runtime, the 'com.bank.web' module requires 'com.bank.core' and 'com.fasterxml.jackson.databind' (the automatic module). The 'com.bank.core' module requires 'java.sql' and 'java.logging'. When the application runs, it throws an 'IllegalAccessError' indicating that the module 'com.bank.core' tries to access a class from 'com.fasterxml.jackson.databind' but the module does not read it. Yet, 'com.bank.web' is the only module that explicitly requires Jackson. What is the most likely cause and the correct resolution?
Direct use requires a requires directive; this resolves the readability chain.
Why this answer
Option B is correct because the error indicates that 'com.bank.core' directly uses classes from 'com.fasterxml.jackson.databind', but its module-info.java does not include a 'requires com.fasterxml.jackson.databind' directive. In the Java module system, a module can only access types from another module if it explicitly reads that module. Since 'com.bank.core' needs Jackson classes at runtime, it must declare the dependency itself, even if another module ('com.bank.web') also requires it.
Exam trap
The trap here is that candidates assume transitive dependencies are automatically resolved by the module system, but in Java modules, each module must explicitly declare its own 'requires' for any module it directly uses, even if another module already requires it.
How to eliminate wrong answers
Option A is wrong because converting all modules to unnamed modules by removing module-info files would defeat the purpose of modularization, breaking encapsulation and potentially causing classpath conflicts; it does not fix the missing 'requires' directive. Option C is wrong because placing the Jackson jar on the classpath instead of the module path would make it an unnamed module, which would still not grant 'com.bank.core' read access to Jackson's packages unless the module reads the unnamed module (via 'requires java.base' or '--add-reads'), and it would also lose the benefits of reliable configuration. Option D is wrong because using jlink to create a custom runtime image does not resolve the missing module readability; jlink only includes modules that are explicitly required, and if 'com.bank.core' does not require Jackson, the error persists.