पायथन से जावा कॉलिंग


123

अजगर से जावा को कॉल करने का सबसे अच्छा तरीका क्या है? (jython और RPC मेरे लिए कोई विकल्प नहीं है)।

मैंने JCC के बारे में सुना है: http://pypi.python.org/pypi/JCC/1.9 C ++ / Python से जावा को कॉल करने के लिए C ++ कोड जनरेटर लेकिन इसके लिए हर संभव कॉल को संकलित करने की आवश्यकता होती है; मैं एक और समाधान पसंद करूंगा।

मैंने JPype के बारे में सुना है: http://jpype.sourceforge.net/ ट्यूटोरियल: 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() 

ऐसा लगता है कि मुझे क्या चाहिए। हालाँकि, अंतिम रिलीज़ जनवरी 2009 से है और मैं देख रहा हूँ कि लोग JPype को संकलित करने में असफल हैं।

क्या JPype एक मृत परियोजना है?

क्या कोई अन्य विकल्प हैं?

सादर, डेविड


3
क्या आप इस बारे में विस्तार से जान सकते हैं कि आपको क्यों लगता है कि Jython और RPC आपकी स्थिति के लिए कोई विकल्प नहीं है?
नाथन डेविस

2
ऐसा लग रहा है कि इस बीच एक नया JPype रिलीज़ हुआ था: 2011-07-28 को
0.5.4.2

जवाबों:


51

यहाँ इस समस्या का मेरा सारांश है: अजगर से जावा को कॉल करने के 5 तरीके

http://baojie.org/blog/2014/06/16/call-java-from-python/ ( कैश्ड )

संक्षिप्त उत्तर: Jpype बहुत अच्छी तरह से काम करता है और कई परियोजनाओं (जैसे कि अजगर-बॉयलरपाइप) में सिद्ध होता है, लेकिन Pyjnius JPype से अधिक तेज़ और सरल है

मैंने Pyjnius / Jnius, JCC, javabridge, Jpype और Py4j की कोशिश की है।

Py4j का उपयोग करना थोड़ा कठिन है, क्योंकि आपको खुशबू की एक और परत जोड़कर एक प्रवेश द्वार शुरू करने की आवश्यकता है।


135

आप Py4J का उपयोग भी कर सकते हैं । फ्रंटपेज और बहुत सारे प्रलेखन पर एक उदाहरण है, लेकिन अनिवार्य रूप से, आप अपने अजगर कोड से जावा विधियों को कहते हैं जैसे कि वे अजगर के तरीके थे:

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

जेथॉन के विपरीत, Py4J का एक हिस्सा पायथन वीएम में चलता है, इसलिए यह हमेशा पायथन के नवीनतम संस्करण के साथ "अद्यतित" होता है और आप पुस्तकालयों का उपयोग कर सकते हैं जो ज्यथन (जैसे, एलएक्सएमएल) पर अच्छी तरह से नहीं चलते हैं। दूसरा भाग जावा वीएम में चलता है जिसे आप कॉल करना चाहते हैं।

संचार जेएनआई के बजाय सॉकेट्स के माध्यम से किया जाता है और Py4J का अपना प्रोटोकॉल है (कुछ मामलों का अनुकूलन करने के लिए, स्मृति का प्रबंधन करने के लिए, आदि)

डिस्क्लेमर: मैं Py4J का लेखक हूं


लिंक के लिए धन्यवाद। यह एक खुला स्रोत जैसा दिखता है जैसा कि djna ने प्रस्तावित किया, CodeMesh। मैं निश्चित रूप से इस पर एक नज़र डालूँगा। हालाँकि कोडमेश में भी यही समस्या है, इसके लिए जावा प्रक्रिया शुरू करने की आवश्यकता है, और सुनिश्चित करें कि यह अजगर का उपयोग करने से पहले चल रहा है (प्रोजेक्ट के मुख्य वेबपेज में सूची देखें, ListPrinter.java -> मुख्य - GatewayServer.start ( ))। यह विफलता का एक संभावित बिंदु है। मुझे अभी भी लगता है कि JPype का दृष्टिकोण उत्कृष्ट है; केवल यह कि यह एक मृत परियोजना लगती है।
डेविड पोर्टेबेला

8
@alvas मैं अभी भी Py4J को बनाए रखता हूं अगर आपका यही मतलब है।
बार्टेलमी

@Barthelemy, अगर जावा कोड मेरे मामले में एक पुस्तकालय - opencv पर निर्भर है, तो कैसे एकीकृत किया जाए?

