Fork me on GitHub

Hi there. I have a seemingly silly question which I hope someone can enlighten me: What is the difference between the Clojure deps in a project (e.g. org.clojure/clojure {:mvn/version "1.10.3"}) and the Clojure CLI itself (e.g. clj/`clojure` command) and how are they related? What happens when there is a mismatch between these two versions? Thanks in advance 🙂


@rextruong clj / clojure are essentially bash scripts that build a call to an uberjar which packages tools.deps.alpha. tools.deps.alpha then calculates a classpath and returns this to the script. The script then starts a java process with this classpath. This classpath can contain any Clojure version, completely unrelated to the clj / clojure version you have installed.


I see. Thank you for answering 🙂 This has always been a bit confusing for me after coming from Java land 😅


I've also translated those bash scripts to Clojure, you can see those here:


Hi. I am trying to use google’s protocol buffers in a clojure project. lein javac to compile .java files, produced by protoc compiler, is failing. I am using protoc of version 3.19.4 and [ "3.19.4"] and proto2 . one of the errors is error: cannot find symbol

user=> (import

user=> (import
Execution error (ClassNotFoundException) at (

user=> (import$OneofDescriptor)
Execution error (IncompatibleClassChangeError) at java.lang.ClassLoader/defineClass1 (
class$OneofDescriptor has interface$GenericDescriptor as super class I never used protocol buffers with java or clojure before. Can someone please help me out


If it's a nested class, replace the last . in its FQN with $.


This .java code is generated by the protoc compiler. There are other errors too. This . notation is inside .java file, so it is a valid java code. Shouldn’t lein javac take care of it itself.

error: OneofDescriptor is not public in Descriptors; cannot be accessed from outside package                                                                                                         


replacing . with $ did not work


error: OneofDescriptor is not public in Descript ors; cannot be accessed from outside package$OneofDescriptor


Ah, I'm still waking up - managed to miss that you actually did use $, my bad. >

class$OneofDescriptor has interface$GenericDescriptor as super class 
Weird - that's not in the source code, it's public abstract static class GenericDescriptor there. Are you trying the latest version?


protoc is of version 3.19.4 - it is the latest one protobuf-java is of version 3.19.4 - but it is not latest, but it looks same as latest version FQN of OneofDescriptor in java is in clojure it should be$OneofDescriptor Since OneofDescriptor is used in .java file, is the right FQN I don’t even understand the error now


I would make sure that the protobuf-java JAR is on the classpath. protoc will generate whatever it wants to generate without regard to that


protobuf-java jar is on the classpath


output of lein classpath has /Users/harshakiranboyapati/.m2/repository/com/google/protobuf/protobuf-java/3.19.4/protobuf-java-3.19.4.jar


If you want to make sure, you can run javac with the same arguments that lein javac generates and verify it works correctly. If it doesn't, then lein is misleading you. 😅


lein javac `lein classpath`   did not give any errors


No, I mean work out what javac call lein javac is making, then do the same thing to see if your code compiles

Ben Sless14:03:34

Check your protoc version

Ben Sless14:03:20

I stumbled across it when the proto dependency and compiler versions weren't the same


protoc is of version 3.19.4 and protobuf-java is of version 3.19.4


lein version
Leiningen 2.9.8 on Java 17.0.2 OpenJDK 64-Bit Server VM

protoc version
libprotoc 3.19.4
Attached files of a trivial project, which is giving the same error while trying to compile generated java code to java bytecode is the file generated by protoc on compiling person.proto lein-javac-error.txt has the console output of lein javac project.clj only has [ 3.19.4] other than clojure as dependency


protoc -I=resources --java_out=src/java resources/proto/person.proto is the command used to generate .java from .proto


→ lein javac
Retrieving org/clojure/clojure/1.10.3/clojure-1.10.3.pom from central
Retrieving org/clojure/spec.alpha/0.2.194/spec.alpha-0.2.194.pom from central
Retrieving org/clojure/core.specs.alpha/0.2.56/core.specs.alpha-0.2.56.pom from central
Retrieving nrepl/nrepl/0.8.3/nrepl-0.8.3.pom from clojars
Retrieving org/nrepl/incomplete/0.1.0/incomplete-0.1.0.pom from clojars
Retrieving org/clojure/core.specs.alpha/0.2.56/core.specs.alpha-0.2.56.jar from central
Retrieving org/clojure/spec.alpha/0.2.194/spec.alpha-0.2.194.jar from central
Retrieving org/clojure/clojure/1.10.3/clojure-1.10.3.jar from central
Retrieving org/nrepl/incomplete/0.1.0/incomplete-0.1.0.jar from clojars
Retrieving nrepl/nrepl/0.8.3/nrepl-0.8.3.jar from clojars
Compiling 1 source files to /home/conor/dev/Coats/temp/target/classes
Note: /home/conor/dev/Coats/temp/src/java/person/ uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.




But how do u get a success message in first try and I have been stuck with this error for days what is your protoc version


Also what is your leiningen version Does the generated java code matches with what has been generated for me? Anything else that could be the reason?


protoc --version
libprotoc 3.19.4


lein --version
Leiningen 2.9.8 on Java 11.0.11 OpenJDK 64-Bit Server VM


javac is compiling the java code generated by protoc just fine but lein javac is failing for me


Is anyone working with protocol buffers in clojure? If you are, did you not face any issue while compiling generated .java files to .class files? if you did not face any issues please share the steps u have followed. If you did face issues please share the steps u have taken to resolve them. Thanks in advance:slightly_smiling_face:


I've done this in the past. We created a separate project with the protobuf files that compiled to class files, then required that as a dependency in the Clojure project. The protobuf files were a schema defining data provided by another team, so we deployed them as an artifact to our internal artifactory.


But I think that if you're using the new Clojure build tools, there's a way to include preparation steps like this.


javac is compiling the java code generated by protoc just fine but lein javac is failing for me


Anyone knows how to get what does but with API?


Yes, Tick can do that

👍 1

yeah tick has a range function which is basically the same thing


... which has an example in those docs linked by lukasz, if you search within the page... no direct link


cool, thanks! didn't look at that one.


Just found a production bug related to clojure.set/union - was quite surprised by that

(set/union [1 2 3] #{3 4 5})
  ;; => [1 2 3 4 3 5]

universe_guy 1
R.A. Porter22:03:59

I agree that it's not great that it silently does the wrong thing.


Yep, and there's no mention about it in the docstring.


An answer that can be often seen from the core team in such situations - if it's not in the docstring, then the behavior is undefined. In this case, the docstring talks about "input sets" and doesn't talk about any other types. So using instances of any other types as inputs is undefined behavior.


Oh, yeah - I know about this "GIGO approach" but it's quite easy to miss and make a mistake 😞


Many people have pointed this out over the years, but it seems that once you know about it, no one seems to care about it so much that they use a library like this:


I wrote a big old fat warning about this here years ago:


(scroll down a little bit to see my comment)


funjible downloaded 96 times in 4 years on Clojars (practically unknown & unused)


In theory, couldn't someone write a spec with which to instrument clojure.set?


Definitely. I have done it. Performance numbers in the funjible project README, but sure, as long as you only turn spec checking on during testing, not deployment, the significant performance hit won't matter as much.


I'm wondering if at least expanding the docstring or maybe even checking the inputs or coercing to sets would be doable here


It's doable but has been discussed a number of times, both here and on Google Groups - it won't happen. The reasoning is that the current state is sufficient and that changing it would require for it to be changed everywhere to be consistent - that would be a whole paradigm shift.


@U06BE1L6T If a library like already exists and does nothing additional except check the inputs, would you consider using it?


Or does it HAVE TO BE IN CORE in order to consider it?


I am curious, since despite pointing out alternative docs ( and alternative libraries, they never seem to satisfy people.

Joshua Suskalo15:03:24

I think that people are generally pretty averse to adding in new dependencies, and if the dependency just does something that you can already do with core, even if it's a little better or less error prone, people just won't add it even if they know about it.


@U5NCUG8NR I agree that people should be averse to adding dependencies willy-nilly. This one is one that you cannot do with core as it is. Or if you can, it is by adding something functionally equivalent to funjible in your own code and using that instead. I do understand the wish that this stuff was in core, but unless the core developers change their minds in a very significant way, do not hold your breath on that.

Joshua Suskalo16:03:16

Oh yeah, I agree with you on that, and I do conceptually like having more checking available. Something I've noticed in my own code and in others' as well though is that Clojure programmers seem averse to error-like situations, and are more likely to program code in such a way as to make errors just not happen rather than use or write code that handles errors better, so honestly I expect more to happen when the core team eventually gets around to speccing core (which is a stated eventual goal) than I expect to happen from any library that adds additional error checking.

vemv06:03:17 seems a sound, non-disruptive approach to me


As long as the performance hit of spec (which is significant -- see the perf stats in the funjible library readme) is OK for you. Perhaps during testing it is. I doubt it would be for production use with many calls to those functions.


Even very simple sanity checks in spec are very slow compared to a hand-coded type check.


Hi random question, if I have two independent async operations that might be called, and I want them never to both happen at the same time (eg. say they're both messing with the same file and would corrupt it if they ran together), the only way I can think of to do that in clojure (without using java locking) is to put the resource they're contending behind a channel and pipeline-async with parallelism 1 to basically serialize the access. Is that a reasonable way to do it and what others exist? Also is my scenario understandable?


I realize I could also use a go macro and manual <! but I'm counting that as basically the same thing as that paralellism 1 pipeline-async although if anyone has a strong preference for one over the other, that would be interesting


sorry, also let's say it has to be clojurescript compatible, so no STM or other clojure-specific async tools, although I'm curious which would be right


I would definitely prefer a single go loop to a pipeline when the whole point is to have no parallelism


pipeline-async is also has some subtlety to it, a single go loop over a channel is less likely to be screwed up


it is already the case that js is singled threaded, so you can maybe use reader conditionals to noop whatever concurrency control is needed in clojurescript


js is single threaded but if the two operations both have async parts they might still get interleaved as operations on [thing that must be worked on by one thing at a time]? Like you don't have shared mutable state INSIDE the language/runtime but might still want this logical exclusion of a resource? Is that right?


which is why I said "maybe", depending on what you are doing you may be able to take advantage of the single threaded nature of js