2009-08-10 12 views
53

मैं लगभग दो साल के लिए एक अजगर प्रोग्रामर किया गया है, और मैं कुछ दोहराए जाने वाले कार्यों मैं कार्यालय में करना था स्वचालित करने के लिए छोटा सा स्क्रिप्ट लिखने के लिए प्रयोग किया जाता रहा हूँ। अब, स्पष्ट रूप से मेरे सहयोगियों ने यह देखा, और वे उन स्क्रिप्ट को भी चाहते हैं।Jython के साथ जार फ़ाइलों के रूप में मेरी पाइथन स्क्रिप्ट वितरित किया जा रहा?

उनमें से कुछ Mac, कुछ Windows है; मैंने इन्हें खिड़कियों पर बनाया है। मैं py2exe या यहाँ तक कि py2app का उपयोग कर मेरी स्क्रिप्ट के मूल निवासी बनाने के लिए की संभावना की जांच की, लेकिन उन्होंने मुझे संतुष्ट कभी नहीं ...

मुझे पता है कि उन सभी को अपने सिस्टम पर JVM है आया, तो मैं उन्हें एक ही दे सकते हैं ज्योथन जैसे कुछ का उपयोग कर मेरी लिपि की निष्पादन योग्य जेएआर फ़ाइल हो सकती है?

यह कितना व्यवहार्य है ... मेरा मतलब है, मुझे नहीं पता था कि ज्योथन के लिए लिपियों को कैसे लिखना है, न ही जब मैंने उन्हें लिखा था तो मुझे इसकी परवाह नहीं थी ... यह किस तरह की समस्याएं देगा?

उत्तर

65

एक जार में अपने अजगर फ़ाइलों के वितरण के लिए सबसे अच्छा वर्तमान तकनीकों Jython के विकि पर इस लेख में विस्तृत कर रहे हैं: http://wiki.python.org/jython/JythonFaq/DistributingJythonScripts

अपने मामले के लिए, मुझे लगता है कि आप Jython लेने के लिए चाहते हो जाएगा .jar फ़ाइल है कि आप जब आप Jython स्थापित हो और Jython लिब निर्देशिका ज़िप में है, तो अपनी .py फ़ाइलें ज़िप, और उसके बाद अपने स्टार्टअप तर्क के साथ एक __run__.py फ़ाइल जोड़ने (इस फ़ाइल Jython द्वारा विशेष रूप से इलाज किया जाता है और फ़ाइल हो जाएगा जब आप जार को "जावा -जर" के साथ बुलाते हैं तो निष्पादित)।

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

$ cd $JYTHON_HOME 
$ cp jython.jar jythonlib.jar 
$ zip -r jythonlib.jar Lib 

जार करने के लिए अन्य मॉड्यूल जोड़ें::

$ cd $MY_APP_DIRECTORY 
$ cp $JYTHON_HOME/jythonlib.jar myapp.jar 
$ zip myapp.jar Lib/showobjs.py 
# Add path to additional jar file. 
$ jar ufm myapp.jar othermanifest.mf 

__run__.py मॉड्यूल जोड़ें:

बुनियादी जार बनाएं

# Copy or rename your start-up script, removing the "__name__ == '__main__'" check. 
$ cp mymainscript.py __run__.py 
# Add your start-up script (__run__.py) to the jar. 
$ zip myapp.jar __run__.py 
# Add path to main jar to the CLASSPATH environment variable. 
$ export CLASSPATH=/path/to/my/app/myapp.jar:$CLASSPATH 

एमएस विंडोज, कि अंतिम पंक्ति, क्लास्स्पैट पर्यावरण परिवर्तक को सेट करना, ऐसा कुछ दिखाई देगा:

set CLASSPATH=C:\path\to\my\app\myapp.jar;%CLASSPATH% 

या, एमएस विंडोज पर फिर से, नियंत्रण कक्ष और सिस्टम गुण CLASSPATH वातावरण चर सेट करने के लिए इस्तेमाल करते हैं।

आवेदन चलाएँ:

$ java -jar myapp.jar mymainscript.py arg1 arg2 

या, यदि आप जार करने के लिए अपने स्टार्ट-अप स्क्रिप्ट को शामिल किया है, निम्न में से एक का उपयोग करें:

$ java org.python.util.jython -jar myapp.jar arg1 arg2 
$ java -cp myapp.jar org.python.util.jython -jar myapp.jar arg1 arg2 
$ java -jar myapp.jar -jar myapp.jar arg1 arg2 

डबल जार तरह का है कष्टप्रद है, तो आप उस से बचने और प्राप्त करना चाहते हैं, तो अधिक मनभावन:

