Clojure Game Of Life App on Heroku

A while ago I created a heroku account to try it out. They allow you to host clojure web apps in the cloud. One worker is for free and there are also quite more languages supported.

In order to practice some clojure I implemented game of life and packaged it into a lib. Here does leiningen help you a lot, it is the maven of the clojure world and also creates maven compatible jar files.

My app was originally printing out the game of life world to the CLI but now outputs it as text/plain.

I won’t repeat the steps to setup heroku since they are explained very well on heroku: http://devcenter.heroku.com/articles/clojure

The result can be accessed here: http://gentle-journey-9851.herokuapp.com/

The state is globally shared through all requests. So don’t be surprised if there are some generations missing.

The code and library is available on github. The game of life source code is included in the jar, in case some is interested. I might have a different post about this later.

https://github.com/dedeibel/herokus_game_of_clojure_life

To start the app:

Prerequisites: leiningen

To run locally, simple run

$ lein run -m herokutest.web 5000

or

$ foreman start

And visit http://localhost:5000

(ns herokutest.web
  (:use [game_of_life.cell :only (new_cell)])
  (:use [game_of_life.world_printer :only (to_string)])
  (:use [game_of_life.world_builder :only (from_string)])
  (:use [game_of_life.game :only (next_generation)])
  (:use ring.adapter.jetty)
)

(def twentyfour_and_more
"xx
,xx
,
,
,
,                                   x x  xxx
,                                   x x    x
,                                   xxx  xxx
,                                     x  x
,                                     x  xxx
,                                                                                                   xx  
,                                                                                                  x  x
,                                                                                                 x    x
,                                                                                                x      x
,                                                                                                x      x
,                                                                                                 x    x
,                                                                                                  x  x
,                                                                                                   xx"
)

(def counter (atom 0))
(def world (atom (from_string twentyfour_and_more new_cell)))

(defn app [req]
  (let [current @world]
    (swap! counter inc)
    (swap! world next_generation)
    {:status 200
     :headers {"Content-Type" "text/plain"}
     :body 
       (str "Game Of Life (Step " @counter "):\n" (to_string current))
    }
  )
)

(defn -main [port]
  (run-jetty app {:port (Integer. port)}))
Advertisements

clojure lein gives error „Exception in thread „main“ java.lang.RuntimeException: java.lang.NoSuchMethodError: clojure.lang.KeywordLookupSite …“

For all of you searching for this problem when running lein (1.6) and clojure (1.3). You have to add the clojure directory to your classpath. Simple as that. :-\

$ lein help
Exception in thread "main" java.lang.RuntimeException: java.lang.NoSuchMethodError: clojure.lang.KeywordLookupSite.(ILclojure/lang/Keyword;)V
at clojure.lang.Util.runtimeException(Util.java:165)
at clojure.lang.Compiler.eval(Compiler.java:6476)
at clojure.lang.Compiler.eval(Compiler.java:6431)
at clojure.core$eval.invoke(core.clj:2795)
at clojure.main$eval_opt.invoke(main.clj:296)
at clojure.main$initialize.invoke(main.clj:315)
at clojure.main$script_opt.invoke(main.clj:339)
at clojure.main$main.doInvoke(main.clj:426)
at clojure.lang.RestFn.invoke(RestFn.java:457)
at clojure.lang.Var.invoke(Var.java:413)
at clojure.lang.AFn.applyToHelper(AFn.java:172)
at clojure.lang.Var.applyTo(Var.java:518)
at clojure.main.main(main.java:37)
Caused by: java.lang.NoSuchMethodError: clojure.lang.KeywordLookupSite.(ILclojure/lang/Keyword;)V
at leiningen.util.paths$native_arch_path.(paths.clj:32)
at leiningen.util.paths__init.load(Unknown Source)
at leiningen.util.paths__init.(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at clojure.lang.RT.loadClassForName(RT.java:2030)
at clojure.lang.RT.load(RT.java:417)
at clojure.lang.RT.load(RT.java:398)
at clojure.core$load$fn__4610.invoke(core.clj:5386)
at clojure.core$load.doInvoke(core.clj:5385)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5200)
at clojure.core$load_lib.doInvoke(core.clj:5237)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:602)
at clojure.core$load_libs.doInvoke(core.clj:5271)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:602)
at clojure.core$require.doInvoke(core.clj:5352)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at leiningen.core$loading__4414__auto__.invoke(core.clj:1)
at leiningen.core__init.load(Unknown Source)
at leiningen.core__init.(Unknown Source)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at clojure.lang.RT.loadClassForName(RT.java:2030)
at clojure.lang.RT.load(RT.java:417)
at clojure.lang.RT.load(RT.java:398)
at clojure.core$load$fn__4610.invoke(core.clj:5386)
at clojure.core$load.doInvoke(core.clj:5385)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invoke(core.clj:5200)
at clojure.core$load_lib.doInvoke(core.clj:5237)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invoke(core.clj:602)
at clojure.core$load_libs.doInvoke(core.clj:5271)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invoke(core.clj:604)
at clojure.core$use.doInvoke(core.clj:5363)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at user$eval1.invoke(NO_SOURCE_FILE:1)
at clojure.lang.Compiler.eval(Compiler.java:6465)
... 11 more

Setting the paths:


echo "export CLOJURE_HOME=$HOME/Opt/clojure
export CLASSPATH=$CLASSPATH:$CLOJURE_HOME" >> $HOME/.profile

lein works, tadaaa:

$ lein help
Leiningen is a tool for working with Clojure projects.

Several tasks are available:
classpath Print the classpath of the current project.