This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-03-17
Channels
- # announcements (6)
- # babashka (2)
- # babashka-sci-dev (1)
- # beginners (74)
- # calva (3)
- # cider (33)
- # clj-kondo (19)
- # cljsrn (10)
- # clojure (75)
- # clojure-dev (11)
- # clojure-europe (39)
- # clojure-italy (1)
- # clojure-nl (1)
- # clojure-spec (4)
- # clojure-uk (6)
- # clojurescript (139)
- # code-reviews (8)
- # core-typed (7)
- # data-science (1)
- # docs (2)
- # emacs (11)
- # events (1)
- # introduce-yourself (8)
- # lsp (4)
- # malli (10)
- # off-topic (15)
- # pedestal (5)
- # podcasts (4)
- # polylith (18)
- # re-frame (6)
- # react (1)
- # reagent (18)
- # reitit (6)
- # releases (2)
- # rewrite-clj (1)
- # spacemacs (15)
- # sql (2)
- # vscode (5)
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: https://github.com/borkdude/deps.clj
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 [com.google.protobuf/protobuf-java "3.19.4"]
and proto2
. one of the errors is
error: cannot find symbol com.google.protobuf.Descriptors.OneofDescriptor
user=> (import com.google.protobuf.Descriptors)
com.google.protobuf.Descriptors
user=> (import com.google.protobuf.Descriptors.OneofDescriptor)
Execution error (ClassNotFoundException) at java.net.URLClassLoader/findClass (URLClassLoader.java:445).
com.google.protobuf.Descriptors.OneofDescriptor
user=> (import com.google.protobuf.Descriptors$OneofDescriptor)
Execution error (IncompatibleClassChangeError) at java.lang.ClassLoader/defineClass1 (ClassLoader.java:-2).
class com.google.protobuf.Descriptors$OneofDescriptor has interface com.google.protobuf.Descriptors$GenericDescriptor as super class
https://javadoc.io/static/com.google.protobuf/protobuf-java/3.19.4/com/google/protobuf/Descriptors.OneofDescriptor.html
I never used protocol buffers with java or clojure before. Can someone please help me outThis .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
error: OneofDescriptor is not public in Descript ors; cannot be accessed from outside package com.google.protobuf.Descriptors$OneofDescriptor
Ah, I'm still waking up - managed to miss that you actually did use $
, my bad.
>
class com.google.protobuf.Descriptors$OneofDescriptor has interface com.google.protobuf.Descriptors$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 https://javadoc.io/doc/com.google.protobuf/protobuf-java/latest/com/google/protobuf/Descriptors.OneofDescriptor.html FQN of OneofDescriptor in java is com.google.protobuf.Descriptors.OneofDescriptor in clojure it should be com.google.protobuf.Descriptors$OneofDescriptor Since OneofDescriptor is used in .java file, com.google.protobuf.Descriptors.OneofDescriptor 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
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. 😅
No, I mean work out what javac call lein javac is making, then do the same thing to see if your code compiles
I stumbled across it when the proto dependency and compiler versions weren't the same
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
Example.java 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 [com.google.protobuf/protobuf-java 3.19.4] other than clojure as dependencyprotoc -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/Example.java 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?
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 https://github.com/clj-time/clj-time/blob/master/src/clj_time/periodic.clj does but with clojure.java-time/Date-Time API?
Not sure, but maybe https://github.com/juxt/tick
... which has an example in those docs linked by lukasz, if you search within the page... no direct link
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]

I agree that it's not great that it silently does the wrong thing.
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: https://github.com/jafingerhut/funjible
I wrote a big old fat warning about this here years ago: https://clojuredocs.org/clojure.set/union
(scroll down a little bit to see my comment)
funjible downloaded 96 times in 4 years on Clojars (practically unknown & unused)
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 https://github.com/jafingerhut/funjible 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 (http://clojuredocs.org) and alternative libraries, they never seem to satisfy people.
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.
A-ha! Here's an "http://ask.clojure.org" suggestion that you can upvote: https://ask.clojure.org/index.php/3341/add-clojure-union-intersection-difference-core-spec-alpha?show=3341#q3341
@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.
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.
https://github.com/borkdude/speculative 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?