1
@stack अपने classpath में opencv जोड़ना सुनिश्चित करें और गेटवेस्वर शुरू करने पर आप इसे पायथन से एक्सेस कर पाएंगे।
बर्थेलेमी

क्या यह किसी पैकेज के लिए काम करता है? मैंने कोशिश की: s = gateway.jvm.ch.ethz.ssh2.crypto.Base64() bt_out = s.decode();यहाँ बेस 6464 में विधि सांकेतिक शब्दों में बदलना () और डीकोड () है और ch.ethz.ssh2.cryptoमेरे .jar फ़ाइल में पैकेज का हिस्सा है । मुझे मिलता हैfrom py4j.reflection import MethodInvoker ImportError: No module named reflection
विशाल साहू

19

Pyjnius।

डॉक्स: http://pyjnius.readthedocs.org/en/latest/

गीथूब: https://github.com/kivy/pyjnius

जीथब पृष्ठ से:

जेएनआई का उपयोग करके पायथन कक्षाओं के रूप में जावा कक्षाओं का उपयोग करने के लिए एक पायथन मॉड्यूल।

PyJNIus एक "वर्क इन प्रोग्रेस" है।

त्वरित अवलोकन

>>> 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

5

मैं OSX 10.10.2 पर हूं, और JPype का उपयोग करने में सफल रहा।

जानूस ( अन्य के पास भी ) के साथ स्थापना समस्याओं में भाग गया , जाबरीज़ ने स्थापित किया लेकिन जब मैंने इसका उपयोग करने की कोशिश की तो रहस्यमयी त्रुटियां हुईं, PyJ4 को जावा में गेटवे सर्वर शुरू करने की यह असुविधा है, JCC स्थापित नहीं होगी। अंत में, JPype ने काम करना समाप्त कर दिया। वहाँ एक है JPype के बनाए रखा कांटा Github पर। इसके प्रमुख लाभ हैं कि (ए) इसे ठीक से स्थापित करता है और (बी) यह बहुत कुशलता से जावा सरणी को संख्यात्मक सरणी में बदल सकता है ( np_arr = java_arr[:])

स्थापना प्रक्रिया थी:

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

और आपको सक्षम होना चाहिए import jpype

निम्नलिखित डेमो ने काम किया:

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

जब मैंने अपने स्वयं के जावा कोड को कॉल करने की कोशिश की, तो मुझे पहले संकलन ( javac ./blah/HelloWorldJPype.java) करना पड़ा, और मुझे डिफ़ॉल्ट से जेवीएम पथ को बदलना पड़ा (अन्यथा आपको "अनावश्यक नहीं मिलेंगे" वर्ग "त्रुटियां नहीं मिली")। मेरे लिए, इसका मतलब है कि startJVM कमांड को बदलना:

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
...

जेपीपे को उपयोग करने के लिए थोड़ा आसान बनाने के लिए एक छोटा आवरण मॉड्यूल यहां है: github.com/petered/spiking-mlp/blob/master/spiking_mlp/…
पीटर

4

यदि आप पायथन 3 में हैं, तो JPype का एक कांटा है जिसे JPype1-p33 कहा जाता है

pip install JPype1-py3

यह मेरे लिए OSX / पायथन 3.4.3 पर काम करता है। (आपको इसकी आवश्यकता हो सकती है export JAVA_HOME=/Library/Java/JavaVirtualMachines/your-java-version)

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

4

मैं जावा सहित हाल ही में बहुत सारे सामान को एकीकृत कर रहा हूं। सबसे मजबूत तरीका जो मैंने पाया है वह है IKVM और C # रैपर का उपयोग करना।

IKVM में एक छोटा सा अनुप्रयोग है जो आपको किसी भी जावा JAR को लेने की अनुमति देता है, और इसे सीधे .Net DLL में बदल देता है। यह बस JVM bytecode से CLR bytecode का अनुवाद करता है। देखें http://sourceforge.net/p/ikvm/wiki/Ikvmc/ जानकारी के लिए।

परिवर्तित लाइब्रेरी केवल मूल C # लाइब्रेरी की तरह व्यवहार करती है, और आप इसका उपयोग JVM की आवश्यकता के बिना कर सकते हैं। आप तब C # DLL आवरण प्रोजेक्ट बना सकते हैं, और परिवर्तित DLL के लिए एक संदर्भ जोड़ सकते हैं।

