Using Module System (JPMS): module-info.java for JDBC in Java 9
module-info.java — Using JPMS for JDBC in Java 9
Using Module System (JPMS): module-info.java for JDBC in Java 9
यह article students और developers के लिए बनाया गया है जो Java 9 के Module System (JPMS) में JDBC setup समझना चाहते हैं।
हम step-by-step बताएँगे कि कैसे module-info.java लिखें, driver modules को register करें, और common issues को fix करें।
Why modules matter for JDBC
Java 9 के साथ JPMS लाया गया और classpath की जगह module-path आया। यह security, encapsulation और dependency management को improve करता है।
JDBC जैसे runtime service-provider mechanisms को module-aware बनाना जरूरी है ताकि Driver discovery सही से हो।
Core concepts you must know
- Module: एक नाम दिया हुआ logical unit (module) जिसमें packages और module descriptor होता है।
module-info.java: हर modular jar का descriptor, जो dependencies और services बताता है।- module-path vs classpath: modules को module-path पर रखना recommended है।
- ServiceLoader & Service Provider: JDBC drivers को service provider के रूप में register किया जाता है।
Primary Keywords & LSI (natural inclusion)
यह article natural तरीके से module-info.java, JPMS, java.sql, DriverManager, ServiceLoader, automatic-module-name, module-path, requires, provides, uses, exports, modular JAR और non-modular JAR जैसे terms cover करेगा।
Basic module-info.java for a JDBC application
सबसे पहले application module का सबसे simple descriptor देखने दें। Application को JDBC API चाहिए, इसलिए requires java.sql; लिखना होगा।
module com.example.app {
requires java.sql;
// अगर आप driver module का नाम जानते हो तो उसे भी add करो
// requires com.mysql.cj; // उदाहरण के लिए
}
ऊपर का module-info.java बताता है कि application JDBC API पर निर्भर है।
Driver-specific dependency तभी add करें जब driver एक proper modular jar है और module name पता हो।
Driver module — अगर आप अपना driver बना रहे हों
अगर आप अपना custom JDBC driver बना रहे हैं तो उसे Service Provider के रूप में declare करना होगा ताकि DriverManager उसे खोज सके।
module com.example.myjdbc {
requires java.sql;
exports com.example.myjdbc.api;
provides java.sql.Driver with com.example.myjdbc.impl.MyDriver;
}
यहां provides बताता है कि यह module java.sql.Driver का implementation उपलब्ध कराता है।
ServiceLoader और DriverManager दोनों JPMS-aware होते हुए provider को load कर पाएँगे।
Non-modular driver jars (common case)
अक्सर आपका JDBC driver अभी modular नहीं होता; वह traditional jar होता है। ऐसे jars के लिए two options हैं:
- Classpath पर रखना: पुराने तरीके जैसा काम करेगा — लेकिन module benefits नहीं मिलेंगे।
- Module-path पर रखना with automatic-module-name: अगर jar में
Automatic-Module-Nameहै तो वह module बन जाएगा और आप उसेrequiresमें use कर सकते हैं।
automatic-module-name कैसे काम करता है
अगर किसी non-modular jar में MANIFEST.MF में Automatic-Module-Name: com.mysql.cj दिया हो तो Java उस jar को module-path पर रखते ही module नाम assign कर देता है।
फायदा यह है कि आप module-info.java में उसे requires com.mysql.cj; लिख सकते हैं।
Example: MySQL driver के साथ application
मान लो आपने MySQL JDBC driver को module-path पर रखा और उसका automatic-module-name mysql.connector.java है। तब application module ऐसा दिखेगा:
module com.example.app {
requires java.sql;
requires mysql.connector.java;
}
यहाँ application direct driver पर निर्भर है और compiler/runtime दोनों को पता है कि कौन-कौन से modules चाहिए।
Driver discovery — किस तरह DriverManager काम करता है
पहले के Java versions में DriverManager drivers को META-INF/services के जरिए ढूँढता था।
JPMS में भी यही mechanism है, पर provider modules को explicit तौर पर resolve होना चाहिए या service provider के रूप में declare किया होना चाहिए।
जब driver module provide नहीं करता
अगर driver jar सिर्फ classpath पर है और module-path पर नहीं, तब भी DriverManager many cases में driver register कर देता है क्योंकि driver खुद अपने static initializer में register कर सकता है।
पर module-path पर होने पर proper provides declaration recommended है ताकि ServiceLoader JPMS-aware तरीके से काम करे।
Practical steps — setup checklist
- Driver jar identify करो: modular है या non-modular?
- अगर modular है: उसके module name note करो और application
requiresमें डालो। - अगर non-modular है: दो options — classpath पर रखो (compatible), या module-path पर रखो और automatic-module-name का use करो।
- Driver development करते हो तो
provides java.sql.Driver with ...add करो। - Run करते वक्त
--module-pathऔर--add-modulesflags सही ढंग से use करो।
Run-time examples (javac and java)
Compilation (source modular):
javac -d out --module-source-path src $(find src -name "*.java")
Run (module path):
java --module-path out:lib/mysql-connector.jar --module com.example.app/com.example.app.Main
उपर्युक्त command में driver jar अगर lib में है और module-path पर रखा है तो Driver discovery का chance बढ़ जाता है।
Common module-info.java patterns for JDBC apps
- Simple app:
requires java.sql; - App explicitly needing driver module:
requires mysql.connector.java; - App exposing own DB API:
exports com.example.app.db;
module com.example.app {
requires java.sql;
requires mysql.connector.java; // अगर modular driver है
exports com.example.app.db;
}
छोटे, clear descriptors से compiler और runtime दोनों को मदद मिलती है।
Table: module-path vs classpath (JDBC context)
| Feature | module-path | classpath |
|---|---|---|
| Encapsulation | Yes | No |
| Service discovery | JPMS-aware ServiceLoader (requires provides/uses) | Traditional META-INF/services or driver static registration |
| Automatic-module-name | Works | Irrelevant |
| Compatibility | Better for modular jars | Better for old legacy jars |
Troubleshooting: common errors and fixes
Error: java.sql.SQLException: No suitable driver
Fixes:
- Driver jar module-path/classpath में शामिल है या नहीं check करो।
- Driver modular है तो उसके module name को
requiresमें जोड़ो। - Driver non-modular है और module-path पर रखा है तो
Automatic-Module-Nameसही है या नहीं देखें। - Driver self-registration (static block) पर rely मत करो — JPMS में provide declaration safer है।
Error: ServiceConfigurationError या provider load fail
Fixes:
- Driver module में
provides java.sql.Driver with ...मौजूद है या नहीं देखें। - Jar के META-INF/services/java.sql.Driver entry सही class का नाम दिखा रही है या नहीं check करो (non-modular jars के लिये)।
Example: module-info for a packaged MySQL driver (hypothetical)
module mysql.connector.java {
exports com.mysql.cj;
requires transitive java.sql; // driver itself uses java.sql
provides java.sql.Driver with com.mysql.cj.jdbc.Driver;
}
यह descriptor driver को एक proper service provider बनाता है।
Notes on DriverManager and ServiceLoader interaction
DriverManager internally ServiceLoader का use कर सकता है जब modules resolved हों। JPMS में service providers तब ही discover होते हैं जब provider modules module layer में resolved हों।
इसलिए runtime में modules को सही तरह से resolve करना ज़रूरी है — वरना DriverManager driver न पा सकेगा।
When to prefer module-path for drivers
- अगर driver modular है — module-path बेहतर है।
- यदि आप encapsulation और strict dependencies चाहते हैं — module-path लें।
- Legacy project जहाँ many non-modular jars हों, classpath रखना practical होता है।
Best practices checklist (exam-useful points)
- Always declare
requires java.sql;in application module that uses JDBC. - Driver authors should use
provides java.sql.Driver with <impl-class>. - Library jars में possible हो तो
Automatic-Module-Nameशामिल करें। - Run-time पर
--module-pathऔर module main specify करें:--module com.example.app/com.example.app.Main. - जब error आये तो module resolution और service files (META-INF/services) check करें।
Sample full example — small project layout
project structure (simple):
project/
├─ src/
│ ├─ com.example.app/
│ │ ├─ module-info.java
│ │ └─ com/example/app/Main.java
│ └─ com.example.myjdbc/
│ ├─ module-info.java
│ └─ com/example/myjdbc/impl/MyDriver.java
└─ lib/
└─ mysql-connector.jar (optional)
इस layout से आप modular app और driver दोनों दिखा सकते हैं।
module-info.java examples summary
Application:
module com.example.app {
requires java.sql;
// requires mysql.connector.java; // optional, depends on driver modularity
}
Driver:
module com.example.myjdbc {
requires java.sql;
provides java.sql.Driver with com.example.myjdbc.impl.MyDriver;
}
Exam-style short notes (bullet-ready)
- JPMS = Java Platform Module System, Java 9 में आया।
module-info.javadefines module name, requires, exports, provides, uses।- JDBC API package =
java.sql; application मेंrequires java.sql;ज़रूरी। - Driver discovery uses ServiceLoader / META-INF/services / provides mechanism।
- Non-modular jars के लिए
Automatic-Module-Namehelpful। - Run-time flags:
--module-path,--add-modules, और--module।
Quick checklist before exam or deployment
- module names सही हैं और conflicts नहीं हैं।
- driver registered via
providesया META-INF/services मौजूद है। - module-path में सभी required jars मौजूद हों।
- यदि mixing classpath और module-path कर रहे हो तो known pitfalls समझो।
- error logs में module resolution या ServiceConfiguration errors देखें।
Small FAQ-like reminders (short points only)
- Q: क्या driver jar classpath पर होना चाहिए या module-path पर?
A: दोनों possible हैं; modular jars के लिए module-path recommended है। - Q: DriverManager JPMS में काम करेगा?
A: हाँ, अगर providers properly resolved और declared हों।
Advanced tip: shadowing और automatic modules
कभी-कभी दो अलग jars का automatic module name same हो सकता है — यह conflict पैदा कर सकता है। इसलिए production में verified module names use करें।
अगर आप shading करते हो (one-jar bundling) तो service files और module descriptors सही merge हों यह confirm करें।
Notes for graders / exam markers
इस article में दिए गए code snippets और tables practical scenario पर आधारित हैं। module-info.java के examples basic से लेकर driver provider तक cover करते हैं।
Students को recommended है कि वे small modular demo बनाकर ऊपर के commands try करें — theory के साथ practical याद जल्दी रहती है।
Quick reference: commands & flags
- Compile modules:
javac -d out --module-source-path src $(find src -name "*.java") - Run module:
java --module-path out:lib/* --module com.example.app/com.example.app.Main - Classpath fallback:
java -cp app.jar:lib/* com.example.app.Main
Final exam-style notes (short, copy-ready)
- Definition:
module-info.javais the module descriptor in JPMS. - JDBC dependency: Always include
requires java.sql;in app module. - Service provider: Driver modules should declare
provides java.sql.Driver with <impl>. - Non-modular jars: Use classpath or automatic-module-name on module-path.
- Runtime: Use
--module-pathand--moduleto run modular apps.