zcaudate
zcaudate

Reputation: 14258

how to load resources from a specific .jar file using clojure.java.io

In clojure.java.io, there is a io/resource function but I think it just loads the resource of the current jar that is running. Is there a way to specify the .jar file that the resource is in?

For example:

I need functions that can do these operations:

(list-jar "/path/to/abc.jar" "some/text/")
;; => "output.txt"

(read-from-jar "/path/to/abc.jar" "some/text/output.txt")
;; => "The required text that I want"

Thanks in advance!

Upvotes: 1

Views: 1145

Answers (1)

zcaudate
zcaudate

Reputation: 14258

From Ankur's comments, I managed to piece together the functions that I needed:

The java.util.jar.JarFile object does the job.

you can call the method (.entries (Jarfile. a-path)) to give the list of files but instead of returning a tree structure:

i.e:

/dir-1
  /file-1
  /file-2
  /dir-2
    /file-3
  /dir-3
    /file-4

it returns an enumeration of filenames:

/dir-1/file-1, /dir-1/file-2, /dir-1/dir-2/file-3, /dir-1/dir-3/file-4

The following functions I needed are defined below:

(import java.util.jar.JarFile)
(defn list-jar [jar-path inner-dir]
  (if-let [jar          (JarFile. jar-path)]
    (let [inner-dir    (if (and (not= "" inner-dir) (not= "/" (last inner-dir)))
                         (str inner-dir "/")
                         inner-dir)
          entries      (enumeration-seq (.entries jar))
          names        (map (fn [x] (.getName x)) entries)
          snames       (filter (fn [x] (= 0 (.indexOf x inner-dir))) names)
          fsnames      (map #(subs % (count inner-dir)) snames)]
      fsnames)))

(defn read-from-jar [jar-path inner-path]
  (if-let [jar   (JarFile. jar-path)]
    (if-let [entry (.getJarEntry jar inner-path)]
      (slurp (.getInputStream jar entry)))))

Usage:


(read-from-jar "/Users/Chris/.m2/repository/lein-newnew/lein-newnew/0.3.5/lein-newnew-0.3.5.jar"
               "leiningen/new.clj")

;=> "The list of built-in templates can be shown with `lein help new`....."

(list-jar  "/Users/Chris/.m2/repository/lein-newnew/lein-newnew/0.3.5/lein-newnew-0.3.5.jar" "leiningen")
;; => (new/app/core.clj new/app/project.clj .....)

Upvotes: 2

Related Questions