Trying to import libraries in Clojure

I have a problem with a code I am developing in Clojure:

(ns problem2 (:require [cheshire.core :as json]
                       [clojure.spec.alpha :as s]
                       [invoice-spec]))

(defn json->map [file-name]
  (-> file-name
      slurp
      json/parse-stream
      :invoice))

(defn generate-invoice [file-name]
  (let [invoice (json->map file-name)
        customer {:name (:company_name (:customer invoice))
                  :email (:email (:customer invoice))}
        items (map (fn [item]
                     {:price (:price item)
                      :quantity (:quantity item)
                      :sku (:sku item)
                      :taxes (map (fn [tax]
                                    {:category (keyword (:tax_category tax))
                                     :rate (:tax_rate tax)})
                                  (:taxes item))})
                   (:items invoice))]
    {:issue-date (java.util.Date. (:issue_date invoice))
     :customer customer
     :items items}))

(defn -main []
  (let [invoice (generate-invoice "invoice.json")]
    (if (s/valid? ::invoice-spec/invoice invoice)
      (println "Invoice is valid")
      (println "Invoice is not valid"))))

When I try to import external libraries here, and using deps.edn:

{:deps {org.clojure/data.json {:mvn/version "2.4.0"}
        org.clojure/clojure {:mvn/version "1.10.3"}
        org.clojure/spec.alpha {:mvn/version "0.2.194"}
        cheshire {:mvn/version "5.10.0"}}
       }

There is always the same error, just like this:

Execution error (FileNotFoundException) at problem2/eval138$loading (problem2.clj:1).
Could not locate cheshire/core__init.class, cheshire/core.clj or cheshire/core.cljc on classpath.

I don't know what I am doing wrong, please help. Pd. I need to develop the solution using deps.edn. Thanks

Upvotes: 1

Views: 103

Answers (2)

Arek C.
Arek C.

Reputation: 1581

The problem is most likely due to you running clojure problem2.clj from src directory instead of root of your project. When you run it's from src Clojure doesn't detects deps.edn and doesn't load these libraries. Also it's deprecated to use unqualified lib names, but you probably already read it as Clojure will warn you about it.

The solution is to change directory to the root of your project and from there run clj src/problem2.clj or whatever path to your file is. Also in Clojure during development you don't really use console to run your code but rather REPL integrated with your IDE/editor like Cider for Emacs, Calva for Visual Studio Code, Fireplace for Vim, Conjure for NeoVim or Cursive for IntelliJ

Upvotes: 0

Alan Thompson
Alan Thompson

Reputation: 29958

Here is a simple way to get going:

~ > mkdir expr
~ > cd expr
~/expr > git clone https://github.com/io-tupelo/clj-template.git  demo-703
Cloning into 'demo-703'...
remote: Enumerating objects: 130, done.
remote: Counting objects: 100% (130/130), done.
remote: Compressing objects: 100% (72/72), done.
remote: Total 130 (delta 46), reused 110 (delta 26), pack-reused 0
Receiving objects: 100% (130/130), 217.82 KiB | 1.47 MiB/s, done.
Resolving deltas: 100% (46/46), done.

~/expr > cd demo-703
~/expr/demo-703 > clojure -X:test

Running tests in #{"test"}

Testing tst._bootstrap

-------------------------------------
   Clojure 1.12.0-beta1    Java 21
-------------------------------------

Testing tst.demo.core

Ran 2 tests containing 5 assertions.
0 failures, 0 errors.

This is a simple template project using deps.edn with everything in the correct location & format.

I then modified the deps.edn to include:

 :deps    {
           org.clojure/clojure {:mvn/version "1.12.0-beta1"}
           prismatic/schema    {:mvn/version "1.4.1"}
           tupelo/tupelo       {:mvn/version "23.07.04"}
           cheshire/cheshire   {:mvn/version "5.10.0"}
           }

Notice that you need cheshire/cheshire. Also, I added to the unit test:

  (is= (json/encode {:a 1 :b [2 3]})
       "{\"a\":1,\"b\":[2,3]}")
  )

Upvotes: -2

Related Questions