Program Club

Jython을 사용하여 Python 스크립트를 JAR 파일로 배포합니까?

proclub 2021. 1. 8. 20:47
반응형

Jython을 사용하여 Python 스크립트를 JAR 파일로 배포합니까?


저는 거의 2 년 동안 Python 프로그래머로 일했으며 사무실에서해야하는 반복적 인 작업을 자동화하기 위해 작은 스크립트를 작성하는 데 익숙합니다. 제 동료들은이 사실을 알아 차렸고 그 스크립트도 원합니다.

그들 중 일부는 Mac, 일부 Windows; 나는 이것을 창문에 만들었다. py2exe 또는 py2app을 사용하여 내 스크립트의 네이티브를 만들 가능성을 조사했지만 결코 만족하지 못했습니다.

나는 그들 모두가 그들의 시스템에 JVM을 가지고 있다는 것을 알게 되었기 때문에 자이 썬과 같은 것을 사용하여 내 스크립트의 단일 실행 가능한 JAR 파일을 그들에게 줄 수 있습니까?

이것이 얼마나 타당한가 ... 내 말은, 나는 자이 썬을위한 스크립트를 작성하는 방법을 몰랐고, 내가 그것들을 작성할 때 신경 쓰지 않았다는 것을 의미한다 ... 어떤 종류의 문제를 줄 것인가?


Jar에 Python 파일을 배포하는 최신 기술은 Jython 위키의이 기사에 자세히 설명되어 있습니다. http://wiki.python.org/jython/JythonFaq/DistributingJythonScripts

귀하의 경우에는 Jython을 설치할 때 얻은 jython.jar 파일을 가져 와서 Jython Lib 디렉토리를 압축 한 다음 .py 파일을 압축 한 다음 __run__.py시작 논리가 있는 파일 을 추가하고 싶을 것입니다 ( 이 파일은 Jython에 의해 특별히 처리되며 "java -jar"로 jar를 호출 할 때 실행되는 파일이됩니다.

이 프로세스는 당연한 것보다 확실히 더 복잡하므로 우리 (자이 썬 개발자)는 이러한 작업을 자동화 할 멋진 도구를 찾아야하지만 지금은 이것이 최고의 방법입니다. 아래에서는 위의 기사 하단에있는 레시피 (문제 설명에 맞게 약간 수정 됨)를 복사하여 솔루션을 이해합니다.

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

이중 항아리는 다소 성가신 것이므로 그것을 피하고 더 즐겁게 얻으려면 다음을 수행하십시오.

$ java -jar myapp.jar arg1

우리가 미래의 자이 썬 (Jython 2.5.1의 일부인 업데이트 : JarRunner)에서 이와 같은 것을 얻을 때까지 좀 더 많은 작업을해야 할 것입니다. 다음은 __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.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

Add this to a file that you will use to update the manifest, a good name is manifest.txt:

Main-Class: org.python.util.JarRunner

Then update the jar's manifest:

$ jar ufm myapp.jar manifest.txt

Now you should be able to run your app like this:

$ java -jar myapp.jar

I experienced a similar issue in that I want to be able to create simple command line calls for my jython apps, not require that the user go through the jython installation process, and be able to have the jython scripts append library dependencies at runtime to sys.path so as to include core java code.

# 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"))

When running the 'jython' launcher explicitly on the command line, on Unix systems, it just runs a big shell script to properly form a java command line call. This jython launcher seems to have a dependency on reaching back to a core install of jython, and by some way of magic allows the proper handling of .jar files being added to the sys.path at runtime from within my .py scripts. You can see what the call is and block execution by the following:

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

But it's still just firing up a JVM and running a class file. So my goal was to be able to make this java call to a standalone jython.jar present in my distribution's lib directory so users would not need to do any additional installation steps to start using my .py scripted utilities.

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

Trouble is that the behavior is enough different that I would get responses like this:

  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

Now you might say that I should just add the jar files to the -classpath, which in fact I tried, but I would get the same result.

The suggestion of bundling all of your .class files in a jython.jar did not sound appealing to me at all. It would be a mess and would bind the Java/Python hybrid application too tightly to the jython distribution. So that idea was not going to fly. Finally, after lots of searching, I ran across bug #1776 at jython.org, which has been listed as critical for a year and a half, but I don't see that the latest updates to jython incorporate a fix. Still, if you're having problems with having jython include your separate jar files, you should read this.

http://bugs.jython.org/issue1776

In there, you will find the temporary workaround for this. In my case, I took the Apache POI jar file and unjar'ed it into its own separate lib directory and then modified the sys.path entry to point to the directory instead of the jar:

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

Now, when I run jython by way of java, referencing my local jython.jar, the utility runs just peachy. Now I can create simple scripts or batch files to make a seamless command line experience for my .py utilities, which the user can run without any additional installation steps.


The 'jythonc' command should be able to compile your .py source into JVM bytecode, which should make it portable to any Java install. Or so I read at: http://hell.org.ua/Docs/oreilly/other2/python/0596001886_pythonian-chp-25-sect-3.html


For distributing your Python scripts in a way that doesn't require a native Python installation, you could also try Nuitka, which basically translates your Python code to C++ code, which is then compiled to a true native binary.

ReferenceURL : https://stackoverflow.com/questions/1252965/distributing-my-python-scripts-as-jar-files-with-jython

반응형