https://www.jython.org/index
Source:
https://github.com/jython
Jython是比较有名的连接Java和Python的桥梁(不应该认为是桥本身),Jython是用Java编写的Python解释器。
Jython最大的劣势在于,目前(2020.10)只支持Python2.7,无法访问庞大的CPython生态系统,不支持如NumPy或SciPy之类的库,而很多机器学习的工具都依赖这些库。
Jython的优势在于灵活,可以直接将python代码嵌入Java代码中,也允许在Python中直接写Java代码:
1 2 3 4 5 6 7 8 9
import org.python.util.PythonInterpreter;public class JythonHelloWorld { public static void main (String[] args) { try (PythonInterpreter pyInterp = new PythonInterpreter()) { pyInterp.exec("print('Hello Python World!')" ); } } }
1 2 3 4
from java.lang import System print ('Running on Java version: ' + System.getProperty('java.version' ))print ('Unix time from Java: ' + str (System.currentTimeMillis()))
Website:
https://github.com/bcdev/jpy/
Documentation:
https://jpy.readthedocs.io/en/latest/
Source:
https://github.com/bcdev/jpy
PyPI:
https://pypi.org/project/jpy/
jpy是一个双向的Python-Java桥,可以使用它在Python程序中嵌入Java代码,或者反过来使用。它是专门针对两种语言之间的最大数据传输速度而设计的。
jpy的最初开发是由于需要为一个用Java编程的已建立的科学成像应用程序编写Python扩展,即SNAP toolbox,由欧洲航天局(ESA)资助的项目。(jpy与SNAP发行版捆绑在一起。)
clone the repository
1 2 3
export JDK_HOME=<your-jdk-dir> export JAVA_HOME=$JDK_HOME python3 setup.py build maven bdist_wheel
在Python中使用:
1 2 3 4 5 6 7 8 9 10
jpy.create_jvm(["-Djava.class.path=" + jar_path]) StringBuilder = jpy.get_type("java.lang.StringBuilder" ) sb = StringBuilder() sb.append("Demonstration of " ) sb.append("StringBuilder" ) print (sb.toString())Main = jpy.get_type("net.talvi.pythonjavabridgedemos.Main" ) main = Main("Bob" ) print (main.greet("Wotcha" ))
需要很多设置才能使用,不是很推荐
https://github.com/ninia/jep
Documentation:
https://github.com/ninia/jep/wiki
Source:
https://github.com/ninia/jep
PyPI:
https://pypi.org/project/jep/
在其首页介绍是通过 ==JNI== 来将CPython嵌入Java
setup.py build install命令进行编译安装。
Install完成之后,Python对应的site-package路径也会有对应的jar包。
invoke_args.py
1 2 3 4 5 6 7 8
import numpy as npimport pandas as pd df2 = pd.DataFrame(np.array([[1 , 2 , 3 ], [4 ,5 , 6 ], [7 , 8 , 9 ]])) def invokeNoArgs (): print ("hello" ) print (df2)
Java调用Python代码如下,注意把JEP添加到Java的Library Path中去。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
package first; import jep.Interpreter;import jep.JepConfig;import jep.JepException;import jep.SubInterpreter; public class invoke2 { public static void main (String[] args) throws JepException { JepConfig config = new JepConfig(); config.addIncludePaths("C:\\Users\\IdeaProjects\\DailyLearning\\src\\python" ); try (Interpreter interp = new SubInterpreter(config)){ interp.eval("from invoke_args import *" ); Object result = interp.invoke("invokeNoArgs" ); if (result!=null ){ throw newIllegalStateException( "Received " +result + "but expected null" ); } } } }
支持CPython扩展和模块,比如numpy等库,但不能保证在所有情况下都可正常工作
支持python3.x
不支持从Python中调用Java
https://www.py4j.org/
允许在Python解释器中运行的Python程序动态访问Java虚拟机中的Java对象
允许Java程序会调Python对象
JPype
Website:
https://github.com/jpype-project/jpype/
是一个Python库,让Python可以使用Java的库
并非像Jython那样实现了解释器,而是通过两个虚拟机的本机接口实现
同时提供对CPython和Java库的访问
PyJNIus
Website:
https://github.com/kivy/pyjnius
Python库,不支持Java调Python
允许Python通过JNI来获得Java的类,从Github star来看是上述几种方式中最多的
适用场景:极个别的加密算法等内容,用python不方便实现或者实现较耗时,可基于Pyjnius把java类当做python库使用
https://developer.aliyun.com/article/175227
https://juejin.im/post/6844903972596088846#heading-18
使用HTTP接口是一种耦合性较低的方式,也方便Java部分和Python部分单独开发,但问题在于当服务器不够多但访问量较大时,并发网络访问会成为速度的瓶颈。
对于 Java 来说,能够本地调用的有两种:
Java 代码包
Native 代码模块
像Jython这种在JVM中使用Python的方式有诸多局限,还有一条路就是,把 Python 代码转换成 Native 代码块,Java 通过 JNI 的接口形式调用。
https://www.graalvm.org/
Documentation:
https://www.graalvm.org/docs/
Source:
https://github.com/oracle/graal
GraalVM并非某个库或者工具,而且一个JVM虚拟机,但目前仍处于实验性质,其目标可以用雄心勃勃来形容,引用周志明老师的话:
Graal VM被官方称为“Universal VM”和“Polyglot VM”,这是一个在HotSpot虚拟机基础上增强而成 的跨语言全栈虚拟机,可以作为“任何语言”的运行平台使用,这里“任何语言”包括了Java、Scala、 Groovy、Kotlin等基于Java虚拟机之上的语言,还包括了C、C++、Rust等基于LLVM的语言,同时支 持其他像JavaScript、Ruby、Python和R语言等。Graal VM可以无额外开销地混合使用这些编程语言, 支持不同语言中混用对方的接口和对象,也能够支持这些语言使用已经编写好的本地库文件。
Graal VM的基本工作原理是将这些语言的源代码(例如JavaScript)或源代码编译后的中间格式 (例如LLVM字节码)通过解释器转换为能被Graal VM接受的中间表示(Intermediate Representation, IR),譬如设计一个解释器专门对LLVM输出的字节码进行转换来支持C和C++语言,这个过程称为程 序特化(Specialized,也常被称为Partial Evaluation)。Graal VM提供了Truffle工具集来快速构建面向一 种新语言的解释器,并用它构建了一个称为Sulong的高性能LLVM字节码解释器。
参考《深入理解Java虚拟机》周志明
下面这个回答对GraalVM有进一步的介绍:
如何评价 GraalVM 这个项目? - kelthuzadx的回答 - 知乎
https://www.zhihu.com/question/274042223/answer/1270829173
个人看法:
目前GraalVM还在实验阶段,无法保证其能兼容Python的现有库,如果希望在工程上同时使用Java和Python,可能尚不适合
如果使用Jython可以尝试迁移到GraalVM
首先需要明白使用的场景
如果本地简单实用,那么直接用runtime新开进程就可以
尽量减少程序耦合
推荐使用RESTFUL,网络传输是其速度的瓶颈
使用支持Python3的方式