Skip to content

Instantly share code, notes, and snippets.

@Reder
Created March 16, 2013 18:32
Show Gist options
  • Save Reder/5177673 to your computer and use it in GitHub Desktop.
Save Reder/5177673 to your computer and use it in GitHub Desktop.
In order to get a resource from the standalone jar and run directly when development, I have to use following code to get the true file path. I wonder if there is some better way…
(ns my.utils
(:gen-class)
(:use clojure.tools.logging
clj-logging-config.log4j)
(:use [clojure.string :only (split)])
(import (java.util.zip ZipFile))
(import (java.io File
FileInputStream
FileOutputStream
BufferedInputStream
BufferedOutputStream)))
;; find the path of the jar. via: http://stackoverflow.com/a/13276993/1364840
(defn this-jar
"utility function to get the name of jar in which this function is invoked"
[]
(-> (class *ns*)
.getProtectionDomain .getCodeSource .getLocation .getPath))
; copy file from one file to another
(defn copy-file [input-stream output-stream]
(with-open [in (BufferedInputStream. input-stream)
out (BufferedOutputStream. output-stream)]
(loop [buf (make-array Byte/TYPE 1024)]
(let [len (.read in buf)]
(when (pos? len)
(.write out buf 0 len)
(recur buf))))))
; get path with the file name.
; deal with the condition when the file is in a jar.
(defn get-path [file-name]
(let [jar-file (ZipFile. (File. (this-jar)))]
(if-let [file-entry (.getEntry (ZipFile. (File. (this-jar))) file-name)]
(let [splitted (split file-name #"\.")
prefix (first splitted)
suffix (str "." (second splitted))
temp (File/createTempFile prefix suffix)]
(.deleteOnExit temp)
(with-open [input-stream (.getInputStream jar-file (.getEntry jar-file file-name))
output-stream (FileOutputStream. temp)]
(copy-file input-stream output-stream))
(.getAbsolutePath temp))
(.getFile (clojure.java.io/resource file-name)))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment