I am working in emacs, swank-clojure. I start my repl using clojure-jack-in. However when I add a new dependency to my project.clj, the dependency is not available in the repl.
1) Is there a way to load new dependencies automatically in swank, when project.clj changes ?
2) Also what is a clean way to terminate the swank server ? Currently I just kill the buffer.
Thanks,
Murtaza
When Java VM starts it reads all the included jars there is straight-forward way to include jars later. If you really don't want to restart application you could try something like this. But it may get very tricky as if you don't use same class loader as Clojure does then when loading another Clojure library you may end up with 2 instances of Clojure core.
To disconnect from swank server use M-x slime-disconnect. To stop publishing on the server you can issue:
(swank.swank/stop-server)
Related
I have multiple, separate leiningen projects that ostensibly could depend on one-another.
Example:
~/projects/mywebapp (my own project)
~/projects/noir (a clone of the github repo)
~/projects/clojureql (a clone of the github repo)
I want to have them all compiled into the same JVM at the same time. I would like to run the git repos bleeding edge (pulling new commits/making my own commits) and not have to run lein jar or lein deps and certainly not have to restart the VM if I change any of the projects.
Here's a use case:
After running lein swank, from within emacs, I connect to the repl and compile a file from mywebapp (with C-c-k), which requires a file from noir. It finds the version of the file in my projects directory. Later, I open that file, edit it, and compile it (with C-c-k).
Note that I'm not asking for auto-compiling when I do git pull. I just don't want to have to restart the JVM or do lengthy jar compiling processes.
Is this possible in leiningen? How can I set this up?
Does this question from the Lein FAQ help?
Q: I want to hack two projects in parallel, but it's annoying to switch between them.
A: Use a feature called checkout dependencies. If you create a directory called checkouts in your project root and symlink some other
project roots into it, Leiningen will allow you to hack on them in
parallel. That means changes in the dependency will be visible in the
main project without having to go through the whole
install/switch-projects/deps/restart-repl cycle. Note that this is not
a replacement for listing the project in :dependencies; it simply
supplements that for tighter change cycles.
If you're already using swank, you don't need lein checkout dependencies. You can just C-c C-k your project (which will load the jarred versions of noir/whatever), and then browse to your local version of noir and C-c C-k that as well. Swank happily sends all the code to your repl, and the jvm never need know that it came from a different place!
I can only recommend this for smallish changes though, because I think if you compile noir.core, which depends on (say) noir.internal, clojure will load the jarred version of noir.internal even while you compile the local version of noir.core. Even so, it's a handy trick in general.
I'm using lein repl to execute clojure repl in console.
When I run it, it takes over 15 seconds.
When I run java -cp clojure-1.6.0.jar clojure.main, it takes just a few seconds.
Why is lein repl so slow? Are there anyways to make it faster?
My env:
H/W: MacBookAir
O/S: Mac OS 10.9 Mavericks
CPU: i7
MEM: 8GB
Leiningen starts two JVMs, and hooks them together. It's got to load extra stuff to do that. The prompt you type into is a different process from the Clojure process that evaluates your code. Leiningen also has to parse your project file and make sure that everything is set up as it requires, or go and get what's needed from the web if there's anything missing in your maven configuration directory. In the Leiningen sample project file there are some options that can speed up things a little bit, if you read through it carefully. I think that Leiningen having slow startup is just one of the facts of life right now.
More relevant information:
Improving startup time of Clojure REPL with Leiningen on the Raspberry Pi
Faster
If you run lein repl from within a project directory, it will load your project's source files in addition to starting a repl. Even for a small project, this can add significant time if your source files reference external dependencies.
java -cp clojure-1.6.0.jar clojure.main won't load any project source files or dependencies.
There are multiple ways to improve the startup time off lein.
Documented here:
https://github.com/technomancy/leiningen/wiki/Faster
Your first question has been answered, so regarding the second one I guess what you want is to decrease the booting time cause you usually load some namespaces that are being changed as you code. It's possible to reload code from a modified namespace without exiting the REPL with (use 'your.namespace :reload). This way you might boot just once and reload the updated namespaces
user=> (doc require)
...
:reload forces loading of all the identified libs even if they are already loaded
:reload-all implies :reload and also forces loading of all libs that the identified libs directly or indirectly load via require or use
...
In the other hand if you read the output of lein help repl you will see how setup a REPL server and client that might reduce your booting time
In my case it was the cider-nrepl plug-in that significantly contributed to the load time.
Quick unscientifical research with jvisualvm showed that good deal of time goes into loading & evaluating the files (0.10-snapshot is not AOT-ed) and there was also init logic that scans the classpath.
Using fast trampolines halved the start-up time.
The jvm plays no bigger role than the OS or the file system in my opinion. It's all about the code being loaded.
I have multiple, separate leiningen projects that ostensibly could depend on one-another.
Example:
~/projects/mywebapp (my own project)
~/projects/noir (a clone of the github repo)
~/projects/clojureql (a clone of the github repo)
I want to have them all compiled into the same JVM at the same time. I would like to run the git repos bleeding edge (pulling new commits/making my own commits) and not have to run lein jar or lein deps and certainly not have to restart the VM if I change any of the projects.
Here's a use case:
After running lein swank, from within emacs, I connect to the repl and compile a file from mywebapp (with C-c-k), which requires a file from noir. It finds the version of the file in my projects directory. Later, I open that file, edit it, and compile it (with C-c-k).
Note that I'm not asking for auto-compiling when I do git pull. I just don't want to have to restart the JVM or do lengthy jar compiling processes.
Is this possible in leiningen? How can I set this up?
Does this question from the Lein FAQ help?
Q: I want to hack two projects in parallel, but it's annoying to switch between them.
A: Use a feature called checkout dependencies. If you create a directory called checkouts in your project root and symlink some other
project roots into it, Leiningen will allow you to hack on them in
parallel. That means changes in the dependency will be visible in the
main project without having to go through the whole
install/switch-projects/deps/restart-repl cycle. Note that this is not
a replacement for listing the project in :dependencies; it simply
supplements that for tighter change cycles.
If you're already using swank, you don't need lein checkout dependencies. You can just C-c C-k your project (which will load the jarred versions of noir/whatever), and then browse to your local version of noir and C-c C-k that as well. Swank happily sends all the code to your repl, and the jvm never need know that it came from a different place!
I can only recommend this for smallish changes though, because I think if you compile noir.core, which depends on (say) noir.internal, clojure will load the jarred version of noir.internal even while you compile the local version of noir.core. Even so, it's a handy trick in general.
I have been able to run a custom plugin from within my projects project.clj, and even leiningen/plugin.clj (ie just a private plugin) - but when I go to put this plugin in its own project - I am unable to get it to work at all.
Following the advice, I should create a new project, and have a namespace of leiningen.myplugin etc etc... but the jar that I produce doesn't seem to provide the new task in the project (either via jar, or via clojars).
http://nakkaya.com/2010/02/25/writing-leiningen-plugins-101/
https://github.com/technomancy/leiningen/blob/stable/doc/PLUGINS.md
Anyone who has published a plugin care to confirm if the above is correct - or is there some crucial step I am missing? (I assume my task goes in core.clj in the plugin project)
Do you have the :eval-in-leiningen option set to true in the project.clj?
In addition if you want to use the task all around with your leiningen without having to add it to the dev dependencies of the project where you need to use it you need to use lein plugin install
Or did i miss something about your problem
Note that eval-in-leiningen doesn't need to be used for very simple project-specific plugins or tasks, and it can sometimes wreak build havoc. You can enable a Leiningen task for a given project by just using .lein-classpath for that project. More information here:
Project-level Leiningen Plugin
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).