Builds JARs, uberjars, does AOT, manifest generation, etc for deps.edn projects (forked from healthfinch/depstar and enhanced).
For support, help, general questions, use the #depstar channel on the Clojurians Slack.
Note: these instructions assume you have at least version 1.10.1.697 of the Clojure CLI installed -- otherwise you'll need to use
-A
instead of-M
.
Install this tool to an alias in $PROJECT/deps.edn
or $HOME/.clojure/deps.edn
:
{
:aliases {:depstar
{:extra-deps
{seancorfield/depstar {:mvn/version "1.1.132"}}}}
}
Create a (library) jar by invoking depstar
with the desired jar name:
clojure -M:depstar -m hf.depstar.jar MyLib.jar
If you want to deploy a library to Clojars (or Maven Central), you're going to also need a pom.xml
file -- see below.
Create an uberjar by invoking depstar
with the desired jar name:
clojure -M:depstar -m hf.depstar.uberjar MyProject.jar
An uberjar created by that command can be run as follows:
java -cp MyProject.jar clojure.main -m project.core
If you want to be able to use java -jar
to run your uberjar, you'll need to specify the main class (namespace) in the uberjar and you'll probably want to AOT compile your main namespace. See the sections below for more information about both of those.
If you want to see all of the files that are being copied into the JAR file, add -v
or --verbose
before or after the JAR filename.
By default, depstar
uses the classpath computed by clojure
.
For example, you can add web assets into an uberjar by including an alias in your deps.edn
:
{:paths ["src"]
:aliases {:webassets {:extra-paths ["public-html"]}}}
Then invoke depstar
with the chosen aliases:
clojure -M:depstar:webassets -m hf.depstar.uberjar MyProject.jar
You can also pass an explicit classpath into depstar
and it will use that instead of the (current) runtime classpath for building the JAR:
clojure -M:depstar -m hf.depstar.uberjar --classpath "$(clojure -Spath -A:webassets)" MyProject.jar
--classpath
can be abbreviated to -P
.
pom.xml
If there is a pom.xml
file in the current directory, depstar
will attempt to read it and figure out the group ID, artifact ID, and version of the project. It will use that information to generate pom.properties
and MANIFEST.MF
in the JAR file, as well as copying that pom.xml
file into the JAR file. If you are building an uberjar, the manifest will declare the Main-Class
(specified by the -m
/ --main
option below, clojure.main
if omitted).
You can suppress the consumption of the pom.xml
file with the -n
/ --no-pom
option.
Note that depstar
does no AOT compilation by default -- use the -C
/ --compile
option to enable AOT compilation (see below).
If you build an uberjar, you can run the resulting file as follows:
clojure -M:depstar -m hf.depstar.uberjar MyProject.jar
java -cp MyProject.jar clojure.main -m project.core
If you build an uberjar with a pom.xml
file present and do not specify -n
/ --no-pom
, so that a manifest is included, you can run the resulting file as follows:
# generate pom.xml (or create it manually)
clojure -Spom
# build the uberjar without AOT compilation
clojure -M:depstar -m hf.depstar.uberjar MyProject.jar
# Main-Class: clojure.main
java -jar MyProject.jar -m project.core
Finally, if you have a pom.xml
file and also include a (compiled) class in your JAR file that contains a main
function, you can use the -m
/ --main
option to specify the name of that class as the Main-Class
in the manifest instead of the default (clojure.main
).
As of 0.4.0, you can ask depstar
to compile your main namespace via the -C
/ --compile
option:
# generate pom.xml (or create it manually)
clojure -Spom
# build the uberjar with AOT compilation
clojure -M:depstar -m hf.depstar.uberjar MyProject.jar -C -m project.core
# Main-Class: project.core
java -jar MyProject.jar
This will compile the project.core
namespace, which must have a (:gen-class)
clause in its ns
form, into a temporary folder, add that temporary folder to the classpath (even when you specify an explicit classpath with -P
/ --classpath
-- see above), build the uberjar based on the pom.xml
file, including everything on the classpath, with a manifest specifying project.core
as the main class.
Remember that AOT compilation is transitive so, in addition to your project.core
namespace with its (:gen-class)
, this will also compile everything that project.core
requires and include those .class
files (as well as the sources).
Note: for the 0.4.x releases of
depstar
, you needed to create aclasses
folder manually and add it to the classpath yourself; as of 0.5.0, this is handled automatically bydepstar
.
The -X
/ --exclude
option can be used to provide one or more regex patterns that will be used to exclude unwanted files from the JAR. Note that the string provided will be treated as a regex (via re-pattern
) that should be a complete match for the full relative path and filename. For example, if you wanted to exclude clojure.core.specs.alpha
code from your JAR, you would specify --exclude "clojure/core/specs/alpha.*"
-- note .*
at the end so it matches the entire filename.
clojure -X
UsageThe Clojure CLI added an -X
option (in 1.10.1.697) to execute a specific function and pass a hash map of arguments. See Executing a function that takes a map in the Deps and CLI reference for details.
As of 1.1.117, depstar
supports this via hf.depstar/jar
and hf.depstar/uberjar
which both accept a hash map that mirrors the available command-line arguments:
:aot
-- if true
, perform AOT compilation (like the -C
/ --compile
option):classpath
-- if specified, use this classpath instead of the (current) runtime classpath to build the JAR (like the -P
/ --classpath
option):debug-clash
-- if true
, print warnings about clashing jar items (and what depstar
did about them):exclude
-- if specified, should be a vector of strings to use as regex patterns for excluding files from the JAR:jar
-- the name of the destination JAR file (may need to be a quoted string if the path/name is not valid as a Clojure symbol; also like the -J
/ --jar
option):jar-type
-- can be :thin
or :uber
-- defaults to :thin
for hf.depstar.jar/run
and to :uber
for hf.depstar.uberjar/run
(and can therefore be omitted in most cases):main-class
-- the name of the main class for an uberjar (can be specified as a Clojure symbol or a quoted string; like the -m
/ --main
option; used as the main namespace to compile if :aot
is true
):no-pom
-- if true
, ignore the pom.xml
file (like the -n
/ --no-pom
option):verbose
-- if true
, be verbose about what goes into the JAR file (like the -v
/ --verbose
option)The following commands would be equivalent:
clojure -M:depstar -m hf.depstar.uberjar MyProject.jar -C -m project.core
clojure -X:depstar hf.depstar.uberjar/run :jar MyProject.jar :aot true :main-class project.core
You can make this shorter by adding :exec-fn
to your alias with some of the arguments defaulted since, for a given project, they will likely be fixed values:
;; a new :uberjar alias to build a project-specific JAR file:
:uberjar {:extra-deps {seancorfield/depstar {:mvn/version "1.1.132"}}
:exec-fn hf.depstar.uberjar/run
:exec-args {:jar "MyProject.jar"
:aot true
:main-class project.core}}
Now you can just run:
clojure -X:uberjar
You can choose to override those on the command-line if you wish:
clojure -X:uberjar :jar '"/tmp/MyTempProject.jar"'
For convenience, you can specify the JAR file as a Clojure symbol (e.g., MyProject.jar
above) if it could legally be one and depstar
will convert it to a string for you. Per the CLI docs, you would normally specify string arguments as "..."
values, that need to be wrapped in '...'
because of shell syntax (so the quoted string is passed correctly into clojure
).
Note: currently, uberjars built via
-X
will includeorg.clojure/tools.deps.alpha
even if it is not a dependency of your project. If that matters, use the-M
approach above. This will be addressed indepstar
2.0.
depstar
BehaviorIf you are seeing unexpected results with depstar
and the -v
/ --verbose
option doesn't provide enough information, you can enable "debug mode" with either DEPSTAR_DEBUG=true
as an environment variable or depstar.debug=true
as a JVM property. Be warned: this is very verbose!
After you've generated your JAR file as above with a pom.xml
file, you can use the mvn
command below to deploy to Clojars (or other Maven-like repositories) -- or you could use deps-deploy
-- see below.
mvn deploy:deploy-file -Dfile=MyProject.jar -DpomFile=pom.xml -DrepositoryId=clojars -Durl=https://clojars.org/repo/
This assumes that you have credentials for your chosen repository in your ~/.m2/settings.xml
file. It should look like this (with your username and password):
<settings>
<servers>
<server>
<id>clojars</id>
<username>someperson</username>
<password>topsecret</password>
</server>
</servers>
</settings>
If you only want to install the artifact locally (for use in local development, similar to lein install
), you can use the following mvn
command:
mvn install:install-file -Dfile=MyProject.jar -DpomFile=pom.xml
After that you can require the dependency coordinates as usual, using the group ID, artifact ID, and version that you had setup in the pom.xml
file.
deps-deploy
As noted above, you could also use deps-deploy
to deploy your JAR file to Clojars.
Add the following alias to your deps.edn
file:
;; version 0.1.1 was the most recent as of 2020-10-09:
:deploy {:extra-deps {slipset/deps-deploy {:mvn/version "RELEASE"}}
:main-opts ["-m" "deps-deploy.deps-deploy" "deploy" "MyProject.jar"]}}}
This expects your Clojars username to be in the CLOJARS_USERNAME
environment variable and your Clojars token to be in the CLOJARS_PASSWORD
environment variable.
This project follows the version scheme MAJOR.MINOR.COMMITS where MAJOR and MINOR provide some relative indication of the size of the change, but do not follow semantic versioning. In general, all changes endeavor to be non-breaking (by moving to new names rather than by breaking existing names). COMMITS is an ever-increasing counter of commits since the beginning of this repository.
Latest stable release: 1.1.132
The use and distribution terms for this software are covered by the Eclipse Public License 2.0
Can you improve this documentation? These fine people already did:
Sean Corfield, Ghadi Shayban, Quest Yarbrough, Gert Goet & ⅅ₳ℕⅈⅇℒℒⅇ ҜⅇℱℱʘℝⅅEdit on GitHub
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close