在Ubuntu系统中,Python和Java可以通过多种方式实现交互。以下是一些常见的方法:
Jython是一个在Java虚拟机(JVM)上运行的Python实现。它允许你在Java应用程序中直接使用Python代码。
wget https://repo1.maven.org/maven2/org/python/jython-standalone/2.7.2/jython-standalone-2.7.2.jar
java -jar jython-standalone-2.7.2.jar your_script.py
JNI允许Java代码调用本地代码(如C/C++),而Python可以通过C扩展与JNI交互。
Java代码(HelloWorld.java)
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello from Java!");
}
}
编译成共享库:
javac -h . HelloWorld.java
Python代码(call_java.py)
import ctypes
# Load the shared library
lib = ctypes.CDLL('./HelloWorld.so')
# Call the Java method
lib.main([])
你可以创建一个Java应用程序作为HTTP服务器,然后使用Python通过HTTP请求与Java应用程序通信。
Java(使用Spring Boot)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class JavaApplication {
public static void main(String[] args) {
SpringApplication.run(JavaApplication.class, args);
}
}
@RestController
class HelloController {
@GetMapping("/hello")
public String sayHello() {
return "Hello from Java!";
}
}
Python(使用requests库)
import requests
response = requests.get('http://localhost:8080/hello')
print(response.text)
你可以使用消息队列(如RabbitMQ、Kafka)在Python和Java之间传递消息。
Java(使用RabbitMQ)
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
public class JavaProducer {
private final static String QUEUE_NAME = "hello";
public static void main(String[] argv) throws Exception {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
channel.queueDeclare(QUEUE_NAME, false, false, false, null);
String message = "Hello from Java!";
channel.basicPublish("", QUEUE_NAME, null, message.getBytes());
System.out.println(" [x] Sent '" + message + "'");
}
}
}
Python(使用pika库)
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='hello')
def callback(ch, method, properties, body):
print(" [x] Received %r" % body.decode())
channel.basic_consume(queue='hello', on_message_callback=callback, auto_ack=True)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
gRPC是一个高性能、开源和通用的RPC框架,可以在Python和Java之间实现高效的通信。
proto文件(hello.proto)
syntax = "proto3";
package hello;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
编译生成代码:
protoc -I=. --java_out=./java --python_out=./python hello.proto
Java(实现服务端)
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;
import hello.GreeterGrpc;
import hello.HelloRequest;
import hello.HelloReply;
import java.io.IOException;
public class JavaServer {
private Server server;
private void start() throws IOException {
int port = 50051;
server = ServerBuilder.forPort(port)
.addService(new GreeterImpl())
.build()
.start();
System.out.println("Server started, listening on " + port);
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
System.err.println("*** shutting down gRPC server since JVM is shutting down");
JavaServer.this.stop();
System.err.println("*** server shut down");
}));
}
private void stop() {
if (server != null) {
server.shutdown();
}
}
private void blockUntilShutdown() throws InterruptedException {
if (server != null) {
server.awaitTermination();
}
}
public static void main(String[] args) throws IOException, InterruptedException {
final JavaServer server = new JavaServer();
server.start();
server.blockUntilShutdown();
}
static class GreeterImpl extends GreeterGrpc.GreeterImplBase {
@Override
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}
}
Python(实现客户端)
import grpc
import hello_pb2
import hello_pb2_grpc
def run():
with grpc.insecure_channel('localhost:50051') as channel:
stub = hello_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(hello_pb2.HelloRequest(name='Python'))
print("Greeter client received: " + response.message)
if __name__ == '__main__':
run()
选择哪种方法取决于你的具体需求和应用场景。HTTP API和消息队列适用于松耦合的系统,而JNI和gRPC适用于需要高性能和强类型检查的场景。