परिचय: हज़ारों JARs का अभिशाप
\nक्या आपने कभी ऐसी स्थिति का सामना किया है जब आपका Java प्रोजेक्ट बढ़ता जाता है और lib/ फ़ोल्डर दर्जनों, या सैकड़ों JAR फ़ाइलों का चिड़ियाघर बन जाता है? और हर बार एप्लिकेशन चलाते समय, आपको याद आता है कि कौन सा JAR आपने जोड़ा और कौन सा भूल गए? है ना परिचित?
"Java classpath में एक डायरेक्ट्री के सभी JAR फ़ाइलों को शामिल करना" Stack Overflow पर सबसे लोकप्रिय प्रश्नों में से एक है। और यह कोई आश्चर्य की बात नहीं है। यह एक सामान्य सी लगने वाली समस्या सिरदर्द बन जाती है अगर आप सही टूल्स नहीं जानते। इस लेख में, हम सभी तरीकों पर चर्चा करेंगे: प्राचीन तरीकों से लेकर 2025 में हर स्वाभिमानी Java डेवलपर द्वारा उपयोग किए जाने वाले सबसे आधुनिक तरीकों तक।
\nतैयार हो जाइए, हम classpath के जंगल में एक रोमांचक यात्रा पर निकल रहे हैं!
\n\nयह समस्या क्यों है? (या "-cp" की महागाथा)
\nपुराने ज़माने में (Java 6 से पहले), डेवलपर्स को प्रत्येक JAR फ़ाइल को मैन्युअल रूप से सूचीबद्ध करना पड़ता था। यह कुछ इस तरह दिखता था:
\njava -cp lib/guava.jar:lib/spring-core.jar:lib/log4j.jar:lib/jackson.jar MyApp\nअब कल्पना करें कि आपके पास 30 लाइब्रेरीज़ हैं। एक टाइपिंग की गलती और एप्लिकेशन ClassNotFoundException के साथ क्रैश हो जाता है। बुरा सपना! यही कारण है कि समुदाय ने Java classpath में सभी jar फ़ाइलों को एक लाइन में जोड़ने के तरीके खोजने शुरू कर दिए।
तरीका #1: Wildcard — Java 6 से उद्धारकर्ता
\nJava 6 से शुरू करके, JVM में एक जादुई क्षमता आई — wildcard (वाइल्डकार्ड)। आप बस फ़ोल्डर के पथ के साथ एक तारांकन चिह्न (*) देते हैं, और JVM स्वचालित रूप से वहाँ से सभी JAR फ़ाइलों को लोड कर लेता है।
\nयह कैसे काम करता है:
\njava -cp "lib/*" MyApp\nमहत्वपूर्ण! कोट्स पर ध्यान दें। उनके बिना, कुछ शेल्स (जैसे Unix) में तारांकन शेल द्वारा इंटरप्रेट किया जा सकता है, और आपको वह नहीं मिलेगा जो आप चाहते हैं। कोट्स सुनिश्चित करते हैं कि * सीधे JVM को भेजा जाए।
यह तरीका आज भी प्रासंगिक है। यह सरल, सुरुचिपूर्ण है और 90% समस्याओं को हल करता है। लेकिन एक बात है: wildcard रिकर्सिवली काम नहीं करता। अगर आपके पास नेस्टेड फ़ोल्डर हैं (lib/subdir/), तो उनकी सामग्री लोड नहीं होगी। इसके लिए आपको प्रत्येक स्तर को मैन्युअल रूप से निर्दिष्ट करना होगा:
java -cp "lib/*:lib/subdir/*" MyApp\n\nWildcard का उपयोग कब करें?
\n- \n
- आप एक सरल स्क्रिप्ट या यूटिलिटी लिख रहे हैं। \n
- आपके पास कोई बिल्ड सिस्टम (Maven/Gradle) नहीं है। \n
- आपको जल्दी से कुछ "चालू" करना है। \n
तरीका #2: Maven — उद्योग का मानक
\nअगर आप किसी वास्तविक प्रोजेक्ट पर काम कर रहे हैं, तो आप शायद Maven का उपयोग कर रहे हैं। और "एक फ़ोल्डर से सभी JARs को कैसे शामिल करें" का सवाल यहाँ बिल्ड स्तर पर हल हो जाता है।
\nMaven स्वयं डिपेंडेंसीज़ का प्रबंधन करता है। आप बस उन्हें pom.xml में निर्दिष्ट करते हैं, और Maven आवश्यक JARs डाउनलोड करता है और उन्हें स्वचालित रूप से classpath में जोड़ता है।
pom.xml का उदाहरण:
<dependencies>\n <dependency>\n <groupId>org.springframework.boot</groupId>\n <artifactId>spring-boot-starter-web</artifactId>\n <version>3.2.0</version>\n </dependency>\n <dependency>\n <groupId>com.google.code.gson</groupId>\n <artifactId>gson</artifactId>\n <version>2.10.1</version>\n </dependency>\n</dependencies>\nबिल्ड करते समय (जैसे mvn package), Maven एक fat JAR बनाता है (या maven-dependency-plugin का उपयोग करता है) जिसमें सभी डिपेंडेंसीज़ शामिल होती हैं। अब आपको classpath के बारे में सोचने की ज़रूरत नहीं है — यह अंदर पैक होता है।
लेकिन क्या होगा अगर आपको किसी स्थानीय फ़ोल्डर से सभी JARs को कनेक्ट करना है जो Maven द्वारा प्रबंधित नहीं है? इसके लिए System Dependencies हैं (हालाँकि इसे एंटी-पैटर्न माना जाता है):