2010-07-26 11 views
19

मैं कोड का एक टुकड़ा एम्बेड करना चाहता हूं जो उस समय को मुद्रित करेगा जब वर्तमान वर्ग को अंतिम बार संकलित किया गया था। जावा में इसे कैसे कार्यान्वित किया जा सकता है?अंतिम संकलन के जावा प्रिंट समय

+0

क्या कारण के लिए ब्याज के संकलन की तारीख है? –

+1

@MichaelKonietzka रन समय पर एक जेएआर के संस्करण संख्या को पुनर्प्राप्त करने का एक कैननिक तरीका है? – uprego

उत्तर

11

के बाद से वहाँ कोई पूर्वप्रक्रमक है वहाँ, जावा में इस के लिए कोई सीधा समर्थन है। निकटतम समकक्ष जेएआर मैनिफेस्ट में "बिल्ड-डेट" विशेषता है। कई बिल्ड सिस्टम डिफ़ॉल्ट रूप से इस विशेषता को जोड़ते हैं, या इसे जोड़ने के साधन प्रदान करते हैं।

फिर आप दिनांक प्राप्त करने के लिए रनटाइम पर जेएआर के मैनिफेस्ट को पढ़ सकते हैं। इस SO question का उत्तर वर्णन करता है कि जेएआर मैनिफेस्ट से मूल्य कैसे पढ़ा जाए।

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

+1

+1। मैं एक मानक प्रकट संपत्ति की तलाश में था लेकिन इसे अच्छे समय में नहीं मिला। –

4

विशेष प्लेसहोल्डर की जगह एक खोल स्क्रिप्ट है कि संकलन समय के साथ वर्ग कोड अद्यतन करता है बनाएँ:

public final class CompilationInfo 
{ 
    public static final String TIME = "$COMPILE_TIME"; 
} 

अधिक जानकारी के लिए, this article देखते हैं।

+1

हम StackOverflow को अपनी जानकारी का भंडार बनाना पसंद करते हैं। क्या आप यहां एक उदाहरण समझा सकते हैं और दिया जा सकता है, या कम से कम संक्षेप में? –

+0

यहां संदेश का एक लिंक है जिसे SO स्वीकार करना चाहिए: http://groups.google.com/group/comp.lang.java.help/msg/5177eeaea2ef9ad9?hl=hi –

+0

अब फिक्स्ड, धन्यवाद। – spektom

1

ऐसा करने का एक मानक तरीका नहीं है, मेरा सुझाव spektom के लिंक के समान है, लेकिन आपके निर्माण स्क्रिप्ट द्वारा पॉप्युलेट किए गए आपके जार में एक संपत्ति फ़ाइल जोड़ना होगा (चींटी में संपत्ति बनाने के लिए एक अंतर्निहित कार्य है फ़ाइल)। शायद इसे /buildinfo.properties पर डाल दें। फिर एक जावा क्लास बनाएं जो रनटाइम पर उस प्रॉपर्टी फ़ाइल को बस चुनाव करे।

चींटी में, यह कुछ इस तरह दिख सकता है:

... 
<tstamp/>  
... 
<propertyfile file="${output.dir}/buildinfo.properties"> 
    <entry key="build.date" value="${TSTAMP}"/> 
</propertyfile> 

और फिर इसी जावा

public Date getBuildDate() { 
    Properties buildProps = new Properties(); 
    buildProps.load(getClass().getResourceAsStream("/buildinfo.properties")); 
    return someConversion(buildProps.getProperty("build.date")); 
} 
1

अपने निर्माण प्रक्रिया जानकारी की आवश्यकता युक्त एक संपत्ति फ़ाइल बनाने, और फिर अपने कोड

5

यह थोड़ा भद्दा है में एक संसाधन के रूप गुण पढ़ने दें, लेकिन आप चींटी को छानने के साथ ऐसा कर सकता है।

अपनी कक्षा में निम्न विधि पॉप:

