This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-07-29
Channels
- # announcements (10)
- # aws (4)
- # babashka (42)
- # beginners (208)
- # bristol-clojurians (2)
- # calva (13)
- # chlorine-clover (52)
- # cider (5)
- # clara (22)
- # clj-kondo (2)
- # clojars (14)
- # clojure (107)
- # clojure-europe (24)
- # clojure-nl (4)
- # clojure-uk (6)
- # clojurescript (3)
- # conjure (20)
- # cursive (23)
- # datascript (2)
- # datomic (15)
- # figwheel-main (3)
- # fulcro (23)
- # jobs (3)
- # kaocha (5)
- # keechma (3)
- # local-first-clojure (1)
- # malli (13)
- # off-topic (16)
- # planck (6)
- # re-frame (8)
- # reagent (3)
- # reitit (1)
- # releases (1)
- # remote-jobs (1)
- # rum (1)
- # sci (37)
- # shadow-cljs (16)
- # tools-deps (158)
- # vim (3)
- # xtdb (8)
(OK, running 1.10.1.596 on all our servers at work now š )
how would one represent this in deps.edn
?
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc-bom</artifactId>
<version>19.7.0.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc10</artifactId>
</dependency>
</dependencies>
for the context: https://www.oracle.com/database/technologies/maven-central-guide.html#DIY
@abdusalam Pretty sure you'll need to figure out what that Bill Of Materials expands to and add each of those dependencies directly to deps.edn
thanks, Sean. does it mean there's no direct, built-in support in tools.deps for this kind of use case?
Not as far as I'm aware.
no, deps does not support the BOM / import scope stuff
it seems radical, but deps just expects you to list the specific dependencies you're using :)
i see. oracle's jdbc driver (com.oracle.database.jdbc/ojdbc10) used to list other "extra goodies" as dependencies in its pom.xml. i was looking for an elegant way to exclude the extra stuff in order to avoid doing the "exclusion dance" but just found out that it's dropped all of the dependencies since version 19.7.0.0. all we need to do now is to add com.oracle.database.jdbc/ojdbc10 {:mvn/version "19.7.0.0"}
to get just the driver itself. š
yeah, that's all most people need. the whole bom thing seems like something an enterprise java developer thought up while they were high
So I really appreciate the expanded deps guide and reference, but there are two things from the previous iteration of the docs that I found useful that appear to have disappeared now: One was the old deps data-flow/arg/alias mapping diagram: https://github.com/clojure/clojure-site/blob/master/assets/images/content/guides/deps/deps.png which I appreciate might now either need to be two diagrams, or reworked into a more complex one. Whilst itās not something I used often, I thought it was effective in the guide at showing what aliases influenced each phase of execution etc. And the other perhaps more importantly was the āAliasesā section in the old docs here: https://github.com/clojure/clojure-site/blob/285fda270445a70af9b1ec7bdb069309d2d224d7/content/reference/deps_and_cli.adoc#aliases which clearly described how keys in a deps file were used by the command line alias flags. Are there any plans to bring updated versions of these sections back?
the docs are (always) a work in progress. I pulled the diagram b/c it was way out of date. I have updated it a number of times during the process of the basis changes but I have concerns about whether it actually provides that much value as it has grown increasingly complicated. All of the info from the old Aliases section is still in the doc.
i found that diagram quite helpful, when i was initially learning the clojure cli.
in practice however, i never really had to use anything else then -A
so far...
Second question ā how stable are the new features in tools.deps? In particular the -X
feature and the args map data? Are they likely to experience breaking changes between now and the next stable release? I get the feeling not.
Sometimes itās not clear to me what is blessed as stable and isnāt⦠i.e. the installer, the command line args, or the tools.deps api. (Though I guess itās all technically alpha because itās t.d.a not t.d)
should be stable unless we discover some reason to change. not expecting to discover anything but that's why we're letting people try it. I'm expecting the gap to stable to be like days, not a long time.
I was surprised that 1.10.1.590 seems to be the latest stable version on brew already, given the flurry of bug fix releases yesterday (1.10.1.596 and 1.10.1.600).
It shouldnāt be?
https://github.com/clojure/homebrew-tools/blob/master/Formula/clojure.rb has 561
So Iām curious why you said that
I just did brew upgrade clojure
on WSL1 on my Windows laptop last night and it updated me to 590. Hence my surprise.
Note: brew
on Linux.
Thatās homebrew core, which I no longer update
clojure/tools/clojure is official
I know. Hence my surprise š
Well I released 590 a week ago, just took me a while to doc and announce
But I guess somebody updated it
@alexmiller how come you are dumping all the new features into :aliases
? kinda confusing to give aliases multiple meanings IMHO. maybe I'm just not seeing the bigger picture though.
as far as I have understood it: :aliases
was always intended for naming a chunk of EDN data that could be re-used elsewhere, but it's only now that we can see that being used in more places
correct - I would flip it around to say :aliases
is a generic facility, and we are making more use of it
you can, absolutely
that's kind of the idea
correct - I would flip it around to say :aliases
is a generic facility, and we are making more use of it
:thinking_face: so you can change the function that executed with the default data (by changing the classpath via :extra-deps
); but you canāt change the data for a function alias
I'm not sure that's "changing the function" as much as supplying the function
and you can override the data on the command line
maybe I'm not getting what you're describing
is that intended usage?
It feels a bit weird to have the same fully qualified function name, but with two different definitions (in two different :paths
for example).
Would it not be more natural for -X
:args
to compose?
I don't understand why you have that
can you more fully describe what you're talking about, because I don't get it
@rickmoynihan you mean something like that?
{:aliases {:deploy-to {:fn my.ns/deploy}}
:prod {:args {:url ""}}
:qa {:args {:url ""}}}
clj -X:deploy-to:prod
yeah, that's not a thing
I would probably do this:
{:aliases
{:deploy-prod
{:fn my.ns/deploy
:args {:url ""}}
:deploy-qa
{:fn my.ns/deploy
:args {:url ""}}}
but there may be other variants depending on shared config, command-line overrides etc
also my.ns/deploy could interpret data in :args as something to look up in :aliases via the basis
you don't get that for free, but it's like 2 lines of code
these 2 lines https://insideclojure.org/2020/07/28/clj-exec/#runtime-basis
The basis stuff looks very interesting, but you lose access to it if your build your artifacts as uberjars and run them via java -jar
(although I guess you could still do -Dclojure.basis='{...}'
š )
It almost makes me want to go back to running code in production via clojure
instead š
Yeah sorry⦠I think I misinterpreted the motivation behind what @borkdude was saying as a way of effectively doing what @dominicm was asking earlier about composing :args
data.
But I misread :extra-deps
as being :deps
.
Either way it seems :deps
would kind of allow the kind of thing @dominicm was asking for; but in a nasty way⦠i.e. you could swap the function rather than the data. e.g.
- clj -A:myfn -X:args
- clj -A:myfn2 -X:args
Where myfn and myfn2 aliases defined the same ns but with different function definitions.
I want to run fn2 and fn1 in this example. Tbh, I assumed args and fn had to co exist.
I'm unclear if you have a question, and if so, what it is...
Just clarifying that I don't think this would allow for multiple functions like on after :)
Not saying this is a good idea btw!!!
one helper here is that :args can also refer to an alias instead of a map
oh right⦠that is interesting!
seems more useful than the :paths
one
well the :paths one is foreshadowing :)
thatās something new!
I did forget to mention that in my blog writeup, but I think it's in the docs
or maybe it isn't!
I donāt recall seeing it
it was in some version of the docs but looks like it got lost in the N reworks I did
š easily done
anyhow, that's a thing
wow ā I was silently disappointed that something like this wasnāt there
but itās great that it is
is there an example of how it works?
{:aliases
{:f1 {:fn my/fn1
:args :data}
:f2 {:fn my/fn2
:args :data}
:data {:something :here}}}
and then
clj -X:f1
or clj -X:f2
it's just edn
oh sorry, misread your question
I want to run fn2 and fn1 in this example. Tbh, I assumed args and fn had to co exist.
if you read https://insideclojure.org/2020/07/28/clj-exec/ check out the basis injection stuff there
Now we have runtime basis, does that mean you can go back and interpret the exec aliases however you like?
you can write a program that uses alias data
which is broader than what you said
I asked in a thread, but I'll ask in the main channel for everyone to see: given that clojure.basis
is a property added by the clojure
command, what is the thinking behind leveraging this in production code if you normally build uberjars and run those with java -jar
? All of that lovely combined deps.edn
structure has gone by that point...
I also had a similar thought when I stumbled across the basis property etc.
Though I figured you could spit out the basis to a clojure.basis
file inside the uberjar, and slurp it as an io/resource
in your -main
.
However the big disadvantage to this is that the basis would be generated at build time rather than run time, so it would be more like a manifest, than what the basis is really supposed to be.
On reflection I think your idea is better ā though Iām not entirely sure what youād use the basis for in that case, other than as a means of using the clojure
tool to provide config to your app.
I guess the only real advantage is using the clojure
tool and a deps.edn to manage the classpath in production code, rather than the underlying java command line.
I have in the past done things like java -cp:myapp-uberjar.jar:some/server/resources/* myapp.main
to for example add assets to an apps resource path as a production overlay⦠so I guess using the clojure tool itself to help manage these kind of things with aliases might be useful; though Iām not convinced the benefits are huge
though I guess it might sometimes be useful to for example provide profiles in production for enabling socket servers etc :thinking_face:
Also another usecase is you could provide extra tooling for prod systems in this manner.
e.g. a set of aliases for various production tasks, e.g. triggering a -A:backup
alias over cron etc.
and it would mean you donāt need to waste time inventing new command line parsers and config formats etc
It almost feels like it's worth switching to using clojure
to run uberjars via an alias in the deps.edn
so that all that stuff remains available in a "production" style context...
The basis differs depending on the aliases used to run clojure
tho', right?
(because the paths and lib map etc can be different from invocation to invocation -- although the set of aliases etc remains the same)
I'd add it to depstar
but I think at this point I want to wait and see what tools.build
ends up being š

I might experiment with using clojure
to run uberjars tho' later today puts on mad scientist hat...

Having an alias that treats the uberjar as a :local/root
dependency and runs the expected -main
function inside it, so you get easy access to the t.d.a. / Clojure CLI infrastructure
This:
:aliases
{:run {:deps {worldsingles/worldsingles {:local/root "../../build/uberjars/worldsingles-1.0.0.jar"}}
:fn worldsingles.publisher/-main}}
...
And then clojure -X:run
So you get the "benefit" of an AOT'd uberjar with the benefits of the Clojure CLI. And the program can read the basis š
(of course, now you need the Clojure CLI installed on a target server, not just the JVM, and you need a deps.edn
file in the folder where you start the app)
@vlaaad Not if the entire :deps
is just the uberjar, right?
There are no other deps to fetch at that point.
Right, which we used to do on production (and, on one server, for "reasons" we still do that).
Not that I really care, just wanted to report that if you call a private function with -X, it also works:
[email protected] /tmp $ cat src/foo.clj
(ns foo)
(defn- foo [_]
(prn :foo))
[email protected] /tmp $ cat deps.edn
{:aliases {:foo {:fn foo/foo}}}
[email protected] /tmp $ clojure -X:foo
:foo
that's not intentional but interesting :)
it does make sense given the impl
Because requiring-resolve
can get at private Vars and there's no access check on that dynamic call path, right?
right, just like calling through a var
I'm ok with that
I don't consider it a bug
private functions are only in your mind
I'm going to quote you on that when somebody will ask questions about this š
$ bb '(ns foo) (defn- foo [] :foo!) (ns bar (:require foo)) (foo/foo)'
:foo!
Specifically
Caused by: Syntax error compiling . at (aleph/http/core.clj:251:3).
Caused by: java.lang.IllegalArgumentException: No matching method setTransferEncodingChunked found taking 2 args for class io.netty.handler.codec.http.HttpUtil
@p14n change in JDK version perhaps? Last night I was helping some beginners debugging a weird reflection-based problem that changed between JDK 11 and JDK 14 (it was broken on 8 and 11 but worked on 14).
That's what I thought. I switched to openjdk-8-tools-deps (tools-deps now 11) but no dice yet
A change in the default Clojure version perhaps, with stricter syntax checking?
How is the groupId derived in clojure -Spom
? mine keeps getting reset to the artifactId when I run it.
That's a bug. That should not happen.
(and it's a new bug ^ @alexmiller)
ah, interesting. this is with 1.10.1.590.
I don't think anything has changed there
(! 1133)-> head pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="" xmlns:xsi="" xsi:schemaLocation=" ">
<modelVersion>4.0.0</modelVersion>
<groupId>seancorfield</groupId>
<artifactId>next.jdbc</artifactId>
<version>1.1.569</version>
<name>next.jdbc</name>
<description>The next generation of clojure.java.jdbc: a new low-level Clojure wrapper for JDBC-based access to databases.</description>
<url></url>
<licenses>
Wed Jul 29 12:17:19
(sean)-(jobs:0)-(/Developer/workspace/next.jdbc)
(! 1134)-> clojure -Spom
Wed Jul 29 12:17:30
(sean)-(jobs:0)-(/Developer/workspace/next.jdbc)
(! 1135)-> git diff
diff --git a/pom.xml b/pom.xml
index 3dce875..5632254 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="" xmlns:xsi="" xsi:schemaLocation=" ">
<modelVersion>4.0.0</modelVersion>
- <groupId>seancorfield</groupId>
+ <groupId>next.jdbc</groupId>
<artifactId>next.jdbc</artifactId>
<version>1.1.569</version>
<name>next.jdbc</name>
The only change it makes is to overwrite the groupId
can you file a jira, I'm juggling many conversations right now
Will do
@seancorfield The expected behavior was just that it should leave that value alone when the pom.xml already exists?
Hopefully that captures it: https://clojure.atlassian.net/browse/TDEPS-157
The function that turns (merge-cli-ops {:default :opts} "[:extra :opts]" "true") => {:extra {:opts true} :default :opts}
is public?
sorry, I don't understand the question
or how it relates to tools.deps
I think that is this one https://github.com/clojure/brew-install/blob/1.10.1/src/main/resources/clj_exec.clj#L59
Oh, yes thatās it. Treat anything about this code as implementation detail though
@cap10morgan Yup, it should only touch the dependencies in an existing pom.xml
file.
well, it's broader than that - deps, repos, directories
there has been some work done internally here to make this more configurable and that will eventually make its way into user configurability