एक संसाधन एक जार


21

अपने आवेदन में मैं इस तरह से संसाधनों के लोड में निहित लोड:

WinProcessor.class.getResource("repository").toString(); 

और यह मुझे देता है:

file:/root/app/repository (and I replace "file:" with empty string) 

यह ठीक काम करता है जब मैं आईडीई से अपने आवेदन को चलाने , लेकिन जब मैं अपने आवेदन के जार चलाएँ:

java -jar app.jar 

पथ हो जाता है:

jar:/root/app.jar!/repository 

क्या इस समस्या को हल करने का कोई तरीका है?

मैं "भंडार" dir नाम आदेश में इस बनाने के लिए उपयोग करेंगे:

ConfigurationContext ctx = (ConfigurationContext) ConfigurationContextFactory.createConfigurationContextFromFileSystem(repositoryString, null); 

इसी तरह, मैं एक फ़ाइल नाम (एक निर्देशिका के बजाय) मिल जाएगा और मैं इस्तेमाल करेंगे यह इस तरह से:

System.setProperty("javax.net.ssl.trustStore", fileNameString) 
35

ऐसा लगता है कि आप FileInputStream या ऐसा कुछ उपयोग करके संसाधन लोड करने का प्रयास कर रहे हैं। ऐसा न करें: getResource पर कॉल करने के बजाय, getResourceAsStream पर कॉल करें और उस से डेटा पढ़ें।

(आप के बजाय URL से संसाधन लोड सकता है, लेकिन बुला getResourceAsStream में थोड़ा और अधिक सुविधाजनक है।)

संपादित करें: अपने अद्यतन जवाब देखने के बाद, ऐसा लगता है कोड के अन्य बिट्स डेटा एक में किया जा रहा पर भरोसा करते हैं फ़ाइल सिस्टम में भौतिक एकल फ़ाइल। इसलिए जवाब पहली बार एक जार फ़ाइल में बंडल नहीं करना है। आप देख सकते हैं कि यह एक अलग फ़ाइल में है, और यदि इसे अस्थायी फ़ाइल में निकाला नहीं गया है, लेकिन यह बहुत हैकी आईएमओ है।

+1

सहमत हैं। जब भी आप 100% निश्चितता के साथ नहीं कह सकते कि आप भौतिक एकल फाइलों (जावा वेब एक के लिए शुरू) से निपटेंगे, तो आपको हमेशा धाराओं के साथ कोड करना चाहिए। 22 feb. 092009-02-22 12:16:38


5

एक URL का निर्माण, तो आप एक संसाधन लोड कर सकते हैं (एक जार फ़ाइल में भी) openStream पद्धति का उपयोग करके।

+1

में सापेक्ष और पूर्ण पथ से मैकॉक्स, यही है 'getResourceAsStream' करता है। 12 jul. 162016-07-12 14:20:56


9

java -jar app.jar का उपयोग करते हुए कोड चलाते समय, जावा केवल JAR फ़ाइल (यानी Class-Path विशेषता) के प्रकट में परिभाषित कक्षा पथ का उपयोग करता है। यदि कक्षा app.jar में है, या कक्षा Class-Path में जेएआर के मैनिफेस्ट की विशेषता के वर्ग पथ में है, तो आप निम्न कोड स्निपेट का उपयोग करके उस वर्ग को लोड कर सकते हैं, जहां className पूरी तरह से योग्य क्लास नाम है।

final String classAsPath = className.replace('.', '/') + ".class"; 
final InputStream input = ClassLoader.getSystemResourceAsStream(path/to/class); 

अब अगर वर्ग जार का हिस्सा नहीं है, और यह प्रकट की Class-Path में नहीं है, तो वर्ग लोडर इसे खोजने नहीं होंगे। इसके बजाए, आप URLClassLoader का उपयोग कर सकते हैं, कुछ विंडोज़ और यूनिक्स/लिनक्स/मैकोज़क्स के बीच मतभेदों से निपटने के लिए कुछ देखभाल के साथ।

// the class to load 
final String classAsPath = className.replace('.', '/') + ".class"; 

// the URL to the `app.jar` file (Windows and Unix/Linux/MacOSX below) 
final URL url = new URL("file", null, "///C:/Users/diffusive/app.jar"); 
//final URL url = new URL("file", null, "/Users/diffusive/app.jar"); 

// create the class loader with the JAR file 
final URLClassLoader urlClassLoader = new URLClassLoader(new URL[] { url }); 

// grab the resource, through, this time from the `URLClassLoader` object 
// rather than from the `ClassLoader` class 
final InputStream input = urlClassLoader.getResourceAsStream(classAsPath); 

दोनों उदाहरण आप अपवाद के साथ सौदा करने की आवश्यकता होगी, और तथ्य यह है कि इनपुट धारा null है अगर संसाधन नहीं मिला जा सकता है। इसके अलावा, अगर आपको InputStream को byte[] में प्राप्त करने की आवश्यकता है, तो आप अपाचे के कॉमन्स IOUtils.toByteArray(...) का उपयोग कर सकते हैं। और, यदि आप Class चाहते हैं, तो आप कक्षा लोडर की defineClass(...) विधि का उपयोग कर सकते हैं, जो byte[] स्वीकार करता है।

आप वाचाल स्रोत कोड है, जो आप Windows और यूनिक्स/लिनक्स के लिए URL बनाने के github.com/robphilipp/diffusive

और एक विधि पर SourceForge पर पा सकते हैं में एक ClassLoaderUtils कक्षा में यह कोड ढूंढने के/RestfulDiffuserManagerResource.createJarClassPath(...)