Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Leiningen uberjar "empty" running time

Tags:

clojure

After creating a uberjar with leiningen, and running the jar with java -jar foo-uberjar.jar the program runs fine, and the last line of code is executed quite fast, but the program hangs for about a minute before shutting down. What is the cause of this?

(ns redditwallpaper.core
  (:gen-class)
  (:require [clojure.contrib.duck-streams :as duck]
            [clojure.java [io :as io] [shell :as shell]]
            [clojure.string :as string]
            [clojure.contrib.json :as json])
  (:import (java.util Random)))

(defn filename [uri]
  (last (string/split uri #"/")))
(defn over_18 [x]
  (:over_18 x))
(defn posts [x]
  (map :data (get-in x [:data :children])))
(defn plain-image [x]
  (re-find #"(.jpg|.png)$" (:url x)))
(def url "http://www.reddit.com/r/wallpaper.json")
(def wallpaperjson (json/read-json (slurp url)))
(defn copy [uri fname]
  (with-open [in (io/input-stream uri)
              out (io/output-stream fname)]
    (.write out (duck/to-byte-array in))))
(defn randrange [n]
  (.nextInt (Random.) n))
(defn randitem [xs]
  (let [n (count xs)]
    (nth xs (randrange n))))
(defn set-background [file]
  (shell/sh "feh" "--bg-scale" file))
(defn -main [& args]
  (let [posts (posts wallpaperjson)
        safe (filter (complement over_18) posts)
        images (filter plain-image safe)
        image (:url (randitem images))
        fname (filename image)]
    (do
      (println (format "Downloading '%s'" image))
      (copy image fname)
      (println (format "Setting background image to '%s'" fname))
      (set-background fname)
      (println "Done"))))

java -jar redditwallpaper-0.0.1-standalone.jar 2.71s user 0.34s system 4% cpu 1:03.15 total

like image 413
Masse Avatar asked Aug 24 '11 09:08

Masse


2 Answers

Try adding,

(shutdown-agents)

when you are ready to exit.

like image 74
Hamza Yerlikaya Avatar answered Oct 26 '22 15:10

Hamza Yerlikaya


I've noticed in in my experiments with bash/clojure interop that a better way might be to simply use the lein-exec plugin, for a couple of reasons.

First off, it works well for me so far.

I also ran a couple of time commands from bash to get a feeling for the difference between my original idea - which was basically to make a lein template for scripts - on the one hand, and lein-exec on the other.

On the one hand, my experiment. I hadn't made a lein template yet, but the idea was this:

(ns closcrite.core
  (:require [clojure.java.shell :as shell])
  (:gen-class))

(defn -main
  "I don't do a whole lot."
  [& args]
  (let [shell-output (apply shell/sh args)]
    (println (shell-output :out))
    (shutdown-agents)))

The (shutdown-agents) sexpr is simply because I ran into this problem. Without (shutdown-agents):

lein compile && lein uberjar 
  && time java -jar target/closcrite-0.1.0-SNAPSHOT-standalone.jar "ls" "-ahl"
Compiling closcrite.core
Compilation succeeded.
All namespaces already :aot compiled.
Created /home/j/Development/closcrite/target/closcrite-0.1.0-SNAPSHOT.jar
Including closcrite-0.1.0-SNAPSHOT.jar
Including clojure-1.4.0.jar
Created /home/j/Development/closcrite/target/closcrite-0.1.0-SNAPSHOT-standalone.jar
total 36K
drwxrwxr-x  6 j j 4.0K Aug 18 18:14 .
drwxrwxr-x 26 j j 4.0K Aug 18 17:55 ..
drwxrwxr-x  2 j j 4.0K Aug 18 17:55 doc
-rw-rw-r--  1 j j   99 Aug 18 17:55 .gitignore
-rw-rw-r--  1 j j  325 Aug 18 18:14 project.clj
-rw-rw-r--  1 j j  199 Aug 18 17:55 README.md
drwxrwxr-x  3 j j 4.0K Aug 18 17:55 src
drwxrwxr-x  4 j j 4.0K Aug 18 18:02 target
drwxrwxr-x  3 j j 4.0K Aug 18 17:55 test


real    1m2.585s
user    0m4.188s
sys     0m0.120s

With (shutdown-agents):

lein compile && lein uberjar 
    && time java -jar target/closcrite-0.1.0-SNAPSHOT-standalone.jar "ls" "-ahl"                                                                
Compiling closcrite.core
Compilation succeeded.
All namespaces already :aot compiled.
Created /home/j/Development/closcrite/target/closcrite-0.1.0-SNAPSHOT.jar
Including closcrite-0.1.0-SNAPSHOT.jar
Including clojure-1.4.0.jar
Created /home/j/Development/closcrite/target/closcrite-0.1.0-SNAPSHOT-standalone.jar
total 36K
drwxrwxr-x  6 j j 4.0K Aug 18 18:14 .
drwxrwxr-x 26 j j 4.0K Aug 18 17:55 ..
drwxrwxr-x  2 j j 4.0K Aug 18 17:55 doc
-rw-rw-r--  1 j j   99 Aug 18 17:55 .gitignore
-rw-rw-r--  1 j j  325 Aug 18 18:14 project.clj
-rw-rw-r--  1 j j  199 Aug 18 17:55 README.md
drwxrwxr-x  3 j j 4.0K Aug 18 17:55 src
drwxrwxr-x  4 j j 4.0K Aug 18 18:02 target
drwxrwxr-x  3 j j 4.0K Aug 18 17:55 test


real    0m2.817s
user    0m3.796s
sys     0m0.084s

On the other hand, lein-exec:

      time lein exec -e "(ns blah 
                             (:require [clojure.java.shell :as shell])) 
                         (print ((shell/sh \"ls\" \"-ahl\") :out))"
    total 36K
    drwxrwxr-x  6 j j 4.0K Aug 18 18:14 .
    drwxrwxr-x 26 j j 4.0K Aug 18 17:55 ..
    drwxrwxr-x  2 j j 4.0K Aug 18 17:55 doc
    -rw-rw-r--  1 j j   99 Aug 18 17:55 .gitignore
    -rw-rw-r--  1 j j  325 Aug 18 18:14 project.clj
    -rw-rw-r--  1 j j  199 Aug 18 17:55 README.md
    drwxrwxr-x  3 j j 4.0K Aug 18 17:55 src
    drwxrwxr-x  4 j j 4.0K Aug 18 18:02 target
    drwxrwxr-x  3 j j 4.0K Aug 18 17:55 test

    real    0m1.371s
    user    0m2.136s
    sys     0m0.120s

Of course time isn't the be-all end-all in profiling, but it's a nice indication of speed. For the user the inline lein-exec shell script feels almost 2x as fast as the code I used to model the execution time of a minimal leiningen shell script template.

like image 31
jjpe Avatar answered Oct 26 '22 15:10

jjpe