Java › Java Platform Module System (JPMS)
What is the difference between 'requires' and 'requires transitive', and how does transitive dependency propagation work in the module system?
AdvancedAnswer
A plain requires ModuleName gives your module access to that dependency's exported packages, but does NOT automatically propagate that access to modules that in turn require YOUR module (they'd need their own separate requires declaration for that same dependency if they need to use it directly); requires transitive ModuleName additionally propagates that dependency to any module requiring yours, meaning if module C requires module B (transitively), and module B requires transitive module A, then module C automatically also gains access to module A's exports without needing its own explicit requires A declaration -- this is specifically useful when your module's own public API directly exposes types from a dependency (like a method returning a type from that dependency), since consumers of your API genuinely need access to that dependency's types too, not just your own module's exports.
// module A (a shared library)
module com.example.geometry { exports com.example.geometry; }
// module B, whose PUBLIC API exposes types from module A
module com.example.shapes {
requires transitive com.example.geometry; // propagates geometry access to consumers of shapes
exports com.example.shapes; // shapes' public API includes methods returning geometry types
}
// module C, using shapes
module com.example.app {
requires com.example.shapes;
// Automatically ALSO has access to com.example.geometry's exports, via transitive propagation,
// without needing 'requires com.example.geometry' explicitly here
}Real-world example A shapes library module whose public API methods return types from a separate geometry module uses requires transitive for its geometry dependency, ensuring any consumer of the shapes module automatically gains the necessary access to work with those returned geometry types, without each individual consumer needing to separately discover and declare that same underlying dependency themselves.