2010-05-01 4 views
5

Chương trình Clojure có thể tìm MANIFEST.MF của riêng nó như thế nào (giả sử nó được đóng gói trong tệp JAR).Chương trình Clojure đọc MANIFEST.MF riêng của mình

Tôi cố gắng để làm điều này từ tôi chức năng "-main", nhưng tôi không thể tìm thấy một lớp học để sử dụng trong đoạn mã sau:

(.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")) 

Cảm ơn.

+0

Cảm ơn, điều này hữu ích. Tôi đã làm một chút refactoring bởi vì tôi là ám ảnh về điều đó. Đây là những gì tôi đã kết thúc với: (defn get-Hàm-vị trí [sym] (.. (lớp sym) getProtectionDomain getCodeSource getLocation)) (defn get-manifest-thuộc tính [] (cho [vị trí (get-function-location get-manifest-attributes)] (khi không (vị trí không) (-> (str "jar:" location "! /META-INF/MANIFEST.MF") (URL.) (.openStream) (Tệp kê khai.) (.getMainAttributes))))) –

+0

Chỉnh sửa: chuyển biểu tượng cho hàm không hoạt động chính xác. Tôi đã kết thúc việc đổi tên địa điểm get-function-get-location và chuyển get-location sang lớp. –

Trả lời

3

Điều này dường như làm việc đáng tin cậy:

(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

Tôi đã tìm thấy câu trả lời phù hợp, tuy nhiên tôi mở để gợi ý cải thiện nó, đặc biệt là thay thế cuộc gọi thành Class/forName.

(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

tôi thấy phiên bản của tôi dễ dàng hơn một chút trên mắt:

(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

Dưới đây là một phiên bản có thể đọc được, về đơn giản như tôi có thể nhận được nó!

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

Cơ bản cung cấp chức năng này, sử dụng cuộc gọi tương tự với các câu trả lời khác được tìm thấy tại đây.