This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-05-22
Channels
- # announcements (4)
- # babashka (10)
- # beginners (25)
- # biff (4)
- # calva (22)
- # clj-on-windows (3)
- # clj-otel (1)
- # clojure (17)
- # clojure-europe (5)
- # clojure-gamedev (2)
- # clojure-norway (1)
- # clojurescript (21)
- # conjure (5)
- # core-async (3)
- # defnpodcast (1)
- # deps-new (8)
- # events (3)
- # graalvm (10)
- # graphql (4)
- # gratitude (2)
- # hyperfiddle (7)
- # introduce-yourself (4)
- # jobs (1)
- # membrane (9)
- # pedestal (5)
- # quil (2)
- # re-frame (7)
- # releases (2)
- # rewrite-clj (14)
- # shadow-cljs (8)
- # tools-deps (5)
I'm running into these require/next.jdbc errors when I attempt
to create a postgres database:
Unhandled java.io.FileNotFoundException
Could not locate next/jdbc__init.class, next/jdbc.clj or next/jdbc.cljc on
classpath.
and the following.
1. Caused by java.lang.RuntimeException
No such namespace: jdbc
Here's my db setup:
(ns cljblog.db)
(require '[next.jdbc :as jdbc])
(def db
{:dbtype "postgresql"
:dbname "cljblog"
:host "localhost"
:user "postgres"
:password "postgres"})
(def ds (jdbc/get-datasource db))
(def ds (jdbc/get-datasource db))
(def conn (jdbc/get-connection ds))
(jdbc/execute! conn ["
-- postgresql version
drop table if exists posts?;
create table posts (
id int,
title varchar(255),
body text,
author varchar(25)
"])
(jdbc/execute! conn ["
insert into posts(title,body,author)
values('Working with postgres',
'this is my first attempt at working
with postgres in Clojure', 'Sam Dees')"])
(def result-set
(jdbc/execute!
conn
["select * from posts"]))
and the project.clj
(defproject cljblog "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url ""
:min-lein-version "2.0.0"
:dependencies [[org.clojure/clojure "1.10.0"]
[compojure "1.6.1"]
[ring/ring-defaults "0.3.2"]
[hiccup "1.0.5"]
[com.github.seancorfield/next.jdbc "1.2.780"]
[org.postgresql/postgresql "9.4-1201-jdbc41"]]
:plugins [[lein-ring "0.12.5"]]
:ring {:handler cljblog.handler/app}
:repl-options {:init-ns clj-jdbc.core}
:profiles
{:dev {:dependencies [[javax.servlet/servlet-api "2.5"]
[ring/ring-mock "0.3.2"]]}})
You need to share the full stacktrace so we can see where the error comes from (I see you've posted this on StackOverflow, ClojureVerse, and Slack).
Your project.clj
specifies clj-jdbc.core
as the initial namespace and you haven't shared that (in src/clj_jdbc/core.clj
) and, as on SO, I want to check you've restarted your REPL after adding com.github.seancorfield/next.jdbc
as a dependency?
Here's the full stack trace.
Show: Project-Only All
Hide: Clojure Java REPL Tooling Duplicates (25 frames hidden)
2. Unhandled clojure.lang.Compiler$CompilerException
Error compiling src/cljblog/db.clj at (12:9)
#:clojure.error{:phase :compile-syntax-check,
:line 12,
:column 9,
:source "/home/2fo/projects/cljblog/src/cljblog/db.clj"}
Compiler.java: 6808 clojure.lang.Compiler/analyze
Compiler.java: 6745 clojure.lang.Compiler/analyze
Compiler.java: 3820 clojure.lang.Compiler$InvokeExpr/parse
Compiler.java: 7108 clojure.lang.Compiler/analyzeSeq
Compiler.java: 6789 clojure.lang.Compiler/analyze
Compiler.java: 38 clojure.lang.Compiler/access$300
Compiler.java: 596 clojure.lang.Compiler$DefExpr$Parser/parse
Compiler.java: 7106 clojure.lang.Compiler/analyzeSeq
Compiler.java: 6789 clojure.lang.Compiler/analyze
Compiler.java: 6745 clojure.lang.Compiler/analyze
Compiler.java: 7180 clojure.lang.Compiler/eval
Compiler.java: 7131 clojure.lang.Compiler/eval
core.clj: 3214 clojure.core/eval
core.clj: 3210 clojure.core/eval
interruptible_eval.clj: 87 nrepl.middleware.interruptible-eval/evaluate/fn/fn
AFn.java: 152 clojure.lang.AFn/applyToHelper
AFn.java: 144 clojure.lang.AFn/applyTo
core.clj: 665 clojure.core/apply
core.clj: 1973 clojure.core/with-bindings*
core.clj: 1973 clojure.core/with-bindings*
RestFn.java: 425 clojure.lang.RestFn/invoke
interruptible_eval.clj: 87 nrepl.middleware.interruptible-eval/evaluate/fn
main.clj: 414 clojure.main/repl/read-eval-print/fn
main.clj: 414 clojure.main/repl/read-eval-print
main.clj: 435 clojure.main/repl/fn
main.clj: 435 clojure.main/repl
main.clj: 345 clojure.main/repl
RestFn.java: 1523 clojure.lang.RestFn/invoke
interruptible_eval.clj: 84 nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 56 nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 152 nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
AFn.java: 22 clojure.lang.AFn/run
session.clj: 218 nrepl.middleware.session/session-exec/main-loop/fn
session.clj: 217 nrepl.middleware.session/session-exec/main-loop
AFn.java: 22 clojure.lang.AFn/run
Thread.java: 829 java.lang.Thread/run
1. Caused by java.lang.RuntimeException
No such namespace: jdbc
Util.java: 221 clojure.lang.Util/runtimeException
Compiler.java: 7383 clojure.lang.Compiler/resolveIn
Compiler.java: 7357 clojure.lang.Compiler/resolve
Compiler.java: 7318 clojure.lang.Compiler/analyzeSymbol
Compiler.java: 6768 clojure.lang.Compiler/analyze
Compiler.java: 6745 clojure.lang.Compiler/analyze
Compiler.java: 3820 clojure.lang.Compiler$InvokeExpr/parse
Compiler.java: 7108 clojure.lang.Compiler/analyzeSeq
Compiler.java: 6789 clojure.lang.Compiler/analyze
Compiler.java: 38 clojure.lang.Compiler/access$300
Compiler.java: 596 clojure.lang.Compiler$DefExpr$Parser/parse
Compiler.java: 7106 clojure.lang.Compiler/analyzeSeq
Compiler.java: 6789 clojure.lang.Compiler/analyze
Compiler.java: 6745 clojure.lang.Compiler/analyze
Compiler.java: 7180 clojure.lang.Compiler/eval
Compiler.java: 7131 clojure.lang.Compiler/eval
core.clj: 3214 clojure.core/eval
core.clj: 3210 clojure.core/eval
interruptible_eval.clj: 87 nrepl.middleware.interruptible-eval/evaluate/fn/fn
AFn.java: 152 clojure.lang.AFn/applyToHelper
AFn.java: 144 clojure.lang.AFn/applyTo
core.clj: 665 clojure.core/apply
core.clj: 1973 clojure.core/with-bindings*
core.clj: 1973 clojure.core/with-bindings*
RestFn.java: 425 clojure.lang.RestFn/invoke
interruptible_eval.clj: 87 nrepl.middleware.interruptible-eval/evaluate/fn
main.clj: 414 clojure.main/repl/read-eval-print/fn
main.clj: 414 clojure.main/repl/read-eval-print
main.clj: 435 clojure.main/repl/fn
main.clj: 435 clojure.main/repl
main.clj: 345 clojure.main/repl
RestFn.java: 1523 clojure.lang.RestFn/invoke
interruptible_eval.clj: 84 nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 56 nrepl.middleware.interruptible-eval/evaluate
interruptible_eval.clj: 152 nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
AFn.java: 22 clojure.lang.AFn/run
session.clj: 218 nrepl.middleware.session/session-exec/main-loop/fn
session.clj: 217 nrepl.middleware.session/session-exec/main-loop
AFn.java: 22 clojure.lang.AFn/run
Thread.java: 829 java.lang.Thread/run
The :repl-options {:init-ns clj-jdbc.core}
can be ignored, I haven't created that namespace (it fails with and without it). It's a cut and past job from a demo next.jdbc/postgres project .
The repl was restarted after the addition of the next.jdbc dependency.
I cross posted this for posterity/SEO (do let me know if that's OTT). I'll update each post with the answer.
As always when debugging issues like this, I recommend trying it in a plain REPL outside your editor to eliminate interactions with other tooling. No nREPL, no CIDER. Those tools sometimes interfere with stack traces etc
Sorry, the final part of my last message was poorly worded, it should've been "I'll update each post as and when I have the answer". I actually haven't found the solution yet.
How is a fullstack Clojure(Script) application structured?
Suppose you use shadow-cljs for CLJS development of an SPA client and manage the overall project with Clojure CLI (deps.edn). Do you just have frontend and backend subdirectories under src
? Is the backend API’s CLJ REPL started separately from the CLJS one?
I don’t have a coherent way of reasoning about this yet. Pointers to resources/examples would be appreciated. Thanks!
With a SPA, I ususally start them separately and use src/clj
for backend code, src/cljs
for frontend code, and src/cljc
for shared code. I experimented quite a bit with different setups. Perhaps you can have a look if one of these suits you as a starting point https://github.com/eighttrigrams/cljc-protos
I wondered about shared code and src/cljc
seems like a great fit. Thanks for sharing. 😃
Enjoying reading through this prototypical setup in particular:
https://github.com/eighttrigrams/cljc-protos/tree/main/fullstack-clj
for an opposite opinion, see the following https://shadow-cljs.github.io/docs/UsersGuide.html#source-paths in shadow-cljs user guide:
> It is not recommended to separate source files by extension (eg. src/clj
, src/cljs
, src/cljc
). For some reason this is widely used in CLJS project templates but it just makes things harder to use.
I intuitively agree with that (anti-?)recommendation for a frontend project, but less so in the case where a project consists of backend, frontend, and shared code. :thinking_face: How do you structure fullstack projects, @U0178V2SLAY?
I don't personally have strong opinions either way. At the moment I'm working with projects which follow the src/clj
/`src/cljc`/`src/cljs` -convention and I do find it a bit ceremonious. A common case is "this .clj
file should actually be .cljc
" which requires moving it to the "other side" instead of just renaming it. Also, if you want to define macros for clojurescript (in a .clj
file), where do you put it/them?
If I was starting from scratch, I think I'd try to follow a couple of rules. First, separate generic infrastructure code (logging, database connection pooling, e.g. stuff you could use in another project) from your domain specific code. Second, within your domain specific code, I would group stuff by features ("here's the backend api, views and domain rules related to feature X") , not by functionality ("all backend api namespaces go in here, all frontend views go over there"). But I'm no expert nor authority on matters like this, so I make no promises that this is the best way 🙂
@U0178V2SLAY I think I just followed what I thought to be the canonical way here and also suspected that the reason for doing it that way would be for reasons that the respective compilers see only "their own" stuff, because it is separated by different source-paths. It is great to hear that there is another option on the table and there are certain things that I like about it, so I'll definitely try. As for the 'where do put the macros', I just put them to the cljc
folder if they were shared. Are there any differences between to cljc
vs clj
macros?
sure, and I don't think there's anything wrong with clj
/`cljc`/`cljs` separation, lots of projects use it and it might make it easier to reason about stuff (also, some have suggested server
, client
, and common
instead). Especially if you also have java sources in your project, it might make sense to have src/java
for them to keep things nice and symmetrical. But on the other hand I don't know if anything actually requires it so it might give you more freedom to organize things semantically if you ignore the file type. I remember doing Java Spring projects, where you must organize stuff by their functionality, because you had to configure stuff by their package name (e.g. "all my web controllers are under org.company.program.app.controller -package") to make it work. I wasn't really a big fan of restrictions like that.
fyi: https://code.thheller.com/blog/shadow-cljs/2019/10/12/clojurescript-macros.html an article highlighting some gotchas in macros, and suggests using plain clj macros for simplicity
Yeah there are many ways to structure the codebase and it’s a bit finding some optimum for a given project. But anyway, thanks for the hints and also for the link!
Hi, all! Using gen/let
from test.check, I am trying to generate a vector of 0s and 1s and its inverse.
The following does not work because the binding for inv-bits
is not a generator.
(gen/generate
(gen/let [bits (gen/vector (gen/choose 0 1))
inv-bits (map #(bit-xor 1 %) bits)]
[bits inv-bits]))
However, the following also does not work because bits
in the fmap
is not a generator.
(gen/generate
(gen/let [bits (gen/vector (gen/choose 0 1))
inv-bits (gen/fmap #(map (partial bit-xor 1) %) bits)]
[bits inv-bits]))
Is there an idiomatic way of wrapping bits
as a generator when used in subsequent bindings? I am essentially looking for a "passthrough" generator that always generates the same value, but I can't seem to find one.Yep, just found it after going through the docs for a 3rd time... Thanks a lot mate!
Hi. I am almost done with Eric Normand’s course: Beginner Clojure: An Eric Normand Signature Course. I would like to take the following courses next (also from Eric). In which order should I take them: A then B or B then A? A. ClojureScript Frontend: An Eric Normand Signature Course 1: Understanding Re-frame Learn the most popular frontend framework in ClojureScript. 2: ClojureScript Markdown Editor Build an interactive markdown editor application with live preview and bidirectional editing. • shadow-cljs • npm • Reagent • Deploy to Netlify 3: Building Re-frame Components Learn to build many interactive widgets and components in Re-frame and Reagent. We go through many examples of common GUI widgets and learn to build them ourselves B. Clojure Web Backend: An Eric Normand Signature Course 1. Web dev in Clojure 2. HTTP client: clj-http Thanks
I would recommend taking B. first so you get a good understanding of HTTP request/response handling and understand how to build APIs -- because you'll want to have a backend for your frontend app to talk to as soon as you get beyond writing simple in-browser ClojureScript apps. But I may be a bit biased because I'm primarily a backend dev. You can get a lot done with just a backend, and SSR (Server-Side Rendering), and you can enhance it with stuff like HTMX and some JS to add interactivity without going full SPA (Single-Page Application).
I see. That makes a lot of sense. Thanks @U04V70XH6!