58

私はほぼ 2 年間 Python プログラマーを務めており、オフィスで行わなければならなかったいくつかの反復タスクを自動化するための小さなスクリプトを作成することに慣れています。さて、明らかに私の同僚はこれに気づき、それらのスクリプトも欲しがっています。

それらのいくつかには Mac があり、いくつかには Windows があります。私は窓でこれらを作りました。py2exe または py2app を使用してスクリプトのネイティブを作成する可能性を調査しましたが、満足することはありませんでした...

それらのすべてのシステムに JVM があることがわかったので、Jython のようなものを使用して、私のスクリプトの実行可能な JAR ファイルを 1 つ提供できますか?

これはどれほど実現可能でしょうか...つまり、Jythonのスクリプトの書き方がわかりませんでしたし、書いたときも気にしませんでした...どのような問題が発生しますか?

4

4 に答える 4

66

Python ファイルを jar で配布するための現在の最適な手法については、Jython の wiki の次の記事で詳しく説明しています: http://wiki.python.org/jython/JythonFaq/DistributingJythonScripts

あなたの場合、Jython をインストールしたときに取得した jython.jar ファイルを取得し、Jython Lib ディレクトリをその中に圧縮してから、.py ファイルを圧縮してから、__run__.py起動ロジックを含むファイルを追加することをお勧めします (このファイルは Jython によって特別に扱われ、"java -jar" で jar を呼び出したときに実行されるファイルになります)。

このプロセスは、本来あるべきよりも明らかに複雑であるため、私たち (Jython 開発者) は、これらのタスクを自動化する優れたツールを考え出す必要がありますが、現時点ではこれらが最良の方法です。以下では、上記の記事の下部にあるレシピをコピーして (問題の説明に合わせて少し変更しています)、解決策を理解してもらいます。

基本的な jar を作成します。

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

他のモジュールを jar に追加します。

$ 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

MS Windows では、CLASSPATH 環境変数を設定する最後の行は次のようになります。

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

または、再び MS Windows で、コントロール パネルとシステム プロパティを使用して CLASSPATH 環境変数を設定します。

アプリケーションを実行します。

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

または、起動スクリプトを jar に追加した場合は、次のいずれかを使用します。

$ 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

二重の -jar はちょっと面倒なので、それを避けてより快適にしたい場合:

$ java -jar myapp.jar arg1

このようなものが将来の Jython に組み込まれるまで、もう少し作業を行う必要があります [更新: JarRunner は Jython 2.5.1 の一部です]。__run__.pyを自動的に検索して実行する Java コードを次に示します。これがこのクラスでの私の最初の試みであることに注意してください。改善が必要な場合はお知らせください。

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 に含めることを決定した場合にそこに移動するためです。コンパイルするには、jython.jar (または myapp.jar) を次のようにクラスパスに入れる必要があります。

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

次に、JarRunner.class を jar に追加する必要があります (クラス ファイルは org/python/util/JarRunner.class にある必要があります)。「org」ディレクトリで jar を呼び出すと、jar へのパス全体が取得されます。

$ jar uf org

これをマニフェストの更新に使用するファイルに追加します。適切な名前は manifest.txt です。

Main-Class: org.python.util.JarRunner

次に、jar のマニフェストを更新します。

$ jar ufm myapp.jar manifest.txt

これで、次のようにアプリを実行できるはずです。

$ java -jar myapp.jar
于 2009-08-10T14:12:55.217 に答える
2

jython アプリの単純なコマンド ライン呼び出しを作成し、ユーザーが jython インストール プロセスを実行する必要がなく、実行時に jython スクリプトがライブラリの依存関係を sys に追加できるようにするという点で、同様の問題が発生しました。コア Java コードを含めるための .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"))

Unix システムのコマンド ラインで「jython」ランチャーを明示的に実行すると、Java コマンド ライン呼び出しを適切に形成するために大きなシェル スクリプトが実行されるだけです。この jython ランチャーは、jython のコア インストールに戻ることに依存しているようで、何らかの方法で、実行時に .py スクリプト内から sys.path に追加される .jar ファイルを適切に処理できます。呼び出しが何であるかを確認し、次の方法で実行をブロックできます。

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 を起動してクラス ファイルを実行しているだけです。したがって、私の目標は、ディストリビューションの lib ディレクトリにあるスタンドアロンの jython.jar に対してこの Java 呼び出しを実行できるようにすることでした。これにより、ユーザーは、.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

jar ファイルを -classpath に追加するだけでよいとおっしゃるかもしれませんが、実際に試してみましたが、同じ結果が得られました。

すべての .class ファイルを jython.jar にまとめるという提案は、私にはまったく魅力的ではありませんでした。それは混乱を招き、Java/Python ハイブリッド アプリケーションを jython ディストリビューションに強くバインドしすぎます。だから、そのアイデアは飛ぶつもりはありませんでした。最後に、多くの検索を行った結果、jython.org でバグ #1776 を見つけました。これは 1 年半にわたって重大なものとしてリストされていましたが、jython の最新の更新に修正が組み込まれているようには見えません。それでも、jython に別の jar ファイルを含めることに問題がある場合は、これを読む必要があります。

http://bugs.jython.org/issue1776

そこには、これに対する一時的な回避策があります。私の場合、Apache POI jar ファイルを取得し、それを個別の lib ディレクトリに unjar してから、jar ではなくディレクトリを指すように sys.path エントリを変更しました。

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

ここで、ローカルの jython.jar を参照して Java 経由で jython を実行すると、ユーティリティは peachy で実行されます。これで、単純なスクリプトまたはバッチ ファイルを作成して、ユーザーが追加のインストール手順なしで実行できる .py ユーティリティのコマンド ライン エクスペリエンスをシームレスにすることができます。

于 2013-02-15T18:04:39.280 に答える
1

「jythonc」コマンドは、.py ソースを JVM バイトコードにコンパイルできるはずです。これにより、任意の Java インストールに移植可能になります。または、私は次を読みました: http://hell.org.ua/Docs/oreilly/other2/python/0596001886_pythonian-chp-25-sect-3.html

于 2009-08-10T05:47:00.997 に答える
1

ネイティブの Python インストールを必要としない方法で Python スクリプトを配布するには、Nuitkaを試すこともできます。これは、基本的に Python コードを C++ コードに変換し、その後、真のネイティブ バイナリにコンパイルします。

于 2015-04-08T19:00:18.857 に答える