04 Jun 2014, 16:04
Generic-user-small

Peter Marshall (3 posts)

Hi, first thanks for a great book.

I have tested the app bundled with embedded Jetty server which works fine. When I bundle up the app with HTTP Kit (Paper book page 139.) the app fails to load any of the environment properties from the project.clj (reports nil for password, user and subname properties) when I load the home page.

Screen shows : db-spec {:password nil, :subprotocol “postgresql”, :user nil, :subname nil} is missing a required parameter.

I cant see why this should be. Do you have any ideas? TIA Pete

04 Jun 2014, 16:09
Generic-user-small

Peter Marshall (3 posts)

Just for extra info Im running Light Table 0.6.5 for all the work. java -version -> java version “1.6.0_65” OSX Mavericks

04 Jun 2014, 22:28
Profile_pic_pragsmall

Dmitri Sotnikov (44 posts)

I don’t think I made this clear in the book, but the variables defined in project.clj will only be visible when you run the app using lein. When you compile the app using lein uberjar these variables must be passed in from the environment. Two common ways of doing is are setting the variables in the shell or passing them as Java flags, eg:

export USER=foo
...

or

java -Duser=foo -D... -jar target/picture-gallery-0.1.0-SNAPSHOT-standalone.jar
06 Jun 2014, 17:14
Generic-user-small

Peter Marshall (3 posts)

Hi Dmitri, thanks for the response. This is the only step that hasn’t worked so far!! Its still not quite working. I use the following command line :

java -Ddbuser=pm -Ddburl=//localhost/gallery -Dgalleriespath=/Users/pm/dev/projects/web_dev_cloj/picture-gallery/galleries -Ddbpass=pm   -jar target/picture-gallery-0.1.0-SNAPSHOT-standalone.jar 

I modified main.clj to be like :


  ...      [environ.core :refer [env]])
  (:gen-class))
(defn -main [& [port]]
  (def db
  {:subprotocol "postgresql"
   :subname (env :dburl)
   :user (env :dbuser)
   :password (env :dbpass)})
 (println db).....

This outputs {:subprotocol postgresql, :subname //localhost/gallery, :user pm, :password pm} as expected. However, when i navigate to the home page I still get an error caused by these properties being null (because its using the database) I did actually get the app to work for a short while and Im wondering if there is an order/timing problem somewhere. For example, the db is used in a macro so when do the env properties get read?

Thanks for your help. Pete

06 Jun 2014, 23:50
Profile_pic_pragsmall

Dmitri Sotnikov (44 posts)

You definitely don’t want to do a def inside a function as you’re doing in the example. A better way would be to create an atom for the properties and populate it in the init function of the handler. So, you’d want to have something like the following.

First, update your picture-gallery.models.db to use an atom for config:

(defonce db (atom nil))

(defmacro with-db [f & body]
  `(sql/with-connection (deref db) (~f ~@body)))

Then in your init function in the picture-gallery.handler, reference the db and set the configuration during startup:

(ns picture-gallery.handler
  (:require ...
           [picture-gallery.models.db :refer [db]]
           [environ.core :refer [env]]))

(defn init []
   ...

  (reset! db
   {:subprotocol "postgresql"
    :subname (env :dburl)
    :user (env :dbuser)
    :password (env :dbpass)})

  (timbre/info "picture-gallery started successfully"))

This way you’re guaranteed that the configuration will be read when your application is initialized.

  You must be logged in to comment