How a Python Script Can Launch a Clojure Application
If you ever need a Python Script that starts a Clojure application, do something else and then stops the application then this post is for you. The script below considers that you have a Clojure application that is self-contained in a single jar file. All the dependencies are there and you run it using java -jar [jar-file.jar]
. If you have something different from that, then make sure the Clojure application can run via console from where the Python script is located. Learn the code below by reading the inline comments.
# Copy, paste and adapt this code in a file located in the root of your Clojure project, in the same level of the project.clj file.
import os
import signal
import subprocess
import time
import traceback
# Reusable function used to kill a subprocess whenever needed. It is used twice in the code.
def _kill_subprocess(subp):
os.killpg(os.getpgid(subp.pid), signal.SIGTERM)
# If you want, you can even build your self-contained jar file before executing it.
subprocess.call(['lein', 'ring', 'uberjar'])
# Executes the jar file as a subprocess, so it will be alive as long as the Python script keeps executing.
subp = subprocess.Popen(
'java -jar target/proj-0.1.0-standalone.jar',
shell=True,
preexec_fn=os.setsid)
# Waits the application to fully launch before doing something else. You have to adapt the seconds below for the needs of your application.
time.sleep(12)
# Write some Python code that does something while the Clojure application is running. When it finishes then the Clojure application will also finish.
try:
do_something_important()
except:
traceback.print_exc()
_kill_subprocess(subp)
exit(1)
# Kills the subprocess to stop the Clojure application.
_kill_subprocess(subp)
exit(0)
That’s a use case, but if you need something slightly different from that let me know in the comments below.
Recent Posts
Can We Trust Marathon Pacers?
Introducing LibRunner
Clojure Books in the Toronto Public Library
![](/images/posts/clojure-books-library.jpg)
Once Upon a Time in Russia
![](/images/posts/saint-petersburg.jpg)
FHIR: A Standard For Healthcare Data Interoperability
![](/images/posts/dragon-sketch.png)
First Release of CSVSource
![](https://www.hildeberto.com/csvsource/images/waterloo_tree_inventory.png)
Astonishing Carl Sagan's Predictions Published in 1995
![](/images/posts/carl-sagan-1987.jpg)
Making a Configurable Go App
![](/images/posts/2021-04-11-configurable-go-app.png)
Dealing With Pressure Outside of the Workplace
![](/images/posts/measuring-pressure-golang.png)
Reacting to File Changes Using the Observer Design Pattern in Go
![](/images/posts/observer-design-pattern.png)
Provisioning Azure Functions Using Terraform
![](/images/posts/terraform-azure-function.png)
Taking Advantage of the Adapter Design Pattern
![](/images/posts/2021-02-28-adapter-go-redis.png)
Applying The Adapter Design Pattern To Decouple Libraries From Go Apps
![](/images/posts/adapter-pattern.png)
Using Goroutines to Search Prices in Parallel
![](/images/posts/golang-sync-goroutine.jpg)
Applying the Strategy Pattern to Get Prices from Different Sources in Go
![](/images/posts/golang-strategy-pattern.png)