简体   繁体   English

使用Processbuilder从Java Web应用程序调用python脚本

[英]Calling python script from java web application with Processbuilder

I am working on a simple meteo station - I want to use raspberry pi 3b+ as a host, dht22 sensor and write a web application in Java (with spring boot, then deploy it to tomcat 8) and Python for retrieving sensor's data. 我正在一个简单的气象站上工作-我想使用树莓派3b +作为主机,dht22传感器,并用Java(使用Spring Boot,然后将其部署到tomcat 8)和Python编写Web应用程序以检索传感器的数据。 What I've done so far: 到目前为止,我所做的是:

Python application for retrieving and displaying data. 用于检索和显示数据的Python应用程序。 Works as expected, it just prints something like "22.5;37.4": 可以按预期工作,它只显示“ 22.5; 37.4”之类的内容:

import Adafruit_DHT

DHT_SENSOR = Adafruit_DHT.DHT22
DHT_PIN = 4

humidity, temperature = Adafruit_DHT.read_retry(DHT_SENSOR, DHT_PIN)

if humidity is not None and temperature is not None:
    print("{0:0.1f};{1:0.1f}".format(temperature, humidity))
else:
    print("FAIL")

Then I've wrote a java application, put it into .jar and checked if I am able to get sensor's data. 然后,我编写了一个Java应用程序,将其放入.jar,并检查是否能够获取传感器的数据。 Not a rocket science, also works as expected when I use java -jar InputTest.jar on my raspberry pi: 不是火箭科学,当我在树莓派上使用java -jar InputTest.jar时,也可以按预期工作:

public static void main(String[] args) {
    try {
        ProcessBuilder pb = new ProcessBuilder("python", "/home/pi/Desktop/input/dht_once.py");
        Process process = pb.start();
        BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
        String line;
        while ((line = reader.readLine()) != null) {
            System.out.println("measured: " + line);
        }
        process.waitFor(); 
    } catch (IOException ) {
        System.out.println(" exception " + e.getLocalizedMessage());
    }
}

Then I've created a spring boot application, put my java code inside (logic same as above), packed as a war, deployed to tomcat 8 and run it. 然后,我创建了一个Spring Boot应用程序,将我的Java代码放入其中(与上面的逻辑相同),打包为一战,部署到tomcat 8并运行它。 It turned out nothing is being printed (of course I've changed code to log output to logfile, it works fine, I can see other logs inside). 原来没有打印任何内容(当然,我已经更改了代码以将输出记录到日志文件中,效果很好,我可以在其中看到其他日志)。 No issues in logs, it looks like reader never returns a line. 日志中没有问题,看起来读者从未返回任何行。
I believe application does not wait for a process to produce output, but I have no idea why. 我相信应用程序不会等待进程产生输出,但是我不知道为什么。 Important thing: it takes up to few seconds to produce sensor's output. 重要的是:产生传感器的输出最多需要几秒钟的时间。 I've also changed python script just for test purposes to return value immediately: 我还出于测试目的更改了python脚本以立即返回值:

print("22.4;33.0")

and it results in successful read by java web application. 并导致Java Web应用程序成功读取。 But when it has to wait few seconds for the output it kills process (process.isAlive() is false right after while loop). 但是,当它必须等待几秒钟的输出时,它会终止进程(while循环之后,process.isAlive()为false)。 I've also tried to play with sleep() on current thread to force it to wait for python process but no success. 我也尝试过在当前线程上使用sleep()来强制它等待python进程,但没有成功。

Do you guys have any idea what can be the reason for this behavior? 你们知道这种行为的原因是什么吗? Is there anything more I should check? 还有什么我应该检查的吗?

TLDR; TLDR;
Java application which creates python process works fine until I run it as a web application - then it looks like it does not wait for a process' output 创建python进程的Java应用程序可以正常工作,直到我将其作为Web应用程序运行-然后看起来它不等待进程的输出

I haven't found a solution yet, however I've implemented workaround/cleaner solution. 我还没有找到解决方案,但是我已经实现了解决方法/更清洁的解决方案。 I've decided to separate totally java and python code and created microservice for data retrieving. 我决定将Java和Python代码完全分开,并创建了用于数据检索的微服务。 I use flask for rest webservice (followed this tutorial https://docs.dataplicity.com/docs/control-gpios-using-rest-api ) and call it directly from java. 我将烧瓶用于其余的Web服务(本教程之后https://docs.dataplicity.com/docs/control-gpios-using-rest-api )并直接从Java调用它。
Since this does not resolve my initial question I do not mark it as an answer, however it might help someone. 由于这不能解决我的最初问题,因此我不会将其标记为答案,但是它可能会对某人有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM