Fork me on GitHub
#clojurescript
<
2023-06-09
>
Andrew Carlile02:06:39

Hello Wizards, I am developing a clj+cljs webapp https://github.com/jollyblondgiant/StrEats and it's been going rather smoothly until this afternoon. I redirected my focus from frontend work to expanding some routes in the backend and when I returned to running lein figwheel i get the error

Can't find 'figwheel.main' as .class or .clj for lein run: please check the spelling.
Syntax error (FileNotFoundException) compiling at (C:\Users\andre\AppData\Local\Temp\form-init14018966624002490164.clj:1:109).
Could not locate figwheel/main__init.class, figwheel/main.clj or figwheel/main.cljc on classpath.

Full report at:
path\to\clojure-11088497302024836677.edn
which reads:
{:clojure.main/message
 "Syntax error (FileNotFoundException) compiling at (path\to\form-init9425192894453551905.clj:1:108).\r\nCould not locate figwheel/main__init.class, figwheel/main.clj or figwheel/main.cljc on classpath.\r\n",
 :clojure.main/triage
 {:clojure.error/phase :compile-syntax-check,
  :clojure.error/line 1,
  :clojure.error/column 108,
  :clojure.error/source "form-init9425192894453551905.clj",
  :clojure.error/path
  "path\to\form-init9425192894453551905.clj",
  :clojure.error/class java.io.FileNotFoundException,
  :clojure.error/cause
  "Could not locate figwheel/main__init.class, figwheel/main.clj or figwheel/main.cljc on classpath."},
 :clojure.main/trace
 {:via
  [{:type clojure.lang.Compiler$CompilerException,
    :message
    "Syntax error compiling at (path\to\form-init9425192894453551905.clj:1:108).",
    :data
    {:clojure.error/phase :compile-syntax-check,
     :clojure.error/line 1,
     :clojure.error/column 108,
     :clojure.error/source
     "path\to\form-init9425192894453551905.clj"},
    :at [clojure.lang.Compiler load "Compiler.java" 7652]}
   {:type java.io.FileNotFoundException,
    :message
    "Could not locate figwheel/main__init.class, figwheel/main.clj or figwheel/main.cljc on classpath.",
    :at [clojure.lang.RT load "RT.java" 462]}],
  :trace
  [[clojure.lang.RT load "RT.java" 462]
   [clojure.lang.RT load "RT.java" 424]
   [clojure.core$load$fn__6856 invoke "core.clj" 6115]
   [clojure.core$load invokeStatic "core.clj" 6114]
   [clojure.core$load doInvoke "core.clj" 6098]
   [clojure.lang.RestFn invoke "RestFn.java" 408]
   [clojure.core$load_one invokeStatic "core.clj" 5897]
   [clojure.core$load_one invoke "core.clj" 5892]
   [clojure.core$load_lib$fn__6796 invoke "core.clj" 5937]
   [clojure.core$load_lib invokeStatic "core.clj" 5936]
   [clojure.core$load_lib doInvoke "core.clj" 5917]
   [clojure.lang.RestFn applyTo "RestFn.java" 142]
   [clojure.core$apply invokeStatic "core.clj" 669]
   [clojure.core$load_libs invokeStatic "core.clj" 5974]
   [clojure.core$load_libs doInvoke "core.clj" 5958]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.core$apply invokeStatic "core.clj" 669]
   [clojure.core$require invokeStatic "core.clj" 5996]
   [clojure.core$require doInvoke "core.clj" 5996]
   [clojure.lang.RestFn invoke "RestFn.java" 408]
   [user$eval140$fn__144 invoke "form-init9425192894453551905.clj" 1]
   [user$eval140 invokeStatic "form-init9425192894453551905.clj" 1]
   [user$eval140 invoke "form-init9425192894453551905.clj" 1]
   [clojure.lang.Compiler eval "Compiler.java" 7181]
   [clojure.lang.Compiler eval "Compiler.java" 7171]
   [clojure.lang.Compiler load "Compiler.java" 7640]
   [clojure.lang.Compiler loadFile "Compiler.java" 7578]
   [clojure.main$load_script invokeStatic "main.clj" 475]
   [clojure.main$init_opt invokeStatic "main.clj" 477]
   [clojure.main$init_opt invoke "main.clj" 477]
   [clojure.main$initialize invokeStatic "main.clj" 508]
   [clojure.main$null_opt invokeStatic "main.clj" 542]
   [clojure.main$null_opt invoke "main.clj" 539]
   [clojure.main$main invokeStatic "main.clj" 664]
   [clojure.main$main doInvoke "main.clj" 616]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.lang.Var applyTo "Var.java" 705]
   [clojure.main main "main.java" 40]],
  :cause
  "Could not locate figwheel/main__init.class, figwheel/main.clj or figwheel/main.cljc on classpath.",
  :phase :compile-syntax-check}}