$ java -jar myapp.jar arg1 

आप में कुछ अधिक परिश्रम unt करना होगा आईएल हमें भविष्य में ज्योथन में ऐसा कुछ मिलता है [अपडेट: जाररुनर ज्योथन 2.5.1 का हिस्सा है]। यहां कुछ जावा कोड है जो __run__.py स्वचालित रूप से देखता है, और इसे चलाता है। ध्यान दें कि यह इस कक्षा में मेरी पहली कोशिश है। अगर मुझे सुधार की ज़रूरत है तो मुझे बताएं!

package org.python.util; 

import org.python.core.imp; 
import org.python.core.PySystemState; 

public class JarRunner { 

    public static void run(String[] args) { 
     final String runner = "__run__"; 
     String[] argv = new String[args.length + 1]; 
     argv[0] = runner; 
     System.arraycopy(args, 0, argv, 1, args.length); 
     PySystemState.initialize(PySystemState.getBaseProperties(), null, argv); 
     imp.load(runner); 
    } 

    public static void main(String[] args) { 
     run(args); 
    } 
} 

मैं org.python.util पैकेज में इस कोड डाल दिया, के बाद से है कि अगर हम एक भविष्य Jython में शामिल करने का फैसला जहां यह जाना होगा। यह संकलन करने के लिए, आप की तरह classpath में jython.jar (या अपने myapp.jar) डाल करने के लिए की आवश्यकता होगी:

$ javac -classpath myapp.jar org/python/util/JarRunner.java 

तो फिर आप अपने जार (वर्ग फ़ाइल को JarRunner.class जोड़ने की आवश्यकता होगी होगा ऑर्ग/पायथन/उपयोग/जाररुनर.क्लास में होने की आवश्यकता है) "संगठन" निर्देशिका पर जार को कॉल करने से आपके जार में पूरा रास्ता मिल जाएगा।

$ jar uf org 

एक फ़ाइल है कि आप प्रकट अद्यतन करने के लिए उपयोग करेगा करने के लिए इस जोड़ें, एक अच्छा नाम manifest.txt है: अब

$ jar ufm myapp.jar manifest.txt 

:

Main-Class: org.python.util.JarRunner 

फिर जार के मेनिफ़ेस्ट अपडेट आपको अपना ऐप इस तरह चलाने में सक्षम होना चाहिए:

$ java -jar myapp.jar 
+0

हे फ्रैंक की सराहना की कोई मदद, अंतर्दृष्टि के लिए धन्यवाद, वास्तव में .. एक बात, मुझे कमांड में एक त्रुटि मिल रही है "ज़िप मैप .jar Lib/showobjs.py ".. यह क्या करना चाहिए? –

+0

जाहिर है, मेरी लिपि कुछ भी करने से पहले ज्योथन दुभाषिया को बुलाया जाना चाहिए .. जो मुझे बताता है कि मेरी पाइथन लिपि चलाने के लिए "जावा -जर MyScript.jar" संभव नहीं है। धन्यवाद फ्रैंक! –

+0

आपको चीजों को सेट करने में सक्षम होना चाहिए ताकि "जावा -जर MyScript.jar" काम करना चाहिए। बाद में आज मैं एक और ठोस उदाहरण बनाने के लिए अपने कदमों को संपादित करूंगा। –

1

'jythonc' कमांड JVM बाईटकोड में अपने .py स्रोत संकलित करने के लिए है, जो यह पोर्टेबल किसी भी जावा स्थापित करने के लिए करना चाहिए सक्षम होना चाहिए। या तो मैंने पढ़ा है पर: http://hell.org.ua/Docs/oreilly/other2/python/0596001886_pythonian-chp-25-sect-3.html

+3

लिंक के लिए धन्यवाद .. मुझे jythonc के बारे में पता नहीं था, लेकिन मुझे यह जानने के लिए हुआ कि jythonc अब और नहीं बनाए रखा गया है ... http://www.jython.org/archive/22/jythonc.html I जार बनाने के लिए ज्योथन कमांड का उपयोग करने के तरीके के बारे में कोई मदद नहीं मिली ... –

2

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

# append Java library elements to path 
sys.path.append(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "lib", "poi-3.8-20120326.jar")) 

जब कमांड लाइन पर स्पष्ट रूप से 'Jython' लांचर चल रहा है, यूनिक्स सिस्टम पर, यह सिर्फ एक बड़ा खोल स्क्रिप्ट ठीक से एक जावा कमांड लाइन कॉल के रूप में चलाता है। इस ज्योथन लॉन्चर को ज्योथन के मूल इंस्टॉल पर वापस आने पर निर्भरता प्रतीत होती है, और जादू के किसी भी तरीके से .jar फ़ाइलों को मेरी .py स्क्रिप्ट के भीतर से रनटाइम पर sys.path में जोड़ा जा रहा है। आप क्या कॉल और ब्लॉक निष्पादन देख सकते हैं का पालन करते हुए:

