Java von Python aus aufrufen

123

Was ist der beste Weg, um Java von Python aus aufzurufen? (Jython und RPC sind für mich keine Option).

Ich habe von JCC gehört: http://pypi.python.org/pypi/JCC/1.9 ein C ++ - Codegenerator zum Aufrufen von Java aus C ++ / Python. Dies erfordert jedoch das Kompilieren jedes möglichen Aufrufs; Ich würde eine andere Lösung bevorzugen.

Ich habe von JPype gehört: http://jpype.sourceforge.net/ Tutorial: http://www.slideshare.net/onyame/mixing-python-and-java

import jpype 
jpype.startJVM(path to jvm.dll, "-ea") 
javaPackage = jpype.JPackage("JavaPackageName") 
javaClass = javaPackage.JavaClassName 
javaObject = javaClass() 
javaObject.JavaMethodName() 
jpype.shutdownJVM() 

Das sieht so aus, wie ich es brauche. Die letzte Version stammt jedoch aus dem Januar 2009 und ich sehe Leute, die JPype nicht kompilieren können.

Ist JPype ein totes Projekt?

Gibt es noch andere Alternativen?

Grüße, David

David Portabella
quelle
3
Könnten Sie näher erläutern, warum Jython und RPC Ihrer Meinung nach keine Option für Ihre Situation sind?
Nathan Davis
2
Es sieht so aus, als ob es in der Zwischenzeit eine neue JPype-Version gab: 0.5.4.2 am 28.07.2011
Joril

Antworten:

51

Hier ist meine Zusammenfassung dieses Problems: 5 Möglichkeiten, Java aus Python aufzurufen

http://baojie.org/blog/2014/06/16/call-java-from-python/ ( zwischengespeichert )

Kurze Antwort: Jpype funktioniert ziemlich gut und hat sich in vielen Projekten bewährt (z. B. Python-Boilerpipe), aber Pyjnius ist schneller und einfacher als JPype

Ich habe Pyjnius / Jnius, JCC, Javabridge, Jpype und Py4j ausprobiert.

Py4j ist etwas schwierig zu verwenden, da Sie ein Gateway starten müssen, um eine weitere Ebene der Fragilität hinzuzufügen.

Jie Bao
quelle
135

Sie können auch Py4J verwenden . Es gibt ein Beispiel auf der Startseite und viele Dokumentationen, aber im Wesentlichen rufen Sie einfach Java-Methoden aus Ihrem Python-Code auf, als wären sie Python-Methoden:

from py4j.java_gateway import JavaGateway
gateway = JavaGateway()                        # connect to the JVM
java_object = gateway.jvm.mypackage.MyClass()  # invoke constructor
other_object = java_object.doThat()
other_object.doThis(1,'abc')
gateway.jvm.java.lang.System.out.println('Hello World!') # call a static method

Im Gegensatz zu Jython wird ein Teil von Py4J in der Python-VM ausgeführt, sodass es immer "auf dem neuesten Stand" mit der neuesten Version von Python ist und Sie Bibliotheken verwenden können, die unter Jython nicht gut laufen (z. B. lxml). Der andere Teil wird in der Java-VM ausgeführt, die Sie aufrufen möchten.

Die Kommunikation erfolgt über Sockets anstelle von JNI und Py4J verfügt über ein eigenes Protokoll (zur Optimierung bestimmter Fälle, zur Speicherverwaltung usw.).

Haftungsausschluss: Ich bin der Autor von Py4J