public static String timeBuilt(){ 
    return "Built at @[email protected] on @[email protected]"; 
} 

फिर अपने चींटी निर्माण फ़ाइल में निम्न डाल दिया।

<target name="get-time"> 
    <tstamp> 
     <format property="buildTime" pattern="HH:mm:ss" locale="en,UK"/> 
     <format property="buildDate" pattern="dd-MM-yyyy" locale="en,UK"/> 
    </tstamp> 
</target> 

<target name="copy-files" depends="get-time"> 
    <filter token="timeBuilt" value="${buildTime}"/> 
    <filter token="dateBuilt" value="${buildDate}"/> 
    <copy includeemptydirs="false" todir="build" filtering="true"> 
     <fileset dir="src"/> 
    </copy> 
</target> 

यह "src" निर्देशिका करने के लिए "का निर्माण" में है और ऐसा करने में क्रमश: समय और निर्माण की तारीख के साथ बदल देगा @ timeBuilt @ और @ dateBuilt @ में सब कुछ कॉपी कर देंगे। बस अपने निर्माण लक्ष्य को कॉपी-फाइलों पर निर्भर करें और "निर्माण" निर्देशिका से बनाएं - न कि "src" निर्देशिका।

एक स्थिर विधि की सामग्री को बदलने का लाभ यह है कि यह प्रति-वर्ग आधार पर काम करेगा - यदि आप उत्पादित कक्षा फाइलें लेना चाहते थे और उन्हें किसी अन्य समय बनाई गई किसी अन्य क्लास फाइलों के साथ जोड़ना चाहते थे, जब वे बनाए गए थे तो वे सभी जानते होंगे। संपत्ति फाइलें समझदार हैं, लेकिन जब तक कि आपके पास एकाधिक प्रॉपर्टी फाइलें न हों, तो आप केवल पैकेज के लिए एक बिल्ड टाइम प्राप्त कर पाएंगे।

8

के बाद से इस का उल्लेख नहीं किया गया था, किसी को भी इस समस्या को हल करने के लिए किसी भी आवश्यक तरह से देख, एक उपयुक्त, अभी तक hacky, समाधान के रूप में यह लग सकता है:

new Date(new File(getClass().getClassLoader().getResource(getClass().getCanonicalName().replace('.', '/') + ".class").toURI()).lastModified())) 

यह बहुत नहीं हो सकता है, और यह बहुत अच्छी तरह से अन्य प्लेटफॉर्म पर संगत नहीं हो सकता है, लेकिन यह एकमात्र तरीका है जिसे मैंने मूल जावा में वर्तमान कक्षा की संकलित तिथि को समझने के लिए पाया है।

+0

मुझे यह पसंद है; मेरी आंखों में, यह दृष्टिकोण एक हैक नहीं है। –

12

इस प्रश्न का उत्तर बहुत समय पहले दिया गया है। लेकिन अगर कोई यहां एक समाधान है जो मेरे लिए काम करता है, तो सुपा फ्लाई के सुझाव के समान, लेकिन जार और फ़ाइल का समर्थन करता है।

private long classBuildTimeMillis() throws URISyntaxException, IllegalStateException, IllegalArgumentException { 
    URL resource = getClass().getResource(getClass().getSimpleName() + ".class"); 
    if (resource == null) { 
     throw new IllegalStateException("Failed to find class file for class: " + 
             getClass().getName()); 
    } 

    if (resource.getProtocol().equals("file")) { 

     return new File(resource.toURI()).lastModified(); 

    } else if (resource.getProtocol().equals("jar")) { 

     String path = resource.getPath(); 
     return new File(path.substring(5, path.indexOf("!"))).lastModified(); 

    } else { 

     throw new IllegalArgumentException("Unhandled url protocol: " + 
       resource.getProtocol() + " for class: " + 
       getClass().getName() + " resource: " + resource.toString()); 
    } 
} 

