depstar

Discussion around https://github.com/seancorfield/depstar
seancorfield 2020-12-08T04:09:12.186300Z

Just a heads up, I plan to change depstar's behavior for an upcoming 2.0 release. Right now, depstar uses the runtime basis and simply excludes itself from the classpath when building JAR files. This is nice and easy but it means that depstar can't depend on anything so it's had to re-implement CLI argument processing and can't use an XML library to process the pom.xml file etc. On the assumption that the vast majority of JARs built from the core classpath in a given project, without anything from the user deps.edn file (other than the depstar alias), I plan to switch depstar over to using a calculated project basis instead.

seancorfield 2020-12-08T04:12:11.188900Z

The main difference will be switching the depstar alias from :extra-deps to :replace-deps, so that depstar behaves as a "tool" instead of a library. It will depend on tools.deps.alpha directly (and tools.cli and maybe other things), it will read the system and project deps.edn files and compute the project basis. I may add options to allow it to include the user deps.edn and to provide aliases to affect the deps used for building a classpath that in turn will be used to build the JAR.

👍 1
Rowan Barnard 2020-12-08T05:44:18.192900Z

Hi Sean, I've just been through some chapters taking me through configuring and building a project with Leiningen, and managed to translate everything to deps.edn, except I'm stuck on the last bit, building an uberjar, or rather running it with java (I've already built the uberjar)

seancorfield 2020-12-08T05:45:46.194200Z

@flyingpython you followed this section https://github.com/seancorfield/depstar/blob/develop/README.md#aot-compilation ?

Rowan Barnard 2020-12-08T05:46:24.195100Z

Hang on - I'm just about to explain which bit I'm stuck on 😅

seancorfield 2020-12-08T05:46:39.195400Z

Heh, type faster man! 🙂

Rowan Barnard 2020-12-08T05:47:06.195600Z

;; uberjar building: ;; - see https://github.com/seancorfield/depstar for a minimalist approach: ;; - clj -A:uberjar result.jar ;; - to run it: ;; - java -cp result.jar clojure.main -m mymain.namespace ;; - build a library JAR: ;; - clj -A:jar result-lib.jar :uberjar {:extra-deps {seancorfield/depstar {:mvn/version "RELEASE"}} :main-opts ["-m" "hf.depstar.uberjar"]}

Rowan Barnard 2020-12-08T05:47:22.196100Z

This is the old version of your uberjar alias I'm using

Rowan Barnard 2020-12-08T05:47:31.196300Z

And the bit I'm stuck on is

Rowan Barnard 2020-12-08T05:47:52.196800Z

mymain.namespace I believe

Rowan Barnard 2020-12-08T05:48:08.197200Z

It is throwing a FileNotFoundException

Rowan Barnard 2020-12-08T05:48:36.197400Z

I typed in java -cp async_tea_party.jar clojure.main core.async-tea-party

seancorfield 2020-12-08T05:48:46.197800Z

You're missing -m

seancorfield 2020-12-08T05:49:09.198200Z

java -cp result.jar clojure.main -m mymain.namespace

Rowan Barnard 2020-12-08T05:49:23.198500Z

Ah OK crikey I missed that 😂

Rowan Barnard 2020-12-08T05:49:52.199600Z

I still might be confused about what to put for mymain.namespace though

seancorfield 2020-12-08T05:50:12.200300Z

The namespace that contains your -main function.

Rowan Barnard 2020-12-08T05:50:21.200600Z

Is mymain the main function or the class and do I use hyphens or underscores?

seancorfield 2020-12-08T05:50:48.201200Z

mymain.namespace is a namespace.

seancorfield 2020-12-08T05:51:22.202300Z

If core.async-tea-party is the namespace of your app that has a -main function, that's your "main namespace".

Rowan Barnard 2020-12-08T05:51:30.202600Z

OK so my file is core.clj in src/async_tea_party/

Rowan Barnard 2020-12-08T05:51:41.202900Z

The main function is -main

seancorfield 2020-12-08T05:52:02.203500Z

Then the namespace is async-tea-party.core

Rowan Barnard 2020-12-08T05:52:02.203600Z

async-tea-party.core is the namespace in core.clj

seancorfield 2020-12-08T05:52:33.204500Z

java -cp async_tea_party.jar clojure.main core.async-tea-party <- your namespace doesn't match (in addition missing -m).

Rowan Barnard 2020-12-08T05:52:37.204700Z

OK thanks so the whole mymain.namespace is async-tea-party.core?

Rowan Barnard 2020-12-08T05:53:13.205100Z

OK I'll try that then

Rowan Barnard 2020-12-08T05:56:10.205500Z

Sweet, thank you very much Sean, it's working!

arnaud_bos 2020-12-08T17:28:31.214700Z

Hello, first time depstar user/AOT compiler here. 👋 I'm trying to build a library jar for the TLC model checker, I've tried:

λ clojure -X:jar                   
Ignoring -C / --compile because -m / --main was not specified!
Building thin jar: aoc.jar
src
src/aoc/day2/impl.clj
src/aoc/day2.clj
classes
I'm having an issue where only the .clj files end-up in my jar file. I was expecting class files, right? Note that I don't have a "main" namespace. Is it required? I've tried from the clojure guide just to check the output:
λ clj -A:local -M -e "(compile 'aoc.day2)"
aoc.day2
Which seem to successfully complete and generate a bunch of .class files in my classes/ directory (under aoc/ and clojure.core.spec). Did I forget something? I've pushed my working copy here : https://github.com/arnaudbos/aoc2020-tla-plus/commit/70d08fa4d48c780c22db706b9a7d5693a7dff507

seancorfield 2020-12-08T17:37:54.216200Z

@arnaud_bos depstar will only AOT code if you tell it which namespace to compile -- there's no "aot all" option. I would say that you really should not AOT compile a library, only an uberjar

arnaud_bos 2020-12-08T17:42:37.219800Z

Please correct me if I'm wrong but wouldn't an uberjar also include the classes of the tla2tools.jar which I'm depending on? Because the classes in this jar will already be provided in the context of a TLC execution (the jar is already in the classpath). Is that not an issue?

seancorfield 2020-12-08T17:43:13.220500Z

An uberjar is a complete standalone program that you can run directly via the java command so it should include all dependencies.

arnaud_bos 2020-12-08T17:44:10.221200Z

Yes, it's not what I want. TLC is the executable, my library would just provide a few "extensions" via annotated methods.

seancorfield 2020-12-08T17:47:18.222100Z

Here's a project that explicitly compiles a namespace when building the (thin) JAR: https://github.com/seancorfield/cfml-interop/blob/develop/deps.edn

seancorfield 2020-12-08T17:48:25.222700Z

See the :build alias that runs the compile with -e and then runs depstar.

seancorfield 2020-12-08T17:49:31.223400Z

It has "classes" already created and has both "classes" and "src" in :paths.

seancorfield 2020-12-08T17:50:19.223700Z

Does that help @arnaud_bos?

seancorfield 2020-12-08T17:51:25.225800Z

I try to discourage this so folks don't just AOT libraries because it's "easy" without understanding the consequences, so in depstar itself AOT is tied to -m and pom.xml and uberjar building. But you can manually compile a namespace and have it included in the JAR.

arnaud_bos 2020-12-08T17:51:50.226Z

Yes! The :build alias hides the two steps I understand.

arnaud_bos 2020-12-08T17:52:41.227200Z

Sure, I get that. My use case seems a little bit different.

arnaud_bos 2020-12-08T17:52:54.227600Z

Thank you so much 🙏

seancorfield 2020-12-08T17:58:09.228900Z

Yeah, that library above has a specific :gen-class because it's building a (Java) class that the non-compiled code needs in order to run -- so the (thin) JAR contains the source files and, for just that one namespace, the .class files as well.

seancorfield 2020-12-08T17:59:06.230Z

When I build depstar v2, I will probably decouple most of the options so that it will do whatever you tell it to do and just warn you if you're "painting outside the lines".

seancorfield 2020-12-08T18:05:14.231Z

(and I'll probably make it possible to compile an arbitrary set of namespaces and I may even add an :all option since v2 won't be restricted on the dependencies it can use, unlike v1)

arnaud_bos 2020-12-08T18:11:28.231400Z

Nice, good to know!