I want to distribute a Clojure program. Do I need a JDK or can a JRE handle everything in Clojure?
You only need the user to have a JRE (v1.5 or above)
Clojure programs can be compiled into a jar file. You don't have to use something like
leiningen, but it's a lot easier.
Check out this page on the Clojure.org site for how to compile and run a program.
You can compile to a jar file from the REPL:
(compile 'clojure.examples.hello)
Here's how you would run a compile jar:
java -cp ./classes:clojure.jar clojure.examples.instance asdf
You just need a JRE.
https://github.com/technomancy/leiningen/blob/master/TUTORIAL.md explains in more detail, but I believe you just want an "Uberjar" which will contain all the dependencies that you need to distribute your application.
JRE is required! You can easily download it from Internet.
Related
I am using Emacs and every time I start a Clojure REPL with cider-jack-in
, the minibuffer echoes the following:
Are you sure you want to run `cider-jack-in' without a Clojure project? (y or n)
I have a prior experience with Common Lisp and Slime. In this other lisp ecosystem, there is not such a thing. You just start Common Lisp without questions asked.
I do not get the purpose of this message from Cider. Probably, because I am missing something.
It is important to highlight that I do know how to create a Clojure project using lein command. I just do not get its relevance.
What am I missing for not using a Clojure project before starting the REPL?
Why is it so relevant?
What is the downside of developing a Clojure program with the .clj file, the REPL, doing some interactive programming, and re-compiling things as the program evolves with editions?
Just preventing problems with namespace?
Thanks
The main reason for using a "project", whether it is via a deps.edn file (for Clojure CLI tooling) or a project.clj file (for lein), is to provide the dependencies and hence the CLASSPATH. Since Clojure runs on the JVM, the CLASSPATH has to be set before the Java process is started. As an aside, this is not strictly true, but I'll ignore that complexity for now. The CLASSPATH is used by the JVM to find and then load classes during runtime.
If you're not using any dependencies then you can probably get away with not using a project.
I use emacs with cider and the Clojure CLI tooling myself. You might also want to look into the inf-clojure emacs package.
I am also coming from Common Lisp to Clojure and was confused a lot at the beginning.
And we use lein new because BraveClojure etc. shows this as the only way. Despite of its truths, it is too old. The Clojure community should write more up-to-date tutorials and books.
There is e.g. boot - the other build tooling tool than lein:
https://github.com/boot-clj/boot
Short intro:
https://jjmojojjmojo.github.io/boot-getting-started-with-clojure-in-10-minutes.html
Which allows you to start a repl with $ boot repl a repl with boot.user as the namespace
similar to CLUSER.
It is as powerful as lein.
And for command line scripting, there is babashka https://github.com/babashka/babashka
which is interpreted Clojure for scripting - callable even from the command line.
I've found two ways of compiling Clojure *.clj files into *.class files, and while they both work, I have some gripes with both of them.
The first one uses a REPL and so cannot be automated (or can it?)
The second one uses lein. To be frank I don't see why I should use a dependency management tool for something that should be part of the core tool-chain of the language. But in any case, using lein soon forces you to use a local Maven repository if your Clojure code needs to access local jars (which is highly likely).
Is there a better way to generate *.class or *.jar files from Clojure code that involves only core Clojure tools and that can be employed in a scripted, non-interactive way?
Clojure provides clojure.core.Compile, which can be used to compile Clojure code from the command-line.
java -Dclojure.compile.path=<targetdir> -cp <targetdir>;clojure.jar <list of namespaces>
For an example of how to use this from ant, look at the compile-clojure task in Clojure's own build.xml file.
clojure.core/compile can be automated via Clojure
Context
I want to use JavaFx with clojure.
I am aware of http://nailthatbug.net/2011/06/clojure-javafx-2-0-simple-app/
Question:
Is there a way to make JavaFX work with Clojure using native-deps in lein instead?
Thanks!
I've created a simple Clojure and JavaFX example on Github. Testing on Ubuntu I had to install the JavaFX runtime into my local Maven repository, using the deploy:deploy-file target (install:install-file did not work for me).
mvn deploy:deploy-file -DgroupId=local.oracle -DartifactId=javafxrt -Dversion=2.2.0 -Dpackaging=jar -Dfile=/usr/lib/jvm/java-7-oracle-amd64/jre/lib/jfxrt.jar -Durl=file:/home/raju/.m2/repository
Make sure you have the following arguments set correctly:
-Dfile={full path to jfxrt.jar in jre/lib folder}
-Durl=file:{full path to Maven repository, e.g. $HOME/m2.repository}
In the project.clj, I added the dependency based on the -DgroupId and -DartifactId values when installing the JAR into the repository. If you use change these values, make sure to change the dependency accordingly:
[local.oracle/javafxrt "2.2.0"]
Java was able to load the binary libraries without any problems. If Java reports problems loading a binary library, e.g.
Caused by: java.lang.UnsatisfiedLinkError: Can't load library:
/usr/lib/jvm/javafx-sdk/rt/lib/amd64/libglass.so
check out these two question on SO:
What is LD_LIBRARY_PATH and how to use it?
java.lang.UnsatisfiedLinkError no *****.dll in java.library.path
Because JavaFx has native dependencies your option are limited to, ]
shipping these dependencies with your project (including them),
creating a package that you can depend on which has them (providing them),
or having your package require the user to install them in some other way.
Because the tutorial you link to covers the case where the user of your package/program installs JavaFx on their own, by using robert.hook and depending on the end-user's package manager to provide the actual native dependencies. I'll cover how to have your package/program include the dependencies.
native-deps can be used to ship native dependencies with your package. You just need to add all the .so, .dll, .etc files in the appropriate directories. I think the projects github page does a better job than I of explaining the structure.
The link in the question is broken so I can't see your example, but with Java 8, JavaFX is now part of the standard JDK/JRE. I therefore expect the native dependency issue to be irrelevant at this point.
Not sure if this will work for others, but this appears (so far) to have worked for me:
mvn install:install-file -DgroupId=javafx -DartifactId=javafx -Dversion=2.1.0 -Dpackaging=jar -Dfile=/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents/Home/jre/lib/jfxrt.jar
I have no idea why this works, but I believe jfxrt.jar has the files I need. Then, after this, I kindle it in project.clj as
[javafx "2.1.0"]
in the :dependencies (not :native-deps) section.
[Having written this, I really have no idea why this even appears to work.]
I'm new to Clojure but I'm learning it. I'd like to know the best way to package and distribute a Clojure program to end users who aren't necessarily programmers. I know in Ruby you can just tell users to download the program with gem install [program name] and then run the command that runs the program. What's the equivalent for Clojure programs?
I you use Leiningen it has an uberjar command to make self contained executable jar files, which your users can just double click. See: http://zef.me/2470/building-clojure-projects-with-leiningen
Clojars is great if you're distributing a library, but I'm not sure if that's the best option for end users.
If you're already using Maven, I believe the best option is to create a uberjar containing all required classes. If you want to make it even more end user friendly, you can then create an installer from this jar using something like IzPack. Just remember that Clojure programs are Java programs, so all distribution options for Java are valid for Clojure as well.
lein uberjar works great for small mostly-Clojure apps, but it doesn't scale when using many Java libraries, including necessary licenses, and other such things. If you use the Maven Clojure plugin, you could take advantage of the vast and terrifying Maven assembly plugin to build and final structure you might conceivably need.
Or you could write a Leiningen plugin to do something similar. I'm not sure if such a thing exists.
Clojars (http://clojars.org/) is the bigger repository of Clojure libraries you can find.
It works perfectly with Leiningen projects or any other Maven based project management tool.
say i create a program in clojure and i have to deliver it to a client. the client does have some computer knowledge but he does not know/want to start the repl, load my program, and run it. he wants to double click an exe file or run a shell script
how do i package my program and deliver (the program itself with the clojure jars) ?
You have a few choices:
Compile the program into Java classes, and give one a main method. Package them into an executable jar.
Per above, if you use Leiningen then you can assemble everything nicely with lein uberjar, making sure that you have declared a main class.
You can alternately package your project into a non-executable jar (no main class) and create a shell script/batch file to execute the proper class e.g. java -cp ./clojure.jar:./myprogram.jar com.my.runthis.class
Just package your .clj files into a jar, and use a shell/batch script to start a repl and then automatically issue commands e.g. java -cp ./clojure.jar:./myprogram.jar clojure.main -e "(in-ns 'your-ns)(start-your-program)" -r
Simplest approach would be to let leiningen handle the jar for you it will package everything into a single fat jar thats all you need to deliver just like any other java app. All client has to do is double click on it. If you need an .exe file launch4j can create it for you, it can also handle JRE installation is it is not already installed on the clients machine. You don't need any bash scripts etc.
You can use leiningen to create uberjar, as Greg Harman wrote...
I personally use maven to create standalone jar with all dependencies, declare main class - this simplify run of it with 'java -jar your-jar-file' command. I also use Izpack to create installers for my programs
The best approach I have found for doing this is cake bin if you are using cake. It will generate a packaged binary for you (probably same as or similar to launch4j).