【问题标题】:Clojure program reading its own MANIFEST.MFClojure 程序读取自己的 MANIFEST.MF
【发布时间】:2010-05-01 18:13:52
【问题描述】:

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)))))
  • 更正:将符号传递给函数无法正常工作。我最终将 get-function-location 重命名为 get-location 并将 get-location 传递给类。

标签: clojure manifest


【解决方案1】:

这似乎工作可靠:

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

【讨论】:

    【解决方案2】:

    我发现我的版本更容易看:

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

    【讨论】:

      【解决方案3】:

      这是一个可读的版本,尽可能简单!

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

          我找到了一个可行的答案,但是我愿意接受改进它的建议,特别是替换对 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")))
          

          【讨论】:

            猜你喜欢
            • 2016-02-02
            • 2011-05-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-12-20
            • 1970-01-01
            相关资源
            最近更新 更多