Last active
June 22, 2021 10:00
-
-
Save brdloush/30efd7cdbf794ae3746454117180488d to your computer and use it in GitHub Desktop.
Standalone CLI utility that triggers a quartz job via QuartzScheduler JMX Bean. Requires clojure + JDK (openjdk 8,11,15 were succesfully tested).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
#_( | |
DEPS=' | |
{:deps {org.clojure/java.jmx {:mvn/version,"1.0.0"}}} | |
' | |
exec clojure $OPTS -Sdeps "$DEPS" -M "$0" "$@" | |
) | |
(ns jmx.core | |
(:require [clojure.java.jmx :as jmx] | |
[clojure.string :as str]) | |
(:import [javax.management.remote JMXServiceURL])) | |
(defn quartz-scheduler-mbean-name [] | |
(->> (jmx/mbean-names "*:*") | |
(map str) | |
(filter #(str/includes? % "type=QuartzScheduler")) | |
first)) | |
(defmacro with-local-pid-connection | |
[pid & body] | |
`(let [vm# (com.sun.tools.attach.VirtualMachine/attach (str ~pid)) | |
url# (.startLocalManagementAgent vm#)] | |
(with-open [connector# (javax.management.remote.JMXConnectorFactory/connect | |
(JMXServiceURL. url#) | |
{})] | |
(binding [jmx/*connection* (.getMBeanServerConnection connector#)] | |
~@body)))) | |
(defn add-system-classpath | |
"Add an url path to the system class loader" | |
[url-string] | |
(let [field (aget (.getDeclaredFields java.net.URLClassLoader) 0)] | |
(.setAccessible field true) | |
(let [ucp (.get field (ClassLoader/getSystemClassLoader))] | |
(.addURL ucp (java.net.URL. url-string))))) | |
(try (Class/forName "com.sun.tools.attach.VirtualMachine") | |
(catch ClassNotFoundException e | |
(add-system-classpath (format "file:///%s/../lib/tools.jar" (System/getProperty "java.home"))) | |
(Class/forName "com.sun.tools.attach.VirtualMachine"))) | |
(let [[pid job-name] *command-line-args*] | |
(if (and pid job-name) | |
(with-local-pid-connection pid | |
(let [scheduler-mbean (quartz-scheduler-mbean-name)] | |
(println (format "Triggering job %s on mbean %s" job-name scheduler-mbean)) | |
(jmx/invoke scheduler-mbean | |
:triggerJob | |
job-name | |
"DEFAULT" | |
(java.util.HashMap.)) | |
(println "Execution finished."))) | |
(println "Usage: triggerJob.clj <pid> <quartz-job-name>"))) |
Its usage might be furthermore simplified with naive helper function (think ~/.zshrc
) such as:
function run-quartz-job {
JPS_APP_NAME=$1 # provide the java app name as seen in `jps` output
JOB_NAME=$2
PID=$(jps | grep $JPS_APP_NAME | cut -d ' ' -f 1); triggerJob.clj $PID $JOB_NAME
}
Then the usage looks like:
➜ ~ run-quartz-job OurSpringbootApplication ourQuartzJob
Triggering job ourQuartzJob on mbean quartz:type=QuartzScheduler,name=ourapp,instance=brdloush-nb1624292395132
Execution finished.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
👍