Barthelemy
quelle
Danke für den Link. es sieht aus wie eine Open-Source-Alternative zu dem, was DJNA vorgeschlagen hat, CodeMesh. Ich werde es mir auf jeden Fall ansehen. Es gibt jedoch das gleiche Problem wie in CodeMesh. Es ist erforderlich, den Java-Prozess vorher zu starten und sicherzustellen, dass er ausgeführt wird, bevor Python verwendet wird (siehe Beispiel auf der Hauptwebseite des Projekts, ListPrinter.java -> main -> GatewayServer.start ( )). Dies ist ein möglicher Fehlerpunkt. Ich denke immer noch, dass der Ansatz von JPype ausgezeichnet ist; nur dass es ein totes Projekt scheint.
David Portabella
8
@alvas Ich pflege immer noch Py4J, wenn du das gemeint hast.
Barthelemy
@Barthelemy, wie gehe ich vor, wenn der Java-Code von einer Bibliothek abhängig ist - in meinem Fall opencv?
1
@stack Stellen Sie einfach sicher, dass Sie opencv in Ihren Klassenpfad einfügen, und Sie können von Python aus darauf zugreifen, wenn Sie den GatewayServer starten.
Barthelemy
Funktioniert das für jedes Paket? Ich habe versucht: s = gateway.jvm.ch.ethz.ssh2.crypto.Base64() bt_out = s.decode();Hier hat die Klasse Base64 die Methoden encode () und decode () und ist Teil des Pakets ch.ethz.ssh2.cryptoin meiner JAR-Datei. Ich bekommefrom py4j.reflection import MethodInvoker ImportError: No module named reflection
Vishal Sahu
19

Pyjnius.

Dokumente: http://pyjnius.readthedocs.org/en/latest/

Github: https://github.com/kivy/pyjnius

Von der Github-Seite:

Ein Python-Modul für den Zugriff auf Java-Klassen als Python-Klassen mit JNI.

PyJNIus ist ein "Work In Progress".

Schneller Überblick

>>> from jnius import autoclass
>>> autoclass('java.lang.System').out.println('Hello world') Hello world

>>> Stack = autoclass('java.util.Stack')
>>> stack = Stack()
>>> stack.push('hello')
>>> stack.push('world')
>>> print stack.pop() world
>>> print stack.pop() hello
gdw2
quelle
5

Ich bin unter OSX 10.10.2 und habe JPype erfolgreich verwendet.

Bei Jnius sind Installationsprobleme aufgetreten ( andere auch ), Javabridge hat installiert, aber es gab mysteriöse Fehler, als ich versuchte, es zu verwenden. PyJ4 hat die Unannehmlichkeit, zuerst einen Gateway-Server in Java starten zu müssen, JCC würde nicht installieren. Schließlich funktionierte JPype. Es gibt eine gepflegte Gabel von JPype auf Github. Es hat die Hauptvorteile, dass (a) es ordnungsgemäß installiert wird und (b) es Java-Arrays sehr effizient in Numpy-Array konvertieren kann ( np_arr = java_arr[:])

Der Installationsprozess war:

git clone https://github.com/originell/jpype.git
cd jpype
python setup.py install

Und du solltest es können import jpype

Die folgende Demo hat funktioniert:

import jpype as jp
jp.startJVM(jp.getDefaultJVMPath(), "-ea")
jp.java.lang.System.out.println("hello world")
jp.shutdownJVM() 

Als ich versuchte, meinen eigenen Java-Code aufzurufen, musste ich zuerst compile ( javac ./blah/HelloWorldJPype.java) und den JVM-Pfad vom Standardpfad ändern (andernfalls werden unerklärliche Fehler "Klasse nicht gefunden" angezeigt). Für mich bedeutete dies, den Befehl startJVM in Folgendes zu ändern:

jp.startJVM('/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/MacOS/libjli.dylib', "-ea")
c = jp.JClass('blah.HelloWorldJPype')  
# Where my java class file is in ./blah/HelloWorldJPype.class
...
Peter
quelle
Ein kleines Wrapper-Modul, das die Verwendung von JPype ein wenig vereinfacht, finden Sie hier: github.com/petered/spiking-mlp/blob/master/spiking_mlp/…
Peter
4

Wenn Sie in Python 3 sind, gibt es eine Gabelung von JPype namens JPype1-py3

pip install JPype1-py3

Dies funktioniert bei mir unter OSX / Python 3.4.3. (Möglicherweise müssen Sie export JAVA_HOME=/Library/Java/JavaVirtualMachines/your-java-version)

from jpype import *
startJVM(getDefaultJVMPath(), "-ea")
java.lang.System.out.println("hello world")
shutdownJVM()
k107
quelle
4

Ich habe in letzter Zeit eine Menge Dinge in Python integriert, einschließlich Java. Die robusteste Methode, die ich gefunden habe, ist die Verwendung von IKVM und eines C # -Wrappers.

