java - जावा क्लासपाथ के भीतर निर्देशिका में सभी जार शामिल हैं
command-line classpath (15)
क्या क्लासपाथ में निर्देशिका के भीतर सभी जार फ़ाइलों को शामिल करने का कोई तरीका है?
मैं java -classpath lib/*.jar:. my.package.Program
कोशिश कर रहा हूँ java -classpath lib/*.jar:. my.package.Program
java -classpath lib/*.jar:. my.package.Program
और यह निश्चित रूप से उन जारों में क्लास फ़ाइलों को खोजने में सक्षम नहीं है। क्या मुझे प्रत्येक जार फ़ाइल को क्लासपाथ में अलग से जोड़ने की ज़रूरत है?
/ * To -cp सेट करने में सक्षम होने का प्रत्यक्ष समाधान नहीं है, लेकिन मुझे उम्मीद है कि आप गतिशील वर्ग-पथ और lib निर्देशिकाओं के लिए स्थिति को कम करने के लिए निम्न स्क्रिप्ट का उपयोग कर सकते हैं।
libDir2Scan4jars="../test";cp=""; for j in `ls ${libDir2Scan4jars}/*.jar`; do if [ "$j" != "" ]; then cp=$cp:$j; fi; done; echo $cp| cut -c2-${#cp} > .tmpCP.tmp; export tmpCLASSPATH=`cat .tmpCP.tmp`; if [ "$tmpCLASSPATH" != "" ]; then echo .; echo "classpath set, you can now use ~> java -cp \$tmpCLASSPATH"; echo .; else echo .; echo "Error please check libDir2Scan4jars path"; echo .; fi;
लिनक्स के लिए लिखित, विंडोज़ के लिए भी एक समान हो सकता है। यदि "libDir2Scan4jars" में इनपुट के रूप में उचित निर्देशिका प्रदान की जाती है; लिपि सभी जार स्कैन करेगी और क्लासपाथ स्ट्रिंग बनाएगी और इसे एक एनवी वैरिएबल "tmpCLASSPATH" में निर्यात करेगी।
Wepapp से कक्षा:
> mvn clean install
> java -cp "webapp/target/webapp-1.17.0-SNAPSHOT/WEB-INF/lib/tool-jar-1.17.0-SNAPSHOT.jar;webapp/target/webapp-1.17.0-SNAPSHOT/WEB-INF/lib/*" com.xx.xx.util.EncryptorUtils param1 param2
आपको उन्हें अलग से जोड़ने की जरूरत है। वैकल्पिक रूप से, यदि आपको वास्तव में केवल एक निर्देशिका निर्दिष्ट करने की आवश्यकता है, तो आप सबकुछ एक डीआईआर में जोड़ सकते हैं और इसे अपने क्लासपाथ में जोड़ सकते हैं। मैं इस दृष्टिकोण की अनुशंसा नहीं करता हूं क्योंकि आप क्लासपाथ संस्करण और अमानवीयता में विचित्र समस्याओं का जोखिम उठाते हैं।
उनके लिए जो इससे सम्बद्ध हो सकते हैं,
मुझे विंडोज़ पर एक एमएसवाईएस / मिनजीडब्ल्यू खोल के तहत यह अजीब व्यवहार मिला।
काम करता है:
$ javac -cp '.;c:\Programs\COMSOL44\plugins\*' Reclaim.java
काम नहीं करता है:
$ javac -cp 'c:\Programs\COMSOL44\plugins\*' Reclaim.java
javac: invalid flag: c:\Programs\COMSOL44\plugins\com.comsol.aco_1.0.0.jar
Usage: javac <options> <source files>
use -help for a list of possible options
मुझे पूरा यकीन है कि वाइल्डकार्ड को खोल से विस्तारित नहीं किया गया है, उदाहरण के लिए
$ echo './*'
./*
(उसी परिणाम के साथ अंतर्निहित echo
की बजाय, इसे किसी अन्य प्रोग्राम के साथ भी echo
।)
मेरा मानना है कि यह javac
जो इसे विस्तारित करने की कोशिश कर रहा है, और यह अलग-अलग व्यवहार करता है कि तर्क में अर्धविराम है या नहीं। सबसे पहले, यह पथों की तरह दिखने वाले सभी तर्कों का विस्तार करने का प्रयास कर रहा है। और केवल तब ही उन्हें पार्स कर दिया जाएगा, -cp
केवल निम्नलिखित टोकन ले रहा है। (ध्यान दें कि com.comsol.aco_1.0.0.jar
उस निर्देशिका में दूसरा जार है।) यह सब अनुमान है।
ये है
$ javac -version
javac 1.7.0
एकमात्र तरीका मुझे पता है कि इसे व्यक्तिगत रूप से कैसे करना है, उदाहरण के लिए:
setenv CLASSPATH /User/username/newfolder/jarfile.jar:jarfile2.jar:jarfile3.jar:.
उम्मीद है की वो मदद करदे!
कृपया ध्यान दें कि विंडोज 7 पर जावा 7 के लिए वाइल्डकार्ड विस्तार टूट गया है।
अधिक जानकारी के लिए इस समस्या को देखें।
वाइल्डकार्ड के बाद सही अर्धविराम डालना है। java -cp "somewhere/*;"
जावा 6 या बाद में, क्लासपाथ विकल्प वाइल्डकार्ड का समर्थन करता है। निम्नलिखित नोट करें:
- सीधे उद्धरण का प्रयोग करें (
"
) -
*
, नहीं*.jar
प्रयोग करें
विंडोज
java -cp "Test.jar;lib/*" my.package.MainClass
यूनिक्स
java -cp "Test.jar:lib/*" my.package.MainClass
यह विंडोज के समान है, लेकिन इसका उपयोग करता है :
इसके बजाए ;
। यदि आप वाइल्डकार्ड का उपयोग नहीं कर सकते हैं, तो bash
निम्न वाक्यविन्यास की अनुमति देता है (जहां lib
निर्देशिका है जिसमें सभी जावा संग्रह फ़ाइलें हैं):
java -cp $(echo lib/*.jar | tr ' ' ':')
(ध्यान दें कि क्लासपाथ का उपयोग -jar
विकल्प के साथ असंगत है। यह भी देखें: कमांड प्रॉम्प्ट से एकाधिक क्लासपाथ पुस्तकालयों के साथ जार फ़ाइल निष्पादित करें )
वाइल्डकार्ड को समझना
Classpath दस्तावेज़ से:
क्लास पथ प्रविष्टियों में बेसनाम वाइल्डकार्ड वर्ण
*
, जिसे एक्सटेंशन में सभी फ़ाइलों की सूची निर्दिष्ट करने के बराबर माना जाता है.jar
या.JAR
। उदाहरण के लिए, कक्षा पथ प्रविष्टिfoo/*
foo नामक निर्देशिका में सभी JAR फ़ाइलों को निर्दिष्ट करता है। एक क्लासपाथ प्रविष्टि जिसमें बस*
शामिल है, वर्तमान निर्देशिका में सभी जार फ़ाइलों की एक सूची में फैली हुई है।एक वर्ग पथ प्रविष्टि जिसमें
*
फ़ाइलें शामिल नहीं हैं। एक ही निर्देशिका में कक्षाओं और जेएआर फ़ाइलों दोनों से मेल खाने के लिएfoo;foo/*
foo/*;foo
याfoo/*;foo
। चुना गया आदेश यह निर्धारित करता है किfoo
में कक्षाएं और संसाधनfoo
में JAR फ़ाइलों से पहले लोड किए गए हैं या इसके विपरीत।उपनिर्देशिकाओं को बार-बार खोजा नहीं जाता है। उदाहरण के लिए,
foo/*
केवलfoo
में JAR फ़ाइलों को देखता है,foo/bar
,foo/baz
, आदि में नहीं।जिस क्रम में निर्देशिका में जेएआर फाइलों का विस्तार किया गया है, विस्तारित वर्ग पथ में उल्लिखित है, निर्दिष्ट नहीं है और प्लेटफॉर्म से प्लेटफार्म और यहां तक कि उसी मशीन पर पल से पल तक भिन्न हो सकता है। एक अच्छी तरह से निर्मित आवेदन किसी भी विशेष आदेश पर निर्भर नहीं होना चाहिए। यदि एक विशिष्ट आदेश की आवश्यकता है तो JAR फ़ाइलों को कक्षा पथ में स्पष्ट रूप से समझा जा सकता है।
कक्षा-लोडिंग प्रक्रिया के दौरान, देर से बजाए, कार्यक्रम की मुख्य विधि के आमंत्रण से पहले, वाइल्डकार्ड का विस्तार जल्दी ही किया जाता है। वाइल्डकार्ड वाले इनपुट क्लास पथ के प्रत्येक तत्व को नामित निर्देशिका में जेएआर फाइलों की गणना करके उत्पन्न तत्वों (संभावित रूप से खाली) अनुक्रम द्वारा प्रतिस्थापित किया जाता है। उदाहरण के लिए, यदि निर्देशिका
foo
मेंa.jar
,b.jar
, औरc.jar
, तो क्लास पथfoo/*
कोfoo/a.jar;foo/b.jar;foo/c.jar
में विस्तारित किया गया हैfoo/a.jar;foo/b.jar;foo/c.jar
, और वह स्ट्रिंग सिस्टम प्रॉपर्टीjava.class.path
का मान होगा।
CLASSPATH
पर्यावरण चर को-classpath
(या-classpath
) कमांड लाइन विकल्प से अलग तरीके से इलाज नहीं किया जाता है। यही है, इन सभी मामलों में वाइल्डकार्ड सम्मानित हैं। हालांकि, क्लास पथ वाइल्डकार्ड कोClass-Path jar-manifest
हेडर में सम्मानित नहीं किया जाता है।
जावा-सन 1.6.0_24 का उपयोग करते हुए उबंटू 10.04 पर मेरा समाधान "lib" निर्देशिका में सभी जार हैं:
java -cp .:lib/* my.main.Class
यदि यह विफल हो जाता है, तो निम्न आदेश काम करना चाहिए (क्लासपाथ परम में lib * निर्देशिका में सभी * .jars प्रिंट करता है)
java -cp $(for i in lib/*.jar ; do echo -n $i: ; done). my.main.Class
यदि आप ग्रहण या Netbeans जैसे किसी भी आईडीई के बाहर जावा एप्लिकेशन को विकसित और चलाते हैं तो उपर्युक्त समाधान बहुत अच्छे काम करते हैं।
यदि आप विंडोज 7 पर हैं और जावा में विकास के लिए एक्लिप्स आईडीई का इस्तेमाल करते हैं, तो ग्रहण के अंदर बनाए गए वर्ग फ़ाइलों को चलाने के लिए कमांड प्रॉम्प्ट का उपयोग करते समय आप समस्याओं में भाग ले सकते हैं।
जैसे ग्रहण में आपका स्रोत कोड निम्न पैकेज पदानुक्रम है: edu.sjsu.myapp.Main.java
आपके पास json.jar मुख्य.जावा के लिए बाह्य निर्भरता के रूप में है
जब आप ग्रहण के भीतर से Main.java को चलाने का प्रयास करते हैं, तो यह बिना किसी समस्या के चलाएगा।
लेकिन जब आप ग्रहण में Main.java संकलित करने के बाद कमांड प्रॉम्प्ट का उपयोग करके इसे चलाने का प्रयास करते हैं, तो यह "क्लास नॉटडिफ त्रुटि ब्ला ब्लाह" कहकर कुछ अजीब त्रुटियों को शूट करेगा।
मुझे लगता है कि आप अपने स्रोत कोड की कामकाजी निर्देशिका में हैं !!
कमांड प्रॉम्प्ट से चलाने के लिए निम्न वाक्यविन्यास का प्रयोग करें:
javac -cp "।; json.jar" Main.java
जावा- सीपी "।; json.jar" edu.sjsu.myapp.Main
[याद मत करो। ऊपर]
ऐसा इसलिए है क्योंकि आपने मेन्यूज को पैकेज के अंदर रखा है edu.sjsu.myapp और java.exe सटीक पैटर्न की तलाश करेगा।
आशा करता हूँ की ये काम करेगा !!
यदि आप जावा 6 का उपयोग कर रहे हैं, तो आप क्लासपाथ में वाइल्डकार्ड का उपयोग कर सकते हैं।
अब क्लासपाथ परिभाषा में वाइल्डकार्ड का उपयोग करना संभव है:
javac -cp libs/* -verbose -encoding UTF-8 src/mypackage/*.java -d build/classes
लघु प्रपत्र: यदि आपका मुख्य जार के भीतर है, तो आपको शायद इसे अतिरिक्त '-jar pathto / yourJar / YourJarsName.jar' की आवश्यकता होगी, इसे स्पष्ट रूप से घोषित करने के लिए घोषित किया गया है (भले ही 'YourJarsName.jar' क्लासपाथ पर था) (या , 5 साल पहले पूछे गए मूल प्रश्न का उत्तर देने के लिए व्यक्त किया गया: आपको प्रत्येक जार को स्पष्ट रूप से फिर से शुरू करने की आवश्यकता नहीं है, लेकिन ऐसा लगता है कि जावा 6 के साथ भी आपको अपने जार को फिर से शुरू करने की आवश्यकता है ...)
लंबा फॉर्म: (मैंने इस बिंदु को स्पष्ट कर दिया है कि मुझे उम्मीद है कि जावा के लिए इंटरलॉपर भी इसका उपयोग कर सकते हैं)
यहां कई लोगों की तरह मैं जार निर्यात करने के लिए ग्रहण का उपयोग कर रहा हूं: (फ़ाइल-> निर्यात -> 'रननेबल जेएआर फाइल')। 'लाइब्रेरी हैंडलिंग' ग्रहण (जूनो) पर तीन विकल्प हैं:
opt1: "Extract required libraries into generated JAR"
opt2: "Package required libraries into generated JAR"
opt3: "Copy required libraries into a sub-folder next to the generated JAR"
आम तौर पर मैं opt2 (और opt1 निश्चित रूप से तोड़ रहा था) का उपयोग करता हूं, हालांकि मैं जिन जारों का उपयोग कर रहा हूं उनमें से एक में देशी कोड मैंने आसान "jarinjar" चाल के साथ ब्रेक की खोज की है, जब आप उस विकल्प को चुनते हैं तो ग्रहण ग्रहण करते हैं। यह महसूस करने के बाद भी मुझे ऑप्ट 3 की आवश्यकता थी, और फिर इस स्टैक ओवरफ्लो एंट्री को ढूंढने के बाद, मुझे यह पता लगाने में कुछ समय लगा कि यह मेरे मुख्य ग्रहण के बाहर कैसे लॉन्च किया जाए, इसलिए यहां मेरे लिए क्या काम किया गया है, क्योंकि यह दूसरों के लिए उपयोगी है ...
यदि आपने अपना जार नाम दिया है: "fooBarTheJarFile.jar" और सभी डीआईआर को निर्यात करने के लिए सेट हैं: "/ पूरी तरह से / योग्य पाथ / toYourChosenDir"।
(जिसका अर्थ है 'निर्यात गंतव्य' फ़ील्ड पढ़ेगा: '/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar')
खत्म करने के बाद, आपको ग्रहण मिलेगा, फिर सभी पुस्तकालयों को उस निर्यात निर्देशिका में 'fooBarTheJarFile_lib' नामक फ़ोल्डर में रखता है, जिससे आपको कुछ ऐसा मिलता है:
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar01.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar02.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar03.jar
/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/SomeOtherJar04.jar
फिर आप अपने सिस्टम पर कहीं से भी लॉन्च कर सकते हैं:
java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*" -jar /theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar package.path_to.the_class_with.your_main.TheClassWithYourMain
(जावा न्यूबीज के लिए: 'package.path_to.the_class_with.your_main' घोषित पैकेज-पथ है जिसे आप 'TheClassWithYourMain.java' फ़ाइल के शीर्ष पर पाएंगे जिसमें 'मुख्य (स्ट्रिंग [] तर्क) {.. है। ।} 'कि आप बाहरी जावा से भागना चाहते हैं)
नोटिस के लिए गड़बड़: यह है कि आपके घोषित वर्गपाथ पर जारों की सूची में 'fooBarTheJarFile.jar' होना पर्याप्त नहीं है। आपको स्पष्ट रूप से '-jar' घोषित करने की आवश्यकता है, और उस जार के स्थान को फिर से शुरू करना होगा।
उदाहरण के लिए यह तोड़ता है:
java -classpath "/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile.jar;/theFully/qualifiedPath/toYourChosenDir/fooBarTheJarFile_lib/*" somepackages.inside.yourJar.leadingToTheMain.TheClassWithYourMain
सापेक्ष पथ के साथ बहाल:
cd /theFully/qualifiedPath/toYourChosenDir/;
BREAKS: java -cp "fooBarTheJarFile_lib/*" package.path_to.the_class_with.your_main.TheClassWithYourMain
BREAKS: java -cp ".;fooBarTheJarFile_lib/*" package.path_to.the_class_with.your_main.TheClassWithYourMain
BREAKS: java -cp ".;fooBarTheJarFile_lib/*" -jar package.path_to.the_class_with.your_main.TheClassWithYourMain
WORKS: java -cp ".;fooBarTheJarFile_lib/*" -jar fooBarTheJarFile.jar package.path_to.the_class_with.your_main.TheClassWithYourMain
(जावा संस्करण "1.6.0_27" का उपयोग करके; ओबजु 12.04 पर ओपनजेडीके 64-बिट सर्वर वीएम के माध्यम से)
विंडोज कोट्स के लिए आवश्यक हैं और; विभाजक के रूप में इस्तेमाल किया जाना चाहिए। उदाहरण के लिए:
java -cp "target\\*;target\\dependency\\*" my.package.Main
संक्षिप्त उत्तर: java -classpath lib/*:. my.package.Program
java -classpath lib/*:. my.package.Program
ओरेकल क्लास पथ वाइल्डकार्ड को समझने वाले अनुभाग के तहत, जावा 6 के लिए यहां क्लासपाथ में वाइल्डकार्ड का उपयोग करने और जावा 7 के लिए दस्तावेज प्रदान करता है। (जैसा कि मैंने यह लिखा है, दोनों पृष्ठों में एक ही जानकारी है।) यहां हाइलाइट्स का सारांश दिया गया है:
सामान्य रूप से, किसी दिए गए निर्देशिका में सभी JARs को शामिल करने के लिए, आप वाइल्डकार्ड
*
( नहीं*.jar
) का उपयोग कर सकते हैं।वाइल्डकार्ड केवल जेएआर से मेल खाता है, क्लास फाइल नहीं; निर्देशिका में सभी वर्गों को प्राप्त करने के लिए, बस निर्देशिका नाम पर क्लासपाथ प्रविष्टि समाप्त करें।
उपरोक्त दो विकल्पों को एक निर्देशिका में सभी जेएआर और कक्षा फ़ाइलों को शामिल करने के लिए जोड़ा जा सकता है, और सामान्य क्लासपाथ प्राथमिकता नियम लागू होते हैं। ईजी-
-cp /classes;/jars/*
वाइल्डकार्ड उपनिर्देशिका में जेएआर की खोज नहीं करेगा।
यदि आप
-classpath
सिस्टम प्रॉपर्टी या-classpath
या--classpath
कमांड लाइन फ्लैग का उपयोग करते हैं तो उपरोक्त बुलेट पॉइंट सत्य हैं। हालांकि, यदि आपClass-Path
जेएआर मैनिफेस्ट हेडर का उपयोग करते हैं (जैसा कि आप चींटी बिल्ड फ़ाइल के साथ कर सकते हैं), वाइल्डकार्ड को सम्मानित नहीं किया जाएगा।
हां, मेरा पहला लिंक शीर्ष स्कोरिंग उत्तर में प्रदान किया गया है (जिसे मुझे आगे बढ़ने की कोई उम्मीद नहीं है), लेकिन वह जवाब लिंक से परे अधिक स्पष्टीकरण प्रदान नहीं करता है। चूंकि इस तरह के व्यवहार को इन दिनों स्टैक ओवरफ़्लो पर discouraged गया है, मैंने सोचा कि मैं इसका विस्तार करूंगा।
हम एक मुख्य जार फ़ाइल myapp.jar
को तैनात करके इस समस्या को हल करते हैं जिसमें एक मेनिफेस्ट ( Manifest.mf
) फ़ाइल होती है जिसमें अन्य आवश्यक जार के साथ क्लासपाथ निर्दिष्ट होता है, जिसे उसके साथ तैनात किया जाता है। इस मामले में, कोड चलाने के दौरान आपको केवल java -jar myapp.jar
घोषित करने की आवश्यकता है।
तो यदि आप मुख्य jar
को कुछ निर्देशिका में तैनात करते हैं, और फिर आश्रित जार को उसके नीचे एक lib
फ़ोल्डर में डाल दें, तो मैनिफेस्ट इस तरह दिखता है:
Manifest-Version: 1.0
Implementation-Title: myapp
Implementation-Version: 1.0.1
Class-Path: lib/dep1.jar lib/dep2.jar
एनबी: यह मंच-स्वतंत्र है - हम एक ही जार का उपयोग यूनिक्स सर्वर या विंडोज पीसी पर लॉन्च करने के लिए कर सकते हैं।
सही :
java -classpath "lib/*:." my.package.Program
गलत:
java -classpath "lib/a*.jar:." my.package.Program
java -classpath "lib/a*:." my.package.Program
java -classpath "lib/*.jar:." my.package.Program
java -classpath lib/*:. my.package.Program