अब आप कुछ रैपर स्टब्स बना सकते हैं जो उन तरीकों को कहते हैं जिन्हें आप उजागर करना चाहते हैं, और उन तरीकों को DllEport के रूप में चिह्नित करते हैं। देखें https://stackoverflow.com/a/29854281/1977538 जानकारी के लिए।

रैपर डीएलएल एक देशी सी लाइब्रेरी की तरह ही काम करता है, एक्सपोर्टेड तरीकों की तरह ही एक्सपोर्टेड सी मेथड होता है। आप हमेशा की तरह ctype का उपयोग करके उनसे कनेक्ट कर सकते हैं।

मैंने इसे पायथन 2.7 के साथ आज़माया है, लेकिन इसे 3.0 के साथ भी काम करना चाहिए। विंडोज और लिनक्स पर काम करता है

यदि आप C # का उपयोग करते हैं, तो यह संभवतः सबसे अच्छा तरीका है, जब लगभग किसी भी चीज़ को अजगर में एकीकृत करने का प्रयास किया जाता है।


1
उह… तुमने मुझे # सी पर खो दिया। मैं नीचे नहीं उतरूंगा क्योंकि यह कुछ मामलों के लिए एक व्यवहार्य संभावना है, लेकिन यह निश्चित रूप से विंडोज और बहुत सारे अन्य सामान को मानता है।
जारेड

2

मैं अभी JPype 0.5.4.2 (जुलाई 2011) का उपयोग करना शुरू कर रहा हूं और ऐसा लग रहा है कि यह अच्छी तरह से काम कर रहा है ...
मैं Xubuntu 10.04 पर हूं


1

मैं मान रहा हूं कि यदि आप C ++ से जावा तक प्राप्त कर सकते हैं तो आप सभी तैयार हैं। मैंने उस तरह का उत्पाद देखा है जिसका आप अच्छी तरह से उल्लेख करते हैं। जैसा कि होता है कि हमने जो कोडमेश का इस्तेमाल किया था । मैं विशेष रूप से इस विक्रेता का समर्थन नहीं कर रहा हूं, या उनके उत्पाद की रिश्तेदार गुणवत्ता के बारे में कोई बयान नहीं दे रहा हूं, लेकिन मैंने इसे काफी उच्च मात्रा परिदृश्य में काम करते देखा है।

मैं आमतौर पर कहूंगा कि यदि संभव हो तो मैं जेएनआई के माध्यम से प्रत्यक्ष एकीकरण से दूर रखने की सलाह दूंगा यदि आप कर सकते हैं। कुछ सरल REST सेवा दृष्टिकोण, या कतार-आधारित वास्तुकला विकसित और निदान के लिए सरल हो जाएगी। यदि आप इस तरह की डिकॉउंडेड तकनीकों का सावधानीपूर्वक उपयोग करते हैं तो आप काफी सभ्य पूर्णता प्राप्त कर सकते हैं।


RPC (या REST) ​​मेरे लिए कोई विकल्प नहीं है।
डेविड पोर्टाबेला

इससे पहले जावा प्रक्रिया शुरू करने की आवश्यकता होगी, और यह सुनिश्चित करें कि यह अजगर का उपयोग करने से पहले चल रहा है। यह विफलता का एक संभावित बिंदु है। JPype का दृष्टिकोण उत्कृष्ट है; केवल यह कि यह एक मृत परियोजना लगती है।
डेविड पोर्टाबेला

मैं सामान्य सलाह दे रहा हूं। जेएनआई एक संभावित खान क्षेत्र है।
djna

0

अपने स्वयं के अनुभव के माध्यम से अजगर के भीतर से कुछ जावा कोड को चलाने की कोशिश कर रहा हूं कि अजगर में जावा कोड के भीतर अजगर कोड कैसे चलता है, मैं एक सीधे आगे की कार्यप्रणाली को खोजने में असमर्थ था।

मेरी समस्या का समाधान उचित संकुल और चर के साथ एक अस्थायी फ़ाइल में जावा कोड को संपादित करने के बाद मेरे अजगर कोड के भीतर से एक शेल कॉम्नैड के रूप में कॉलशेल दुभाषिए को कॉल करके इस जावा कोड को सेमशेल स्क्रिप्ट के रूप में चला रहा था।

अगर मैं जिस बारे में बात कर रहा हूं वह किसी भी तरह से सहायक है, तो मुझे अपने समाधानों के अधिक विवरण साझा करने में मदद करने में खुशी होगी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.