Error / when trying to use persistent (file) storage for client-api

Hi all,

I am very new to clojure (and datomic).

I am trying to setup datomic local for exploring and better understanding the concept(s).

I cannot get local storage to work and am not sure what i am doing wrong.

src/testlocaldb.clj:
(ns testlocaldb
  (:use [clojure.test])
  (:require [datomic.client.api :as d]))

./src/testlocaldb.clj:
(defn run [opts]
  "success"
  (def client-a (d/client {:server-type :datomic-local
    :storage-dir :mem
    :system "dev"}))

  "failure"
  (def client-b (d/client {:server-type :datomic-local
    :system "dev"})))

Running this code (under wsl JDK 21) gives error:

clj -X testlocaldb/run

Execution error (IllegalArgumentException) at datomic.dev-local.impl/validate-storage-dir! (impl.clj:339).
No implementation of method: :as-file of protocol: #'clojure.java.io/Coercions found for class: clojure.lang.Symbol

./src/deps.edn:

{:deps {
    clojure.java-time/clojure.java-time {:mvn/version "1.1.0"}
    com.datomic/local    {:mvn/version "1.0.285"}
}}

~/.datomic/local.edn:

{:storage-dir "/home/X/clj/datomic/log"}

Hi Frunnik!

Try explicitly setting your storage dir in the connection string if you are going to execute the program with clj. I would expect your setup to work from a REPL on a machine with this local.edn file. Have you confirmed it works just from a clojure REPL in the project?

But try this:

  (def client-b (d/client {:server-type :datomic-local
    :storage-dir "/home/X/clj/datomic/log"
    :system "dev"})))

I confirmed this works from my REPL on a machine with java 21:

Using java version 21.0.4-amzn in this shell.
jaret.binford at jaret in ~/Jaret/projects/support/localtest
$ java -version
openjdk version "21.0.4" 2024-07-16 LTS
OpenJDK Runtime Environment Corretto-21.0.4.7.1 (build 21.0.4+7-LTS)
OpenJDK 64-Bit Server VM Corretto-21.0.4.7.1 (build 21.0.4+7-LTS, mixed mode, sharing)
jaret.binford at jaret in ~/Jaret/projects/support/localtest
$ clojure
Clojure 1.12.0
user=> (ns jaretbinford.localtest
  (:use [clojure.test])
  (:require [datomic.client.api :as d]))
nil
jaretbinford.localtest=>   (def client-c (d/client {:server-type :datomic-local
                           :storage-dir "/Users/jaret.binford/Jaret/projects/support/localtest/datomic/log/test"
                           :system "dev"})
)
#'jaretbinford.localtest/client-c
jaretbinford.localtest=>  (def client-b (d/client {:server-type :datomic-local
                           :system "dev"}))
#'jaretbinford.localtest/client-b
jaretbinford.localtest=> 

I also tested to see if I could run with clj which also seemed to work:

jaret.binford at jaret in ~/Jaret/projects/support/localtest
$ clj -X jaretbinford.localtest/run

Thank you very much - that fixed it.

Im still learning the difference between the syntax / working between the REPL and program and I guess I mixed the two up in composing my code from different examples …

1 Like

I am always learning too. Given that this fixed it I suspect wherever you were running did not have access to the :storage-dir or perhaps that .datomic file did not exist with it defined on that place.