Java 在带有Jython的Spring引导应用程序中包含Python脚本失败-找不到模块
我正在尝试习惯python+java交互,因此我编写了一个小python脚本,希望从我的Java 在带有Jython的Spring引导应用程序中包含Python脚本失败-找不到模块,java,python,spring,jython,Java,Python,Spring,Jython,我正在尝试习惯python+java交互,因此我编写了一个小python脚本,希望从我的Spring Boot应用程序中执行该脚本。该脚本位于(相对于.java-文件)路径/scripts\u py/getStockPrice.py中,该路径包含getStockPrice-方法(请参见下面的代码)。因此,我集成了jython,并尝试执行以下CronJob: @Component public class CronService { private PythonScriptSinglet
Spring Boot应用程序中执行该脚本。该脚本位于(相对于.java
-文件)路径/scripts\u py/getStockPrice.py
中,该路径包含getStockPrice
-方法(请参见下面的代码)。因此,我集成了jython
,并尝试执行以下CronJob
:
@Component
public class CronService {
private PythonScriptSingleton pss = PythonScriptSingleton.getInstance();
private final Logger logger = LoggerFactory.getLogger(CronService.class);
//call every 5 sec
@Scheduled(fixedRate = 5000)
public void initStockPriceAPICall() {
this.getStockPrice("NFLX");
}
public void getStockPrice(String ticker) {
String result = (String) (Object) this.pss.getFunc_getPriceForTicker().__call__(new PyString(ticker));
try {
logger.info("Price is " + result);
} catch (NullPointerException e) {
logger.info("Catched NPE");
}
}
}
PythongScriptSingleton
(想法是,我可能需要多次执行该脚本-因此我尝试使用这个类的singleton
实例来保存该脚本,因此我不需要每次都重新编译它:
public class PythonScriptSingleton {
private static PythonScriptSingleton ps;
public static PythonScriptSingleton getInstance() {
if (ps == null) {
ps = new PythonScriptSingleton();
ps.initScript();
}
return ps;
}
private PyObject func_getPriceForTicker;
private PythonScriptSingleton() {
}
private void initScript() {
PythonInterpreter interpreter = new PythonInterpreter();
String fileUrlPath = "/scripts_py";
String scriptName = "getStockPrice.py";
interpreter.exec("import sys\n" + "import os \n" + "sys.path.append('" + fileUrlPath + "')\n" + "from "
+ scriptName + " import * \n");
String funcName = "getStockPrice";
PyObject someFunc = interpreter.get(funcName);
this.func_getPriceForTicker = someFunc;
interpreter.close();
}
public PyObject getFunc_getPriceForTicker() {
return func_getPriceForTicker;
}
}
Python脚本:
from yahoo_fin import stock_info as si
def getStockPrice(ticker):
price = si.get_live_price(ticker)
return price
我正在将嵌入式的tomcat
与Spring Boot
(可执行的JAR
-文件)和jython standalone 2.7.2
一起使用:
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.7.2</version>
</dependency>
我可以部分使用Jython运行您的程序-我无法从雅虎获得股票流程,因为雅虎内部依赖于numpy,而且Jython不支持numpy,因为它是cpython库
private void initScript() {
PythonInterpreter interpreter = new PythonInterpreter();
String fileUrlPath = "/users/sagar/demo/src/main/resources/python";
interpreter.exec("import sys");
interpreter.exec("sys.path.append('" + fileUrlPath + "')");
interpreter.exec("from getStockPrice import *"); this.func_getPriceForTicker =
interpreter.get("getStockPrice", PyFunction.class);
interpreter.close();
}
您将能够克服错误,但您将看到错误
Missing required dependencies ['numpy']
因此,我尝试使用另一个java python库,并做了如下更改
@SpringBootApplication
@EnableScheduling
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
private final Logger logger = LoggerFactory.getLogger(DemoApplication.class);
//call every 5 sec
@Scheduled(fixedRate = 5000)
public void initStockPriceAPICall() throws JepException {
this.getStockPrice("NFLX");
}
private void getStockPrice(String ticker) throws JepException {
try (Interpreter interp = new SharedInterpreter()) {
String fileUrlPath = "/users/sagar/demo/src/main/resources/python";
interp.exec("import sys");
interp.exec("sys.path.append('" + fileUrlPath + "')");
interp.exec("from getStockPrice import *");
interp.set("ticker", ticker);
interp.exec("price = getStockPrice(ticker)");
Object result = interp.getValue("price");
logger.info("Price is " + result);
}
}
}
pom.xml
<dependency>
<groupId>black.ninia</groupId>
<artifactId>jep</artifactId>
<version>3.9.0</version>
</dependency>
添加java库路径以加载本机库
-Djava.library.path=/usr/local/lib/python2.7/site-packages/jep
参考-
pip install jeb
-Djava.library.path=/usr/local/lib/python2.7/site-packages/jep