I'm quite confused because I'm sure I didn't change anything related to figwheel while I was configuring my routes. I've tried deleting my target dir, running lein clean and lein deps, to no avail. I even restarted my machine. What's going wrong?

phronmophobic02:06:01

It looks like you added a plugin recently:

:plugins [[lein-environ "1.2.0"]]
If you comment that, does the figwheel problem go away? If not, I would try stepping back through your git history to see which commit might have introduced the problem.

phronmophobic02:06:35

Another issue to double check is if you've copy pasted some code with weird characters. I think I've seen similar errors where a config file has an “ instead of " and another where it was some weird unicode whitespace character.

Andrew Carlile02:06:25

it's strange, the issue persists if I remove that line or not, or any other mention of environ in my project. the issue also persists if I try commits from as far back as yesterday

phronmophobic03:06:40

Does running figwheel directly instead of using the alias make a difference?

lein run -m figwheel.main

Andrew Carlile03:06:37

the error looks the same. very spooku

phronmophobic03:06:48

Yea, I'm kinda running out of things to double check. • look at lein classpath to see if figwheel is there. • checkout your project from github into a new directory and see if the error still persists

Andrew Carlile03:06:11

figwheel is not on the classpath, in fact

phronmophobic03:06:19

ok, well there's a clue*

Andrew Carlile03:06:11

one thing I have changed, and which is not on the repo nor affected by version control, is my profiles.clj file which I made for environ

Andrew Carlile03:06:49

it looks like this:

{:dev {:env {:gmaps-api-key "a string"
             :server-port 3000
             :server-url "127.0.0.1"}}}

Andrew Carlile03:06:00

could it be that they are interfering?

phronmophobic03:06:28

I would try just commenting it out to find out.

phronmophobic03:06:08

I was just refreshing how https://codeberg.org/leiningen/leiningen/src/branch/stable/doc/PROFILES.md#default-profiles. > The :dev profile is used to specify project specific development tooling. Put things here if they are required for builds or tests, rather than just convenience tooling. > The :user profile is separate from :dev; the latter is intended to be specified in the project itself. In order to avoid collisions, the project should never define a :user profile, nor should a user-wide :dev profile be defined. Likewise, system profiles should use the :system profile, and define neither :user nor :dev profiles.

seancorfield03:06:59

☝️:skin-tone-2: So the :dev in your user profiles.clj is overriding the one in project.clj

phronmophobic03:06:04

So yea, it seems like you're not supposed to have a "user-wide :dev " profile.

seancorfield03:06:33

(checking out your project to fresh folder and lein run -m figwheel.main works -- so I was about to ask about your user profiles.clj)

seancorfield03:06:05

In general, I recommend folks leave that alone (and either empty {} or remove it).

Andrew Carlile03:06:28

what's a better way to develop with sensitive data?

seancorfield03:06:39

Probably the #1 cause of Leiningen problems I see here are people adding things to their user profiles.clj that then cause conflicts with their projects 😞

seancorfield03:06:22

As for sensitive data, I'd remove the lein-environ plugin -- you don't want what that provides -- and use the plain environ library.

Andrew Carlile03:06:11

is that just going to take stuff from sourcing .env files?

seancorfield03:06:20

Use environment variables or Java system properties to provide the keys/etc.

seancorfield03:06:27

At work, we use https://github.com/juxt/aero and have configuration/secrets in a file on each machine/server outside the project, so they can be controlled separately.

seancorfield03:06:24

Aero has a lot of nice affordances for handling env vars, including other config files, finding things on the classpath or the filesystem, etc.

Andrew Carlile03:06:52

can aero work for the cljs side of an app as well?

seancorfield03:06:02

Aero is compatible with ClojureScript, but think about code running in a browser and what access it has to things like the filesystem etc...

Andrew Carlile03:06:41

maybe defining an entire environment is too much work for what I need right now anyway, and that's keeping my server uri and port numbers safe somewhere so my frontend can send http requests to my server

Andrew Carlile03:06:54

not to mention the glaring security concern you mention

seancorfield03:06:58

In ClojureScript, it can't use system properties (JVM only) but it can use "environment" variables: https://github.com/juxt/aero/blob/master/src/aero/core.cljc#L46 You'd have to have the EDN for the configuration loadable into your cljs app -- so it would either have to be baked into your app or you'd have to fetch it from somewhere... but you'd have to know where to fetch it from 🙂

seancorfield03:06:30

(I don't do cljs so I've no idea what js/process.env is...)

seancorfield03:06:42

Looking at Aero some more, I think its cljs aspect is intended for use with ClojureScript running on Node.js on the server.

seancorfield04:06:30

(you'd be in the same boat with environ -- its cljs aspect is for Node.js on the server)

skylize16:06:02

process.env is provided by NodeJS and gives all the environment variables from the env it's running in. A browser would not provide that. https://nodejs.org/api/process.html#processenv

2