This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
Hi again. Does anyone have experience using leiningen to make multiple uberjars from one project? I have a lot of shared code in src/common
and then code for a desktop client in src/desktop
and code for a server in src/server
. All I want to do is be able to make separate uberjars for desktop and server. However, even if I make separate profiles for the two (with the corresponding source-paths), all the classes for both desktop and server end up in both. Is there a trick to this?
You need to run lein clean between the builds or specify a different target directory in the profiles
:target-path "target/%s/"
helps as well.
%s gets replaced with the build name, so that each build is isolated (instead of having competing builds mutate the same folder)
thank you; unfortunately neither of those suggestions prevented code being pulled in from an unwanted dir (e.g. src/desktop
classes go to the server)
I'm pretty sure there aren't any dependencies between the namespaces to account for their inclusion
This is pretty interesting:
src/foo.clj
:
(ns foo)
(println (the-ns 'foo))
(def x (/ 1 0))
$ clj
Clojure 1.10.1
user=> (require '[foo])
#object[clojure.lang.Namespace 0x22bb5646 foo]
Execution error (ArithmeticException) at jdk.internal.reflect.NativeMethodAccessorImpl/invoke0 (NativeMethodAccessorImpl.java:-2).
Divide by zero
user=> (the-ns 'foo)
Execution error at user/eval150 (REPL:1).
No namespace: foo found
It seems like the namespace foo
is created, but on exception it's removed again?What are folks opinions on the best AWS API wrappers with a focus on S3?
Thanks Tim. Looks interesting. Seems that and Amazonica are the two main ones out there.
Personally I think using the Java API is going wrong by introducing a giant wad of unnecessary OO between your beautiful Clojure data and a nice simple wire protocol :)
Honestly, I’d be more concerned about introducing a giant wad of macros over a giant wad of objects 😉
Well Amazonica has the glory of both macros over OO :)
I’ve used the aws-api a lot in the last week and really enjoy it (and not just b/c it’s a Cognitect thing)
I used it a number of months ago and stumbled across a number of shortcomings. I’m sure it’s improved in the meantime.
I haven’t been clojuring for a bit and hadn’t even heard of it. Thanks for the pointer I’ll give it a go.
@danielglauser David Chelimsky gave a really good rational talk about a year ago: https://www.youtube.com/watch?v=ppDtDP0Rntw
Huge props to David C for being a great maintainer too - good mix of regular small updates and periodic important adds
I'd like to ask you "more seasoned" clojurians one question: do you actually use these application state management libraries like Component, Mount or Integrant? I was experimenting with one of these libraries and somehow I felt that the library caused more hassle with my repl workflow than helped me with my repl workflow.
I've found https://github.com/riverford/objection to be somewhat underrated and it tends to be the first thing i reach for
@U76D9RZRR We've used Component very heavily in production for years. We find it great in the REPL too. What sort of problems are you having?
Is it because you're trying to use the "Reloaded" workflow and it's causing you problems? We do not use that workflow -- we don't need it.
Eric Normand talks about this in his REPL-Driven Development course -- and Stu Halloway talks about it on podcasts and in his conference talks. If you have good practices around the REPL, you do not need "reload" / "refresh" workflows.
The "opinionated" installation guide for ProtoREPL for Atom advocated turning on the full refresh workflow but it causes lots of problems for beginners. Chlorine also supports it but I advise people not to use it for the same reason.
Component solves a problem that you don't have in simple programs -- but you do have in spades in a large, complex program.
one should always consider whether there is a more appropriate code structure with fewer dependencies
I agree with Eric and Stu that it is unnecessary -- and it certainly seems to cause endless problems for beginners (since they don't understand what's really going on, under the hood), so I encourage folks to avoid it until they really think they need it (which they don't).
If it works -- which it doesn't for a lot of people.
Yeah, for some folks It. Just. Works. I've had it work perfectly in some projects and not at all in others.
(I’ve hit loads of unexpected behavior/errors before running reload. Usually to do w/ interop.)
it's bit of an unfortunate tradeoff - both Reloaded and manual management have some gotchas I think Reloaded could be improved, in the end it's a fancy name for 'automation'. The current status of that automation is relying in a slightly unmaintained library that doesn't document all its intricacies Raw clojure isn't perfect either - keeping track of namespaces in your head or intricacies related to the compiler isn't perfect either One always can experiment with both approaches, document observations and draw conclusions
If we had searchable archives here, you could just search for the problems many people have experienced with it... 🙂
Its pretty great, for when you want to make sure your code compiles without restarting the repl
I do think there are certain things it can't clean though, like thread locals and all
But just gettijf rid of bindings and letting me know I've got all the right require in place and declared functions is great
I use the "reload" workflow in most of my projects, and indeed, sometimes it works, sometimes it doesn't. With Clara-Rules, for example, I wasn't able to cut an approach that works without reload
But for multiple other projects, manual load-file / other tools work fine too (if there isn't too many protocols/records)
Nowadays, I use a mix of approaches. The thing is, I work mostly with very small microservices now, so the dep graph is very simple to understand (and maybe that's the reason the "reload workflow" works so well for me 😄)
I still think I'm confused about what is the "reloaded" workflow. Initially, from Stuart's talk it was about being able to perform starting and stopping logic in the correct order to initialize and shut down resources
But there is also the issue that load doesn't unload. And sometimes, you just want a clean REPL without having to restart it (because its so slow to restart). Tools.namespace is targeting that issue.
Sorry for late answer, @U04V70XH6 . I used Mount but occasionally one namespace didn't compile anymore (No matching field found: stop for class mount.core.DerefableState) and the only way to fix the issue was to restart REPL - which I'm learning to avoid. I have a personal learning project in which I'm mostly trying to learn a personal efficient REPL workflow. I think next I'm trying to do the same project without any application state management library and see how REPL driven development feels like that way.
Clojure is really a great language and I think REPL is the soul of Clojure - I really want to learn to use REPL smoothly when developing Clojure code.
Actually I have fallen in love with Clojure so much that I gave up my good corporate career and moved to a smaller company just for the chance to do Clojure full-time. 🙂 Well, I have paid my mortgage and my kids are grown-up now so I thought that I can do for the rest of my career what ever I want - and I want to do Clojure. 🙂
BTW. If you guys know links to good REPL driven development sites / pages, please provide links here.
I have watched Purely Functional TV's Repl Driven Development course and I must say it is really great (thanks Eric!).
Also "Chicago Clojure - 2017-06-21 - Stuart Halloway on Repl Driven Development" (https://vimeo.com/223309989) is really wonderful. After watching this video I realized that I have done REPL driven development totally wrong - editing stuff in a REPL editor. After watching that video I immediately started using a scratch file (for REPL experimentation) that I save for future review.
If I remember correctly Stuart somewhere said that he mostly compiles namespaces one after another following the dependency graph manually to better understand what kind of dependencies there are. I have tried to do that also myself more now (and try to avoid fixing issues just by "restarting repl").
... @U04V70XH6 already said it in this thread, I somehow missed it when reading this thread the first time: "Eric Normand talks about this in his REPL-Driven Development course -- and Stu Halloway talks about it on podcasts and in his conference talks. If you have good practices around the REPL, you do not need "reload" / "refresh" workflows." => Maybe that's what I'm trying to achieve: "good REPL practices". 🙂
I prefer not to use it if I can get away with it. I'm keeping an eye open for https://github.com/juxt/clip which should be more repl/cider friendly.
in the past I have used mount but these days, most of my apps are quite small so I avoid it
I cannot provide any background, but was watching Sean Corfield's videos on how he uses Atom + Chlorine + REBL + tools.deps + Clojure CLI, and it showed that their fairly large Clojure code base at the company he works at, World Singles, uses Component: https://www.youtube.com/channel/UC8GD-smsEvNyRd3EZ8oeSrA
Note: Those videos do not go into any detail on the use of Component -- it is simply apparent that they do use it in their code base from seeing it mentioned in the video.
I believe I have heard him mention that he does not use the "reloaded" workflow that some other Clojure devs use, instead choosing to force himself to remember to explicitly resend (via a single keystroke configured in his editor) any modified functions to the REPL, to redefine them.
Here's an example he made awhile back: https://github.com/seancorfield/usermanager-example
@alexmiller mentions 30 tools built for CLJ in his tools.deps clojure conj talk. Are those listed somewhere?
Darn, these are cool!
fwiw, mark bastian's talk at the recent conj covers integrant a bit -- am slowly trying to digest that along with the many pieces used (he's got a repository that has the code for the talk plus extra)
My problem with mount is that it doesn't make a statement about passing around your state, so it's easy for it to leak where it shouldn't.
re aws and any of it's apis, imo aws people, with their official java sdk, slayed an ant with an hammer and then drove a tank over it
last time i checked the language of clojure was smaller than the aws sdk for s3 access + the deps that the latter needed
and their next gen sdk is even worse in that light