2008-09-19 16 views
10

पर जावा के निरंतर मान को परिभाषित करने का कोई तरीका है जब मैं सी/सी ++ में पुस्तकालय लिखता था, तो मुझे संकलन दिनांक/समय वापस करने की विधि होने की आदत मिली। यह हमेशा लाइब्रेरी में संकलित था, इसलिए लाइब्रेरी के निर्माण को अलग करेगा।संकलन समय

सी ++:: मैं कोड में एक #define वापस लौट कर यह मिल गया

#ifdef _BuildDateTime_ 
    char* SomeClass::getBuildDateTime() { 
     return _BuildDateTime_; 
    } 
#else 
    char* SomeClass::getBuildDateTime() { 
     return "Undefined"; 
    } 
#endif 

फिर संकलन पर मैं निर्माण स्क्रिप्ट में था एक '-D_BuildDateTime_ = Date'।

क्या किसी भी फाइल को मैन्युअल रूप से संपादित करने या किसी भी अलग फ़ाइलों को वितरित करने के लिए याद रखने के बिना जावा में यह या समान करने का कोई तरीका है।

एक सहकर्मी से मुझे एक सुझाव प्राप्त हुआ था कि वह एंटी फ़ाइल को क्लासपाथ पर फ़ाइल बनाने और जेएआर में पैकेज करने के लिए प्राप्त करे और इसे विधि द्वारा पढ़ा जाए।

कुछ की तरह (बनाया 'DateTime.dat' कहा जाता था फ़ाइल कल्पना करते हुए): एक हैक है और उन्हें धोखा दिया जा सकता है/किसी को एक समान नाम फ़ाइल होने के बाहर ने तोड़ा कि

// I know Exceptions and proper open/closing 
// of the file are not done. This is just 
// to explain the point! 
String getBuildDateTime() { 
    return new BufferedReader(getClass() 
      .getResourceAsStream("DateTime.dat")).readLine(); 
} 
मेरे मन के लिए

जार, लेकिन कक्षापथ पर।

वैसे भी, मेरे सवाल वहाँ संकलन समय की किसी कक्षा के एक निरंतर इंजेक्षन किसी भी तरह से है कि क्या है

संपादित

कारण मैं जार में एक बाह्य उत्पन्न फ़ाइल के उपयोग पर विचार हैक इस वजह से है ) एक लाइब्रेरी है और क्लाइंट ऐप्स में एम्बेड की जाएगी। ये क्लाइंट ऐप्स अपने स्वयं के क्लासलोडर्स को परिभाषित कर सकते हैं जिसका अर्थ है कि मैं मानक जेवीएम क्लास लोडिंग नियमों पर भरोसा नहीं कर सकता।

मेरी निजी प्राथमिकता कोआरएआर 10 द्वारा सुझाए गए जेएआर फ़ाइल से तारीख का उपयोग करने के साथ जाना होगा।

+0

*। * क्या आप काम के माहौल कार्यक्रम है कि आप लोगों के बारे में चिंतित हैं "को धोखा देने में " इस? चींटी उत्पन्न करने के बाद फ़ाइल एक हैक नहीं है। बेशक मैनिफेस्ट दृष्टिकोण जावा-आईएसएम भी बेहतर है (और आप भी एंटी स्वचालित कर सकते हैं)। – Hejazzman

उत्तर

15

मैं मानक आधारित दृष्टिकोण का पक्ष लेगा। जार के Manifest File में अपनी संस्करण जानकारी (अन्य उपयोगी प्रकाशक सामग्री जैसे बिल्ड नंबर, सबवर्जन संशोधन संख्या, लेखक, कंपनी विवरण, आदि) के साथ रखें।

यह एक अच्छी तरह से प्रलेखित और जावा विनिर्देश समझा गया है। मैनिफेस्ट फाइल बनाने के लिए मजबूत टूल समर्थन मौजूद है (उदाहरण के लिए core Ant task, या maven jar plugin)। ये स्वचालित रूप से कुछ विशेषताओं को सेट करने में मदद कर सकते हैं - मेरे पास निर्माण समय पर मेरे लिए मैर के मेवेन संस्करण संख्या, सबवर्जन संशोधन और टाइमस्टैम्प को मैनिफेस्ट में कॉन्फ़िगर करने के लिए कॉन्फ़िगर किया गया है।

आप मानक जावा API कॉल के साथ रनटाइम पर प्रकट की सामग्री पढ़ सकते हैं - जैसे कुछ:

import java.util.jar.*; 

... 

JarFile myJar = new JarFile("nameOfJar.jar"); // various constructors available 
Manifest manifest = myJar.getManifest(); 
Map<String,Attributes> manifestContents = manifest.getAttributes(); 

मेरे लिए, कि एक और अधिक जावा मानक दृष्टिकोण की तरह लगता है, तो शायद बाद के लिए और अधिक आसान साबित होगा कोड रखरखाव का पालन करने के लिए।

