All 15 Java Platform Module System (JPMS) questions
More in Java Platform Module System (JPMS)
Advertisement
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?

Advanced

Answer

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.

Common follow-ups: What would go wrong (a compile error) for a consumer module if 'requires transitive' were used instead of a plain 'requires' in this exact scenario?;How do you decide whether a given dependency should be declared as plain requires or requires transitive?