Is there a way to have a JVM with Clojure running in the background, which evaluates Clojure code on demand?
The goal is to write some small "scripts" in Clojure, something that one would do with a scripting language like bash for example.
There is a way to write "shebang-style" scripts with the boot building tool, however the execution takes way too long because of the JVM/Clojure startup-time.
Use clojure.tools.nrepl to start a nREPL server that "runs in the background". Then you'll be able to run any "script" by attaching nREPL client to it.
Related
I'm writing a clojure cli and would like to know if there is a way to test if the out (i.e. println) is being written to a console or is being piped to another program?
This is similar to this question but for clojure.
Clojure is hosted language, so system interaction related stuff is more or less equivalent to Java. For Java there exists only partial solution described in this answer. You can of course implement isatty() using JNI and then interop from Clojure.
However, from ClojureScript hosted on Node.js it's easily achievable using process.stdin.isTTY (in ClojureScript would be (-> process .-stdin .-isTTY)). More details are in this answer.
You could use jnr-posix Java library
[com.github.jnr/jnr-posix "3.0.10"]
to call native posix methods directly from Clojure (using Java Interop):
(import 'jnr.posix.POSIXFactory)
(def posix (POSIXFactory/getPOSIX))
(.isatty posix java.io.FileDescriptor/out)
N.B. If you'll run you Clojure application using lein run command, Clojure will not be able to identify TTY terminal since lein will internally pipe stdio between two java processes. You could avoid internal piping by using lein trampoline run command or compiled jar file.
How can I set it up, so that I can use Light Table on the Mac, connected to a Ubuntu-hosted nREPL, and create a new program/project.clj? Can anybody help me to understand what my approach should be, and where I'm going wrong?
I have a Ubuntu server, in VirtualBox, along with Leiningen, Pedestal, and a pedestal 'helloworld' sample program, that displays in a browser. I just can't connect to the same REPL that runs the helloworld program. I don't have client-side access or control to the server-side object.
I want to do client-server Clojure development from my Mac host LT, creating server-side programs, that I can view in a REPL.
I don't find LT to be intuitive in this area, and the advice I've read only suggests that LT will connect to an existing project/REPL. I want to create new objects, from the client
Assuming you are talking mostly about the server side of things (don't know much yet about ClojureScript), here is how you would setup a new project and code interactively against a remote repl.
lein new project-name in your VM.
Setup your project.clj the way you want it. You must include dependencies!
Start the REPL in your VM and note the port number
Commit your code to version control (git).
Checkout the same codebase for editing in LightTable in Mac OSX.
Connect to the remote REPL.
Open core.clj or create a new namespace file and start hacking.
Evaluate your code snippets or the entire file.
There are a couple of potential problems I foresee with this. First is that whenever you add a dependency, you will need to commit the change to version control, synchronize your VM working copy, restart your REPL, and reconnect LightTable to the remote REPL.
Second, you may have problems as the project grows beyond a few namespaces. I believe if your namespace requires another namespace from your project, the remote REPL process will (I think) try to load it off it's local classpath. If the dependency is not there or has changed, I don't think LightTable is smart enough to send the required namespaces over the wire. Try it out and let us know what the actual behavior is.
I am trying to create a c++ daemon that runs on a Red Hat 6.3 platform and am having trouble understanding the differences between the libc daemon() call, the daemon shell command, startproc, start-stop-daemon and about half a dozen other methods that google suggests for creating daemons.
I have seen suggestions that two forks are needed, but calling daemon only does one. Why is the second fork needed?
If I write the init.d script to call bash daemon, does the c code still need to call daemon?
I implemented my application to call the c daemon() function since it seems the simplest solution, but I am running into the problem of my environment variables seem to get discarded. How do I prevent this?
I also need to run the daemon as a particular user, not as root.
What is the simplest way to create a C++ daemon that keeps its environment variables, runs as a specific user, and is started on system boot?
Why is the second fork needed?
Answered in What is the reason for performing a double fork when creating a daemon?
bash daemon shell command
My bash 4.2 does not have a builtin command named daemon. Are you sure yours is from bash? What version, what distribution?
environment variables seem to get discarded.
I can see no indication to that effect in the documentation. Are you sure it is due to daemon? Have you checked whether they are present before, and missing after that call?
run the daemon as a particular user
Read about setresuid and related functions.
What is the simplest way to create a C++ daemon that keeps its environment variables, runs as a specific user, and is started on system boot?
Depends. If you want to keep your code simple, forget about all of this and let the init script do this via e.g. start-stop-daemon. If you want to handle this in your app, daemon combined with retresuid should be a good approach, although not the only one.
I have an issue where I am trying to use my previous knowledge of programming to write a Minecraft launcher. I have use of commands that are in the standard C++ libraries and any Python eggs that are not huge. I would prefer to use system("java ...") in order to launch Minecraft.
The question in short:
How do I launch Minecraft from the command line without any auxillary Java code? (Without using launcher code like net.minecraft.LauncherFrame) Is it possible? I tried java -cp mine craft.jar net.minecraft.client.Minecraft from the Terminal in Mac OS X, to no avail, ending with a ClassNotFoundException.
Can anyone shed some light on my problem?
Thank you,
Pyro.
I'm running on linux, but this also should work for you:
java -cp ".minecraft/bin/*" -Djava.library.path=".minecraft/bin/natives/" net.minecraft.client.Minecraft "username" "login id"
You don't need to input your username/login id, but if you don't, you can't get in any servers.
You can get your login id here: https://login.minecraft.net?user=<username>&password=<password>&version=13
More info about the authentication scheme here
UPDATE:
The new launcher for minecraft 1.6 changed a lot.
For the launch command you should look in .minecraft/versions/<version>/<version>.json
The authentication also changed. It now uses POST parameters and returns JSON. More about it here.
How or in what way would I call out to my clojure code to process the tasks on a RabbitMQ queue?
Would I have to write a daemon or what?
I know java code takes a long time to start up initially, so I would hope there would be a way to write a long running process for my clojure code to be run against.
I'm totally lost as to what container clojure would run in e.g. would it be a daemon, if yes, how to write a clojure daemon?
Your question is a bit generic, so let me break it down:
You have a RabbitMQ queue and you want to consume messages from within Clojure
You want to run this message consumer as a standalone program
You want to run this program as a background task
From your question I understand that you've got the first part (consuming RabbitMQ messages in clojure) covered.
For the second part of your question, running a clojure program standalone:
You need to create a main function in your clojure code so that you can run it as a standalone program:
(defn -main [& args]
"your code")
For more on this, see the clojure website. If you are using Leiningen as a build tool, you should specify your main function in your project.clj file and then build an uberjar, e.g.
$ lein compile
$ lein uberjar
$ java -jar my-uber-jar.jar
The procedure to run your program as a background task is different for different operating systems. The simplest way to run something in the background is to add an ampersand after the command:
$ java -jar my-uber-jar.jar &
But your program will terminate when you close the terminal you typed this command in.
I wrote a blog post about clojure and rabbitMQ, hope it helps!
It covers adding messages to and getting them from queues.
http://www.learningclojure.com/2011/02/rabbitmq-clojure-hello-world.html
If you don't know how to make daemons (It's quite complicated, and I've never done it from clojure), but want a long running process, then a work around might be a screen session. Then you can run your program in a terminal, but still log out and leave it running.
As it happens, I also once wrote a getting started tutorial about screen. You can find it here:
http://johnsunixtips.blogspot.com/2010/12/most-basic-possible-screen-tutorial.h