मेरे मन एक हैक है कि और उन्हें धोखा दिया जा सकता है/किसी जार के बाहर एक समान नाम फ़ाइल होने से टूट, लेकिन classpath पर करने के लिए
1

जब तक आप अपने जावा स्रोत को सी/सी ++ प्रीप्रोसेसर (जो एक बड़ा नो-नो) के माध्यम से चलाने के लिए नहीं चाहते हैं, तो जार विधि का उपयोग करें। यह सुनिश्चित करने के लिए कि किसी ने क्लासपाथ पर डुप्लिकेट संसाधन नहीं डाला है, एक जार से सही संसाधन प्राप्त करने के अन्य तरीके हैं। आप इसके लिए जार मैनिफेस्ट का उपयोग करने पर भी विचार कर सकते हैं। मैनिफेस्ट का उपयोग करके मेरी परियोजना ठीक वही करता है जो आप करने की कोशिश कर रहे हैं (निर्माण तिथियों, संशोधन, लेखक, आदि के साथ)।

आप इस का उपयोग करना चाहते हैं:

Enumeration<URL> resources = Thread.currentThread().getContextClassLoader().getResources("META-INF/MANIFEST.MF"); 

यह आपको classpath पर प्रकट होता है के सभी मिल जाएगा। यूआरएल को पार्स करके आप यह पता लगा सकते हैं कि वे कौन सा जार कर सकते हैं।

2

AFAIK javac के साथ ऐसा करने का कोई तरीका नहीं है। यह आसानी से चींटी के साथ किया जा सकता है - मैं BuildTimestamp.java नामक एक प्रथम श्रेणी वस्तु बनाउंगा और उस फ़ाइल को एंटी लक्ष्य के माध्यम से संकलित समय पर उत्पन्न करूंगा।

Here's an Ant type जो सहायक होगा।

1

व्यक्तिगत रूप से मैं आपके जार में एक अलग गुण फ़ाइल के लिए जाऊंगा जिसे आप रनटाइम पर लोड करेंगे ... क्लासलोडर के पास फ़ाइलों की खोज के लिए एक निर्धारित आदेश है - मुझे याद नहीं है कि यह वास्तव में हाथ से कैसे काम करता है, लेकिन मुझे नहीं लगता कि क्लासपाथ पर कहीं भी एक ही नाम वाली दूसरी फाइल मुद्दों का कारण बन सकती है।

लेकिन ऐसा करने का एक और तरीका यह है कि आप अपनी .java फ़ाइलों को संकलित करने से पहले एक अलग निर्देशिका में कॉपी करने के लिए चींटी का उपयोग करना होगा, स्ट्रिंग स्थिरांक में उचित रूप से फ़िल्टर करना। आप कुछ ऐसा उपयोग कर सकते हैं:

public String getBuildDateTime() { 
    return "@[email protected]"; 
} 

और बिल्ड एंट के साथ इसे बदलने के लिए अपनी एंट फ़ाइल में एक फ़िल्टर लिखें।

0

एक सुझाव मैं एक सह कार्यकर्ता से मिला classpath पर एक फ़ाइल बनाने के लिए और कि जार में और यह विधि से पढ़ लिया है पैकेज चींटी फ़ाइल प्राप्त करने के लिए किया गया था। ... मेरे दिमाग में यह हैक है और JAR के बाहर समान नाम फ़ाइल वाले किसी व्यक्ति द्वारा को घुमाया/टूटा जा सकता है, लेकिन क्लासपाथ पर।

मुझे यकीन नहीं है कि फ़ाइल उत्पन्न करने के लिए चींटी प्राप्त करना एक बहुत ही विशाल हैक है, अगर यह एक हैक है। एक प्रॉपर्टी फ़ाइल क्यों न उत्पन्न करें और इसे संभालने के लिए java.util.Properties का उपयोग करें?

1

शायद manifest documentation में वर्णित अनुसार, आपके पुस्तकालय के संस्करण को इंगित करने का एक और जावा-शैली तरीका जेएआर के मैनिफेस्ट में संस्करण संख्या जोड़ना होगा। एक टेम्पलेट फ़ाइल में

class Version... { 
    public static String tstamp() { 
    return "@[email protected]"; 
    } 
} 

:

10

मैं एक ओपन सोर्स प्रोजेक्ट में कुछ इसी तरह देखकर याद है। चींटी की छानने के साथ कॉपी आप इस मैक्रो एक मूल्य दे सकते हैं:

<copy src="templatefile" dst="Version.java" filtering="true"> 
    <filter token="BUILDTIME" value="${build.tstamp}" /> 
</copy> 

उपयोग इस अपने निर्माण की प्रक्रिया में एक Version.java स्रोत फ़ाइल बनाने के लिए, संकलन कदम से पहले।

संबंधित मुद्दे