IKVM hat eine nette kleine Anwendung, mit der Sie jede Java-JAR nehmen und direkt in die .NET-DLL konvertieren können. Es übersetzt einfach den JVM-Bytecode in den CLR-Bytecode. Weitere Informationen finden Sie unter http://sourceforge.net/p/ikvm/wiki/Ikvmc/ .

Die konvertierte Bibliothek verhält sich wie eine native C # -Bibliothek, und Sie können sie verwenden, ohne die JVM zu benötigen. Anschließend können Sie ein C # DLL-Wrapper-Projekt erstellen und einen Verweis auf die konvertierte DLL hinzufügen.

Sie können jetzt einige Wrapper-Stubs erstellen, die die Methoden aufrufen, die Sie verfügbar machen möchten, und diese Methoden als DllEport markieren. Weitere Informationen finden Sie unter https://stackoverflow.com/a/29854281/1977538 .

Die Wrapper-DLL verhält sich wie eine native C-Bibliothek, wobei die exportierten Methoden genauso aussehen wie die exportierten C-Methoden. Sie können wie gewohnt mit ctype eine Verbindung zu ihnen herstellen.

Ich habe es mit Python 2.7 versucht, aber es sollte auch mit 3.0 funktionieren. Funktioniert unter Windows und Linux

Wenn Sie zufällig C # verwenden, ist dies wahrscheinlich der beste Ansatz, um fast alles in Python zu integrieren.

Rob Deary
quelle
1
Uhg ... du hast mich bei C # verloren. Ich werde nicht abstimmen, da dies in einigen Fällen eine praktikable Möglichkeit ist, aber dies setzt definitiv Windows und viele andere Dinge voraus.
Jared
2

Ich fange gerade an, JPype 0.5.4.2 (Juli 2011) zu verwenden und es sieht so aus, als ob es gut funktioniert ...
Ich bin auf Xubuntu 10.04

Joril
quelle
1

Ich gehe davon aus, dass Sie fertig sind, wenn Sie von C ++ nach Java gelangen können. Ich habe gesehen, dass ein Produkt der von Ihnen erwähnten Art gut funktioniert. Zufällig haben wir CodeMesh verwendet . Ich unterstütze diesen Anbieter nicht ausdrücklich und mache keine Aussage über die relative Qualität seines Produkts, aber ich habe gesehen, dass es in einem Szenario mit ziemlich hohem Volumen funktioniert.

Ich würde allgemein sagen, dass ich, wenn möglich, empfehlen würde, sich von der direkten Integration über JNI fernzuhalten, wenn Sie können. Einige einfache REST-Service-Ansätze oder warteschlangenbasierte Architekturen sind in der Regel einfacher zu entwickeln und zu diagnostizieren. Wenn Sie solche entkoppelten Technologien sorgfältig einsetzen, können Sie eine recht anständige Leistung erzielen.

djna
quelle
RPC (oder REST) ​​ist für mich keine Option.
David Portabella
Dies würde erfordern, dass Sie den Java-Prozess vorher starten und sicherstellen, dass er ausgeführt wird, bevor Sie Python verwenden. Dies ist ein möglicher Fehlerpunkt. Der Ansatz von JPype ist ausgezeichnet; nur dass es ein totes Projekt scheint.
David Portabella
Ich gebe allgemeine Ratschläge. JNI ist ein potenzielles Minenfeld.
DJNA
0

Aufgrund meiner eigenen Erfahrung mit dem Versuch, Java-Code in Python auszuführen, ähnlich wie Python-Code in Java-Code in Python ausgeführt wird, konnte ich keine einfache Methode finden.

Meine Lösung für mein Problem bestand darin, diesen Java-Code als Beanshell-Skripte auszuführen, indem ich den Beanshell-Interpreter als Shell-Commnad aus meinem Python-Code heraus aufrief, nachdem ich den Java-Code in einer temporären Datei mit den entsprechenden Paketen und Variablen bearbeitet hatte.

Wenn das, worüber ich spreche, in irgendeiner Weise hilfreich ist, helfe ich Ihnen gerne dabei, weitere Details meiner Lösungen mitzuteilen.

schattige alaa
quelle