2010-05-01 15 views
5

Lese Wie kann ein Clojure-Programm seine eigene MANIFEST.MF finden (vorausgesetzt, es ist in einer JAR-Datei verpackt).Clojure-Programm seines eigenen MANIFEST.MF

Ich versuche, aus meinem „-main“ -Funktion zu tun, aber ich kann eine Klasse im folgenden Code zu verwenden, nicht finden:

(.getValue 
    (.. 
     (java.util.jar.Manifest. 
     (.openStream 
      (java.net.URL. 
      (str 
       "jar:" 
       (.. 
       (class **WHAT-GOES-HERE**) 
       getProtectionDomain 
       getCodeSource 
       getLocation) 
       "!/META-INF/MANIFEST.MF")))) 
     getMainAttributes) 
    "Build-number")) 

Dank.

+0

Danke, das war hilfreich. Ich habe ein bisschen Refactoring gemacht, weil ich davon besessen bin. Hier ist, was ich am Ende mit: (defn get-Funktion-Standort [sym] (.. (Klasse sym) getProtectionDomain getCodeSource getLocation)) (defn get-Manifest-Attribute [] (lass [location (get-funktion-location get-manifest-attribute)] (when-not (null? location) (-> (str "jar:" location "! /META-INF/MANIFEST.MF") (URL.) (.openStream) (Manifest.) (.getMainAttributes))))) –

+0

Korrektur: Übergeben des Symbols an die Funktion wurde nicht richtig funktionieren. Am Ende habe ich get-function-location get-location umbenannt und get-location an die Klasse übergeben. –

Antwort

3

Dies scheint zuverlässig zu arbeiten:

(defn set-version 
    "Set the version variable to the build number." 
    [] 
    (def version 
    (.getValue (.. (Manifest. 
     (.openStream 
     (URL. 
      (str "jar:" 
      (.getLocation 
       (.getCodeSource 
       (.getProtectionDomain org.example.myproject.thisfile))) 
      "!/META-INF/MANIFEST.MF")))) 
     getMainAttributes) 
     "Build-number"))) 
0

Ich habe eine Antwort gefunden, die funktioniert, aber ich bin offen für Vorschläge zur Verbesserung, insbesondere den Anruf zu Class/forName ersetzen.

(defn -main [& args] 
    (println "Version " 
    (.getValue 
     (.. 
     (Manifest. 
      (.openStream 
      (URL. 
       (str 
       "jar:" 
       (.. 
        (Class/forName "org.example.myproject.thisfile") 
        getProtectionDomain 
        getCodeSource 
        getLocation) 
       "!/META-INF/MANIFEST.MF")))) 
     getMainAttributes) 
     "Build-number"))) 
1

ich meine Version ein wenig leichter auf die Augen finden:

(defn manifest-map 
    "Returns the mainAttributes of the manifest of the passed in class as a map." 
    [clazz] 
    (->> (str "jar:" 
      (-> clazz 
       .getProtectionDomain 
       .getCodeSource 
       .getLocation) 
      "!/META-INF/MANIFEST.MF") 
     clojure.java.io/input-stream 
     java.util.jar.Manifest. 
     .getMainAttributes 
     (map (fn [[k v]] [(str k) v])) 
     (into {}))) 

(get (manifest-map MyClass) "Build-Number") 
1

Hier ist eine lesbare Version, etwa so einfach, wie ich bekommen konnte es!

(when-let [loc (-> (.getProtectionDomain clazz) .getCodeSource .getLocation)] 
    (-> (str "jar:" loc "!/META-INF/MANIFEST.MF") 
     URL. .openStream Manifest. .getMainAttributes 
     (.getValue "Build-Number"))) 
0

Es gibt auch clj-manifest, die im Wesentlichen diese Funktionalität bereitstellt, finden Sie hier die ein Aufruf ähnlich wie in anderen Antworten verwenden.

Verwandte Themen