jython --print run_form.py 
java -Xmx512m -Xss1024k -Dfile.encoding=UTF-8 -classpath /Applications/jython2.5.2/jython.jar: -Dpython.home=/Applications/jython2.5.2 -Dpython.executable=/Applications/jython2.5.2/bin/jython org.python.util.jython run_form.py 

लेकिन यह अभी भी सिर्फ एक JVM ऊपर फायरिंग और एक वर्ग फ़ाइल चल रहा है। तो मेरा लक्ष्य था कि इस जावा कॉल को एक स्टैंडअलोन jython.jar में मेरे वितरण की lib निर्देशिका में प्रस्तुत करने में सक्षम होना था ताकि उपयोगकर्ताओं को मेरी .py स्क्रिप्ट वाली उपयोगिताओं का उपयोग शुरू करने के लिए कोई अतिरिक्त स्थापना चरण करने की आवश्यकता नहीं होगी।

java -Xmx512m -Xss1024k -classpath ../../lib/jython.jar org.python.util.jython run_form.py 

मुसीबत है कि व्यवहार काफी अलग है कि मैं इस तरह की प्रतिक्रियाएं मिलेगा है:

File "run_form.py", line 14, in <module> 
    import xls_mgr 
    File "/Users/test/Eclipse/workspace/test_code/py/test/xls_mgr.py", line 17, in <module> 
    import org.apache.poi.hssf.extractor as xls_extractor 
ImportError: No module named apache 

अब आप कह सकते हैं कि मैं तो बस, -classpath को जार फ़ाइलों जोड़ना चाहिए जो वास्तव में मैंने कोशिश की, लेकिन मुझे एक ही परिणाम मिल जाएगा।

jython.jar में आपकी सभी .class फ़ाइलों को बंडल करने का सुझाव मुझे बिल्कुल आकर्षक नहीं था। यह एक गड़बड़ होगी और जावा/पायथन हाइब्रिड एप्लिकेशन को ज्योथन वितरण के लिए बहुत कसकर बांध देगा। तो वह विचार उड़ने वाला नहीं था। अंत में, बहुत सारी खोज के बाद, मैं jython.org पर बग # 1776 में भाग गया, जिसे डेढ़ साल तक महत्वपूर्ण के रूप में सूचीबद्ध किया गया है, लेकिन मुझे नहीं लगता कि ज्योथन के नवीनतम अपडेट एक फिक्स शामिल करते हैं। फिर भी, यदि आपको ज्योथन रखने में समस्याएं हैं तो अपनी अलग जार फाइलें शामिल करें, आपको इसे पढ़ना चाहिए।

http://bugs.jython.org/issue1776

वहाँ में, आप इस के लिए अस्थायी समाधान मिल जाएगा। मेरे मामले में, मैं Apache POI जार फ़ाइल लिया और अपनी अलग lib निर्देशिका में unjar'ed और उसके बाद जार के बजाय निर्देशिका के लिए बात करने के लिए sys.path प्रविष्टि संशोधित:

sys.path.append('/Users/test/Eclipse/workspace/test_code/lib/poi_lib') 

अब, जब मैं जावा के माध्यम से ज्योथन चलाता हूं, मेरे स्थानीय jython.jar का संदर्भ देता हूं, उपयोगिता केवल peachy चलाता है। अब मैं अपनी .py उपयोगिताओं के लिए एक निर्बाध कमांड लाइन अनुभव बनाने के लिए सरल स्क्रिप्ट या बैच फ़ाइलों को बना सकता हूं, जो उपयोगकर्ता बिना किसी अतिरिक्त स्थापना चरणों के चला सकते हैं।

+0

यह एक अच्छा पोस्ट है, आपके अनुभव और ज्ञान को साझा करने के लिए धन्यवाद। मैं ज्योथन के साथ भी काम कर रहा हूं और आपके जैसी ही समस्याएं अनुभव कर रहा हूं। (+1) – Eder

0

अपनी पायथन स्क्रीप्ट को ऐसे तरीके से वितरित करने के लिए जिसकी मूल पायथन स्थापना की आवश्यकता नहीं है, आप Nuitka भी कोशिश कर सकते हैं, जो मूल रूप से आपके पायथन कोड को C++ कोड में अनुवादित करता है, जिसे तब एक वास्तविक मूल बाइनरी में संकलित किया जाता है।