8

Java プログラムから Python スクリプトにデータ (文字列のリスト) を渡すための推奨される方法は何ですか。Python スクリプトはデータに対して何らかの処理を実行し、その結果を Java プログラムに戻す必要があります。

これを簡単に実行できるフレームワークはありますか?

編集:より具体的な要件。

私の Java プログラムは、外部サービスに接続して RAW データを取得し、Python に送信するスケジューラ (X 分 Y 秒ごとに実行) です。

Python ですべてを書き直すことはできますが、それにはかなりの時間がかかります。今持っているものを再利用する方法がないか探していました。

既存の Python スクリプトを最小限の変更で使用したいと考えています。私の python スクリプトは、多数の外部ライブラリ (numpy など) を使用します。Java から Python に渡されるデータは Json 形式であり、Python から返されるデータも Json です。

ソケットの使用はオプションですが、サーバー プロセスを実行する必要があります。

4

4 に答える 4

5

数か月前に同様の問題に直面したときに、これを一緒にハッキングしました。個別のプロセスが必要だったので、Jython は避けました。Java コードは、リクエストをリッスンするサーバーですが、失敗しても再接続しません。概念は、クラスはソケット メンバーを持つ拡張スレッドであるため、送信コマンドと受信コマンドはオブジェクト スレッドをブロックし、ホスト スレッドは影響を受けないままにしておくことができます。

Python コード:

import StringIO
import re
import select
import socket
import sys
import threading

class IPC(threading.Thread):

    def __init__(self, line_filter = None):
        threading.Thread.__init__(self)
        self.daemon = True
        self.lock = threading.Lock()
        self.event = threading.Event()
        self.event.clear()
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.recv_buffer_size = 8192
        self.buffer = StringIO.StringIO()
        if(line_filter == None):
            self.line_filter = lambda x: x
        else:
            self.line_filter = line_filter


    def run(self):
        self.sock.connect(("localhost", 32000))
        data = True
        while data:
            try:
                data = self.sock.recv(self.recv_buffer_size)
            except socket.error, e:
                print e
                self.sock.close()
                break

            self.lock.acquire()
            self.buffer.write(data)
            self.lock.release()
            self.event.set()

    def readlines(self):
        self.lock.acquire()

        self.buffer.seek(0)
        raw_lines = self.buffer.readlines()
        self.buffer.truncate(0)

        self.lock.release()

        lines = map(self.line_filter, raw_lines)
        return lines

proc_control = IPC()
while True:
    proc_control.event.wait()
    data = proc_control.readlines()
    if(data):
        # Do Stuff

    proc_control.event.clear()

Java コード:

SocketIPC.java:

package project;

import java.net.Socket;
import java.net.ServerSocket;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

public class SocketIPC {

    public PrintWriter out;
    public BufferedReader in;
    Socket socket = null;
    ServerSocket serverSocket = null;
    ConnectionListener connlisten = null;
    DataListener datalisten = null;
    Thread connlisten_thread = null;
    Thread datalisten_thread = null;
    CommandObject ipc_event_cmd = null;

    // Server thread accepts incoming client connections
    class ConnectionListener extends Thread {

        private int port;

        ConnectionListener(int port) {
            this.port = port;
        }

        @Override
        public void run() {
            try {
                serverSocket = new ServerSocket(port);
                socket = serverSocket.accept();
                out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));

                datalisten = new DataListener();
                datalisten_thread = new Thread(datalisten);
                datalisten_thread.start();
            } catch (Exception e) {
                System.err.println("SocketIPC creation error: " + e.getMessage());
            }
        }
    }

    // Server thread accepts incoming client connections
    class DataListener extends Thread {

        String data_str = null;

        DataListener() {
        }

        @Override
        public void run() {
            try {
                while(true) {
                    data_str = recv();
                    ipc_event_cmd.buffer.add(data_str);
                    ipc_event_cmd.execute();
                }
            } catch (Exception e) {
                System.err.println("SocketIPC reading error: " + e.getMessage());
            }
        }
        public String read() {
            String ret_string = null;
            if(!ipc_event_cmd.buffer.isEmpty()) {
                ret_string = ipc_event_cmd.buffer.remove(0);
            }
            return ret_string;
        }
    }

    public SocketIPC(int port) {
        ipc_event_cmd = new CommandObject();
        connlisten = new ConnectionListener(port);
        connlisten_thread = new Thread(connlisten);
        connlisten_thread.start();
    }

    public void send(String msg) {
        if (out != null) {
            out.println(msg);
        }
    }

    public void flush() {
        if (out != null) {
            out.flush();
        }
    }

    public void close() {
        if (out != null) {
            out.flush();
            out.close();
            try {
                in.close();
                socket.close();
                serverSocket.close();
            } catch (Exception e) {
                System.err.println("SocketIPC closing error: " + e.getMessage());
            }
        }
    }

    public String recv() throws Exception {
        if (in != null) {
            return in.readLine();
        } else {
            return "";
        }
    }

    public void set_cmd(CommandObject event_cmd) {
        if (event_cmd != null) {
            this.ipc_event_cmd = event_cmd;
        }
    }
}

CommandObject.java:

package project;

import java.util.List;
import java.util.ArrayList;

public class CommandObject {

    List<String> buffer;

    public CommandObject() {
        this.buffer = new ArrayList<String>();
    }

    public void execute() {
    }

}

DoStuff.java:

package project;

import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Random;

public class DoStuff extends CommandObject {

    public DoStuff () {
    }

    @Override
    public void execute() {
        String tmp_string = null;
        while (!buffer.isEmpty()) {
            tmp_string = buffer.remove(0);
            // Do Stuff
        }
    }
}
于 2013-06-24T08:34:00.437 に答える
1

Jythonの仕事のようですね! Jython は、Java で記述された組み込み可能な Python ランタイムです。Python スクリプトを別のプロセスで実行する必要がない限り (たとえば、それを強制終了したい、大量のメモリを使用する可能性があるなど)、これが断然最良の方法です。

于 2013-06-23T15:40:50.720 に答える
1

Java と python を一緒に作業しようとしている場合は、Jythonを使用して生活を簡素化してください。

JPython の後継である Jython は、Java で記述された Python プログラミング言語の実装です。Jython プログラムは、任意の Java クラスをインポートして使用できます。一部の標準モジュールを除いて、Jython プログラムは Python モジュールの代わりに Java クラスを使用します。Jython には、標準の Python プログラミング言語ディストリビューションのほとんどすべてのモジュールが含まれていますが、元々 C で実装されていたモジュールの一部が欠けているだけです。

Python パスに Java lib があると仮定します。Java クラスを使用することがいかに簡単かを理解するためのコード スニペットを次に示します。

'''
Import JavaUtilities class from a java package
'''
from com.test.javalib import JavaUtilities 

'''
Call a java method
'''
response  = JavaUtilities.doSomething();
于 2013-06-23T15:41:34.973 に答える
0

Java と Python の通信に最適なJythonをご覧ください。

于 2013-06-23T15:42:08.177 に答える