लेकिन यह ज़िप फ़ाइलों या स्थिर संदर्भ को संभाल नहीं पाएगा, और यह चीजें दक्षिण में जाने पर शून्य को वापस करने के बजाय अपवाद फेंकता है। यह थोड़ा और अधिक अनुकूल है:

private static final Date buildDate = getClassBuildTime(); 

/** 
* Handles files, jar entries, and deployed jar entries in a zip file (EAR). 
* @return The date if it can be determined, or null if not. 
*/ 
private static Date getClassBuildTime() { 
    Date d = null; 
    Class<?> currentClass = new Object() {}.getClass().getEnclosingClass(); 
    URL resource = currentClass.getResource(currentClass.getSimpleName() + ".class"); 
    if (resource != null) { 
     if (resource.getProtocol().equals("file")) { 
      try { 
       d = new Date(new File(resource.toURI()).lastModified()); 
      } catch (URISyntaxException ignored) { } 
     } else if (resource.getProtocol().equals("jar")) { 
      String path = resource.getPath(); 
      d = new Date(new File(path.substring(5, path.indexOf("!"))).lastModified());  
     } else if (resource.getProtocol().equals("zip")) { 
      String path = resource.getPath(); 
      File jarFileOnDisk = new File(path.substring(0, path.indexOf("!"))); 
      //long jfodLastModifiedLong = jarFileOnDisk.lastModified(); 
      //Date jfodLasModifiedDate = new Date(jfodLastModifiedLong); 
      try(JarFile jf = new JarFile (jarFileOnDisk)) { 
       ZipEntry ze = jf.getEntry (path.substring(path.indexOf("!") + 2));//Skip the ! and the/
       long zeTimeLong = ze.getTime(); 
       Date zeTimeDate = new Date(zeTimeLong); 
       d = zeTimeDate; 
      } catch (IOException|RuntimeException ignored) { } 
     } 
    } 
    return d; 
} 
+3

इस पुराने उत्तर ने उदाहरण के लिए वेबलॉगिक पर तैनात युद्ध फ़ाइल जैसी कुछ चीज़ों के लिए ज़िप फ़ाइलों को संभाल नहीं लिया था, और इसने दिनांक की नल लौटने की बजाय अपवाद फेंक दिया नहीं जा सकता है, और यह स्थिर संदर्भ को संभाल नहीं पाया। लेकिन मैंने इसे करने के लिए इसे संशोधित किया :)। – ggb667

0

यहां आपके जावा प्रोग्राम के निर्माण समय का पता लगाने के लिए मेरी कक्षा है। यह this उत्तर से कोड का भी उपयोग करता है।

import java.io.File; 
import java.io.IOException; 
import java.net.URISyntaxException; 
import java.net.URL; 
import java.nio.file.attribute.FileTime; 
import java.text.DateFormat; 
import java.util.Date; 
import java.util.Enumeration; 
import java.util.Locale; 
import java.util.jar.JarFile; 
import java.util.zip.ZipEntry; 
import java.util.zip.ZipFile; 

public class BuildDate 
{ 
    private static Date buildDate; 

    static 
    { 
     try 
     { 
      buildDate = setBuildDate(); 
     } catch (Exception exception) 
     { 
      exception.printStackTrace(); 
     } 
    } 

    public static String getBuildDate() 
    { 
     int style = DateFormat.FULL; 
     Locale locale = Locale.getDefault(); 
     DateFormat dateFormat = DateFormat.getDateInstance(style, locale); 
     DateFormat timeFormat = DateFormat.getTimeInstance(style, locale); 

     return dateFormat.format(buildDate) + " " + timeFormat.format(buildDate); 
    } 

    private static Date setBuildDate() throws Exception 
    { 
     if (ProgramDirectoryUtilities.runningFromIntelliJ()) 
     { 
      return getClassBuildTime(); 
     } else 
     { 
      return getNewestFileDate(); 
     } 
    } 

    private static Date getNewestFileDate() throws Exception 
    { 
     String filePath = ProgramDirectoryUtilities.getJARFilePath(); 
     File file = new File(filePath); 
     ZipFile zipFile = new ZipFile(file); 
     Enumeration entries = zipFile.entries(); 

     long millis = -1; 

     while (entries.hasMoreElements()) 
     { 
      ZipEntry entry = (ZipEntry) entries.nextElement(); 

      if (!entry.isDirectory()) 
      { 
       FileTime fileTime = entry.getLastModifiedTime(); 
       long currentMillis = fileTime.toMillis(); 

       if (millis < currentMillis) 
       { 
        millis = currentMillis; 
       } 
      } 
     } 

     return new Date(millis); 
    } 

    /** 
    * Handles files, jar entries, and deployed jar entries in a zip file (EAR). 
    * 
    * @return The date if it can be determined, or null if not. 
    */ 
    private static Date getClassBuildTime() throws IOException, URISyntaxException 
    { 
     Date date = null; 
     Class<?> currentClass = new Object() 
     { 
     }.getClass().getEnclosingClass(); 
     URL resource = currentClass.getResource(currentClass.getSimpleName() + ".class"); 
     if (resource != null) 
     { 
      switch (resource.getProtocol()) 
      { 
       case "file": 
        date = new Date(new File(resource.toURI()).lastModified()); 
        break; 
       case "jar": 
       { 
        String path = resource.getPath(); 
        date = new Date(new File(path.substring(5, path.indexOf("!"))).lastModified()); 
        break; 
       } 
       case "zip": 
       { 
        String path = resource.getPath(); 
        File jarFileOnDisk = new File(path.substring(0, path.indexOf("!"))); 
        try (JarFile jarFile = new JarFile(jarFileOnDisk)) 
        { 
         ZipEntry zipEntry = jarFile.getEntry(path.substring(path.indexOf("!") + 2));//Skip the ! and the/
         long zeTimeLong = zipEntry.getTime(); 
         date = new Date(zeTimeLong); 
        } 
        break; 
       } 
      } 
     } 
     return date; 
    } 
} 

उपयोगिता वर्ग:

import java.io.File; 
import java.lang.invoke.MethodHandles; 
import java.net.URISyntaxException; 
import java.net.URLDecoder; 
import java.util.zip.ZipEntry; 
import java.util.zip.ZipFile; 

public class ProgramDirectoryUtilities 
{ 
    public static String getJARFilePath() throws URISyntaxException 
    { 
     return new File(MethodHandles.lookup().lookupClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getAbsolutePath(); 
    } 

    public static boolean runningFromJAR() 
    { 
     try 
     { 
      String jarFilePath = new File(MethodHandles.lookup().lookupClass().getProtectionDomain() 
        .getCodeSource() 
        .getLocation() 
        .getPath()). 
        toString(); 
      jarFilePath = URLDecoder.decode(jarFilePath, "UTF-8"); 

      try (ZipFile zipFile = new ZipFile(jarFilePath)) 
      { 
       ZipEntry zipEntry = zipFile.getEntry("META-INF/MANIFEST.MF"); 

       return zipEntry != null; 
      } 
     } catch (Exception exception) 
     { 
      return false; 
     } 
    } 

    public static String getProgramDirectory() 
    { 
     if (runningFromJAR()) 
     { 
      return getCurrentJARDirectory(); 
     } else 
     { 
      return getCurrentProjectDirectory(); 
     } 
    } 

    private static String getCurrentProjectDirectory() 
    { 
     return new File("").getAbsolutePath(); 
    } 

    private static String getCurrentJARDirectory() 
    { 
     try 
     { 
      return new File(MethodHandles.lookup().lookupClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParent(); 
     } catch (URISyntaxException exception) 
     { 
      exception.printStackTrace(); 
     } 

     return null; 
    } 

    public static boolean runningFromIntelliJ() 
    { 
     String classPath = System.getProperty("java.class.path"); 
     return classPath.contains("idea_rt.jar"); 
    } 
} 
संबंधित मुद्दे