Clojure程序读取自己的MANIFEST.MF文件

6

如何在Clojure程序中找到自己的MANIFEST.MF文件(假设它已经被打包成JAR文件)。

我正在尝试从我的“-main”函数中完成此操作,但是我无法找到下面代码中要使用的类:

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

谢谢。

谢谢,这很有帮助。我进行了一些重构,因为我对此很执着。以下是我的最终代码:(defn get-function-location [sym] (.. (class sym) getProtectionDomain getCodeSource getLocation))(defn get-manifest-attributes [] (let [location (get-function-location get-manifest-attributes)] (when-not (nil? location) (-> (str "jar:" location "!/META-INF/MANIFEST.MF") (URL.) (.openStream) (Manifest.) (.getMainAttributes))))) - Sarah Roberts
更正:将符号传递给函数时出现了问题。最终我将get-function-location重命名为get-location,并将get-location传递给类。 - Sarah Roberts
5个回答

4

这似乎可以可靠地工作:

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

3
我觉得我的版本更易读一些:

我发现我的版本更容易阅读:

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

2
这是一个易读版本,尽可能简单明了!
(when-let [loc (-> (.getProtectionDomain clazz) .getCodeSource .getLocation)]
  (-> (str "jar:" loc "!/META-INF/MANIFEST.MF")
      URL. .openStream Manifest. .getMainAttributes
      (.getValue "Build-Number")))

1

还有clj-manifest,它使用类似于此处找到的其他答案的调用来提供此功能。


0

我已经找到了一个可行的答案,但是我很乐意听取改进建议,特别是替换对 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")))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接