This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-02-09
Channels
- # announcements (4)
- # babashka (25)
- # beginners (11)
- # calva (32)
- # clj-kondo (5)
- # clojure (130)
- # clojure-dev (11)
- # clojure-europe (17)
- # clojure-nl (1)
- # clojure-norway (96)
- # clojure-spec (1)
- # clojure-uk (3)
- # clojurescript (9)
- # conjure (2)
- # cursive (8)
- # datalevin (1)
- # etaoin (14)
- # ghostwheel (2)
- # hyperfiddle (13)
- # joker (2)
- # leiningen (82)
- # malli (3)
- # pathom (4)
- # polylith (12)
- # releases (3)
- # spacemacs (7)
- # sql (3)
I have a hybrid clojure/java app and am seeing an issue where my project doesn’t automatically invoke javac on the java sources, and I dont understand why. I have done this in the past. Any tips on what to check?
I do have
:source-paths ["src/clojure"]
:java-source-paths ["src/java"]
set, and I don’t have any prep-task overrides.So far the only thing that has worked has been to set up a :precomp profile like
:profiles {:precomp {:java-source-paths ["src/java"]}
and then running
lein with-profile precomp javac
the fundamental issue seems to be that if I dont do this, it tries to process clojure files first…but the clojure code depends on the java code so it fails. I’ve done similar things in the past and it just worked, so I am scratching my head as to what is wrong in this project.
Theres nothing in the project file…but what I dont know is if some plugin may alter it
You can do DEBUG=true ahead of your lein command to get more details of what it is doing.
ok, that helped move the needle a bit. I immediately started with “DEBUG=true lein uberjar” to narrow it down and it actually did the right thing, giving me a hint that its not so much the overall config, but my flow
I have a Makefile and in there are other tasks like lein eastwood and lein cloverage that run before the build
I dont know if this is meaningful to you, but when I enable debugging for one of the broken tasks
$ DEBUG=true lein cloverage
Leiningen's classpath: /usr/local/Cellar/leiningen/2.10.0/libexec/leiningen-2.10.0-standalone.jar
Applying task cloverage to []
Applying task javac to nil
Running javac with [@/var/folders/bl/s_t9lqxx2glgf9dv7h7z54g40000gn/T/.leiningen-cmdline84724007947143382.tmp]
Warning: environ value /Users/ghaskins/.jenv/versions/system for key :java-home has been overwritten with /Library/Java/JavaVirtualMachines/jdk-21.jdk/Contents/Home
Warning: protocol #'manetu.policyengine.api/policyengine is overwriting function test
WARNING: test already refers to: #'clojure.core/test in namespace: manetu.policyengine.api, being replaced by: #'manetu.policyengine.api/test
WARNING: test already refers to: #'clojure.core/test in namespace: manetu.policyengine.core, being replaced by: #'manetu.policyengine.core/test
Reflection warning, protojure/grpc/codec/lpm.clj:184:5 - reference to field close can't be resolved.
Exception in thread "main" Syntax error macroexpanding at (manetu/lambda_service/subservice/executor/wasm/guest_context.clj:1:1).
Of course, if I run the precomp profile or build the uberjar first, javac runs in the right timing
$ DEBUG=true lein uberjar
Leiningen's classpath: /usr/local/Cellar/leiningen/2.10.0/libexec/leiningen-2.10.0-standalone.jar
Applying task uberjar to []
Applying task javac to nil
Running javac with [@/var/folders/bl/s_t9lqxx2glgf9dv7h7z54g40000gn/T/.leiningen-cmdline15031772485933302220.tmp]
Compiling 35 source files to /Users/ghaskins/sandbox/git/mcp-lambda-service/target/uberjar/classes
Note: Annotation processing is enabled because one or more processors were found
on the class path. A future release of javac may disable annotation processing
unless at least one processor is specified by name (-processor), or a search
path is specified (--processor-path, --processor-module-path), or annotation
processing is enabled explicitly (-proc:only, -proc:full).
Use -Xlint:-options to suppress this message.
Use -proc:none to disable annotation processing.
Note: /Users/ghaskins/sandbox/git/mcp-lambda-service/src/java/io/github/kawamuray/wasmtime/Func.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Compiling 35 source files to /Users/ghaskins/sandbox/git/mcp-lambda-service/target/uberjar/classes
well, to be clear, I set that in the top-level config, too. I only added the precomp profile as a hack
:source-paths ["src/clojure"]
:java-source-paths ["src/java"]
:repl-options {:init-ns user}
:eastwood {:add-linters [:unused-namespaces]
:exclude-linters [:unused-meta-on-macro :local-shadows-var :unused-ret-vals]}
:profiles {:precomp {:java-source-paths ["src/java"]}
:dev {:dependencies [[clj-http "3.12.3" :exclusions [commons-io]]
[org.clojure/tools.namespace "1.4.5"]
[criterium "0.4.6"]
[eftest "0.6.0"]
[clj-kondo "2023.12.15"]
[mockery "0.1.4"]
[integrant/repl "0.3.3"]]
:resource-paths ["jna/target" "jna/target/release" "test/lambdas"]
:aliases {"clj-kondo" ["run" "-m" "clj-kondo.main"]}}
:uberjar {:aot :all
:omit-source true
:target-path "target/uberjar"
:uberjar-name "app.jar"
:uberjar-exclusions [#".*manetu.*\.clj[xcs]*"]
:jvm-opts ["-Dclojure.compiler.direct-linking=true"]}}
where
:profiles {:precomp {:java-source-paths ["src/java"]}
Was added in desperation as a hackI had hammered it with rm -rf target, but let me do it the right way and see what happens
ah ok, probably that covered it - just making sure you didn’t somehow have old classfiles somewhere causing issue
its like it ignores the java-source-paths when the source-paths [“src/clojure”] is present
or, maybe it schedules java-source-paths as secondary, but we never live long enough to get there
The default prep-tasks
should run javac
first and javac
explicitly compiles the :java-source-paths
that it finds.
But did you have issues with anything else before you tried using the profile precomp
?
You said lein uberjar
works with no special :aliases
right? So it’d just be based on the top-level project.clj merged with the :uberjar
profile.
right…i didnt try any other flows…i have a top level makefile that does this (currently)
all: scan test bin security-scan
precomp:
lein with-profile precomp javac
scan: precomp
lein cljfmt check
lein bikeshed -l false -n false
#lein kibit
lein eastwood
at the time, I didnt realize uberjar would actually work (should have thought to try that)
Yeah, with the precomp
done first - you leave the classfiles in the :target-path
and the other tasks will get them on their classpath
the part I dont get is where lein is making the decision to compile the java-source-paths in some cases but not others
I don’t understand how every plugin would be susceptible to the same problem though. It isn’t something I’ve heard of I think.
If it was one plugin, I’d wonder if it perhaps altered prep-tasks or didn’t merge with your project top-level - but even then that’d be pretty odd and probably always broken.
I’ll basically git clone the lein version you want to deal with. Then I’ll launch a repl directly in leiningen and try to recreate the project setup via something like leiningen.core.project/read
and then make sure I get the same profile configuration state and then look for things like :java-source-paths
there etc.
I probably could write a tiny post on this at some point, but it’s not that elegant.
Yeah, in worst-case, you could just script that you manually ensure the javac is ran correctly before each plugin task - like you have.
so, it looks like cljfmt is fine, probably because it doesnt need the classfiles present…bikeshed, eastwood, and cloverage all seem to suffer the same fate
in any case, ty for talking it through with me. I at least discovered that the uberjar target works, which at least instills some confidence in me that the config isnt fundamentally broken
Ok, sounds good. I’m making a TODO to see if I can recreate your issue with a tiny project with cloverage
as an example - to see if I can understand better what happened. I probably wont’ get to that for a few days though.
I’ll let you know though if I find out anything interesting there.