尝试使用Debian提供的clojure包

动机

在使用Clojure进行开发时,我一直在使用boot-clj,从未使用过Debian提供的clojure包。但是,当我想要创建一些小工具时,每次都使用boot-clj创建项目,或者安装从jar文件中拾取的库或/usr/share/java中的库到我的maven仓库中,这些都很麻烦。因此,我决定总结并记录如何使用Debian提供的方法。

步驟

安装
$ sudo apt install clojure

随便写个像脚本一样的东西。这里所说的“像脚本一样”是指不设置命名空间。

测试.clj

(println "Hello")

进行。

命令
$ clojure test.clj
Hello

当我们想要使用其他库时,可以通过”-cp”来添加类路径。
当我们想要传递属性给JVM时,可以在代码中使用System/setProperty进行设置。
虽然可以在Clojure应用程序的命令行中一次接收然后用setProperty进行传递(如果情况最坏),但由于/usr/bin/clojure的实现原因,无法直接通过-D选项将其传递给JVM。

尽管没有什么好处,我想试试看是否可以使用Jython从Clojure中执行Python代码。请先通过apt安装jython。

$ sudo apt install jython

将代码改写为以下方式。

测试.clj修订版2
(import '[org.python.util jython])

(System/setProperty "python.home" "/usr/share/jython")
(System/setProperty "python.path" "/usr/share/jython/Lib")
(System/setProperty "python.executable" "/usr/bin/jython")
(System/setProperty "python.console" "org.python.util.JLineConsole")

(jython/main (into-array String *command-line-args*))
命令
$ clojure -cp /usr/share/java/jython.jar:$PWD test.clj
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by jnr.posix.JavaLibCHelper$ReflectiveAccess (file:/usr/share/java/jnr-posix.jar) to method sun.nio.ch.SelChImpl.getFD()
WARNING: Please consider reporting this to the maintainers of jnr.posix.JavaLibCHelper$ReflectiveAccess
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Jython 2.7.1 (, Oct 22 2017, 13:43:00) 
[OpenJDK 64-Bit Server VM (Oracle Corporation)] on java11
Type "help", "copyright", "credits" or "license" for more information.
>>> print("Hello")
Hello
>>> 

忽略WARNING,尝试将Python代码作为命令参数传递给jython。

你好.py
print("Hello in a file")
命令 (Command)
$ clojure -cp /usr/share/java/jython.jar:$PWD test.clj hello.py
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by jnr.posix.JavaLibCHelper$ReflectiveAccess (file:/usr/share/java/jnr-posix.jar) to method sun.nio.ch.SelChImpl.getFD()
WARNING: Please consider reporting this to the maintainers of jnr.posix.JavaLibCHelper$ReflectiveAccess
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Hello in a file

如果将来可能需要与其他代码混合使用,可以给命名空间添加标识。

测试.clj 第三版
(ns test
  (:import [org.python.util jython]))

(defn launch-python [args]
  (System/setProperty "python.home" "/usr/share/jython")
  (System/setProperty "python.path" "/usr/share/jython/Lib")
  (System/setProperty "python.executable" "/usr/bin/jython")
  (System/setProperty "python.console" "org.python.util.JLineConsole")
  (jython/main (into-array String args)))

(defn -main [& args]
  (launch-python *command-line-args*))
“指令” (Zhi Ling)
$ clojure -cp /usr/share/java/jython.jar:$PWD -m test hello.py

在第二版中,与之前的版本不同的是,在命令行中使用“-m”选项来传递一个带有main函数的命名空间,并根据Java的类搜索规则从类路径中搜索test.clj(或相应的初始化类)。这里将当前目录指定为类路径,所以能够找到test.clj。

当把文件交给其他人时,将clj文件打包成jar文件。

$ jar cf from-me.jar *.clj

将制作好的jar文件传递并将其添加到类路径上以进行执行。

$ clojure -cp /usr/share/java/jython.jar:from-me.jar -m test hello.py

最后

由于与以前相比,JVM启动时间的延迟已经处于可接受范围内,所以在进行一些小型物品制作时,可以尝试使用这种方法。