python jython distribution executable-jar

¿Distribuir mis scripts de Python como archivos JAR con Jython?



distribution executable-jar (4)

El comando ''jythonc'' debería ser capaz de compilar su fuente .py en código de byte JVM, lo que debería hacer que sea portátil para cualquier instalación de Java. O al menos leo en: http://hell.org.ua/Docs/oreilly/other2/python/0596001886_pythonian-chp-25-sect-3.html

He sido programador de Python durante casi dos años, y estoy acostumbrado a escribir pequeños guiones para automatizar algunas tareas repetitivas que tenía que hacer en la oficina. Ahora, aparentemente mis colegas notaron esto, y quieren esos guiones también.

Algunos de ellos tienen Mac, algunos Windows; Hice estos en Windows. Investigué la posibilidad de usar py2exe o incluso py2app para hacer nativos de mi script, pero nunca me satisfizo ...

Llegué a saber que todos ellos tienen JVM en sus sistemas, entonces ¿puedo darles un solo archivo JAR ejecutable de mi script utilizando algo como Jython?

¿Qué tan factible es esto? Quiero decir, no tenía idea de cómo escribir guiones para Jython, tampoco me importaba cuando los escribí ... ¿qué tipo de problemas le darán?


Experimenté un problema similar al querer crear simples llamadas de línea de comandos para mis aplicaciones jython, no requerir que el usuario pase por el proceso de instalación de jython, y poder hacer que las secuencias de comandos jython anexen dependencias de biblioteca en tiempo de ejecución a sys .path para incluir código core java.

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

Al ejecutar el iniciador ''jython'' explícitamente en la línea de comandos, en los sistemas Unix, simplemente ejecuta un gran script de shell para formar correctamente una llamada de línea de comando java. Este lanzador de jython parece tener una dependencia en llegar a una instalación central de jython, y de alguna forma de magia permite el manejo apropiado de los archivos .jar agregados a sys.path en tiempo de ejecución desde mis scripts .py. Puede ver cuál es la llamada y bloquear la ejecución de la siguiente manera:

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

Pero todavía es solo encender una JVM y ejecutar un archivo de clase. Así que mi objetivo era poder hacer esta llamada java a un jython.jar independiente presente en el directorio lib de mi distribución para que los usuarios no tengan que hacer ningún paso de instalación adicional para comenzar a usar mis utilidades con scripts .py.

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

El problema es que el comportamiento es lo suficientemente diferente como para obtener respuestas como esta:

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

Ahora podría decir que debería simplemente agregar los archivos jar a -classpath, que de hecho lo intenté, pero obtendría el mismo resultado.

La sugerencia de agrupar todos tus archivos .class en jython.jar no me pareció nada atractiva. Sería un desastre y uniría la aplicación híbrida de Java / Python con la distribución de jython. Entonces esa idea no iba a volar. Finalmente, después de muchas búsquedas, me encontré con el error # 1776 en jython.org, que ha sido catalogado como crítico durante un año y medio, pero no veo que las últimas actualizaciones de jython incorporen una solución. Aún así, si tiene problemas para que jython incluya sus archivos jar por separado, debe leer esto.

http://bugs.jython.org/issue1776

Allí, encontrará la solución temporal para esto. En mi caso, tomé el archivo jar de POI de Apache y lo descomprimí en su propio directorio lib y luego modifiqué la entrada sys.path para apuntar al directorio en lugar de al jar:

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

Ahora, cuando ejecuto jython por medio de java, haciendo referencia a mi jython.jar local, la utilidad se ejecuta solo en color melocotón. Ahora puedo crear scripts simples o archivos por lotes para hacer una experiencia de línea de comandos perfecta para mis utilidades .py, que el usuario puede ejecutar sin ningún otro paso de instalación.


Las mejores técnicas actuales para distribuir sus archivos de Python en un contenedor se detallan en este artículo en el wiki de Jython: http://wiki.python.org/jython/JythonFaq/DistributingJythonScripts

Para su caso, creo que le gustaría tomar el archivo jython.jar que obtiene cuando instala Jython y comprime el directorio Jython Lib, luego comprime tus archivos .py y luego agrega un archivo __run__.py con tu lógica de inicio (este archivo es tratado especialmente por Jython y será el archivo ejecutado cuando llame al jar con "java -jar").

Este proceso es definitivamente más complicado de lo que debería ser, por lo que (los desarrolladores de Jython) necesitamos encontrar una buena herramienta que automatice estas tareas, pero por ahora estos son los mejores métodos. A continuación estoy copiando la receta en la parte inferior del artículo anterior (modificado ligeramente para adaptarse a la descripción de su problema) para darle una idea de la solución.

Crea el jar básico

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

Agregue otros módulos al contenedor:

$ 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

Agregue el módulo __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

En MS Windows, esa última línea, establecer la variable de entorno CLASSPATH, se vería así:

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

O, nuevamente en MS Windows, use el Panel de control y las propiedades del sistema para establecer la variable de entorno CLASSPATH.

Ejecuta la aplicación:

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

O bien, si ha agregado el script de inicio al contenedor, use uno de los siguientes:

$ 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

El doble-jar es un poco molesto, así que si quieres evitar eso y obtener el más agradable:

$ java -jar myapp.jar arg1

Tendrás que trabajar un poco más hasta que obtengamos algo como esto en un futuro Jython [Actualización: JarRunner es parte de Jython 2.5.1]. Aquí hay un código Java que busca el __run__.py automáticamente y lo ejecuta. Tenga en cuenta que este es mi primer intento en esta clase. ¡Avíseme si necesita una mejora!

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); } }

Puse este código en el paquete org.python.util, ya que es donde iría si decidimos incluirlo en un futuro Jython. Para compilarlo, deberá poner jython.jar (o su myapp.jar) en classpath como:

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

Luego necesitará agregar JarRunner.class a su jar (el archivo de clase deberá estar en org / python / util / JarRunner.class). Jar de llamada en el directorio "org" obtendrá la ruta completa en su jar.

$ jar uf org

Agregue esto a un archivo que usará para actualizar el manifiesto, un buen nombre es manifest.txt:

Main-Class: org.python.util.JarRunner

Luego actualiza el manifiesto del jar:

$ jar ufm myapp.jar manifest.txt

Ahora debería poder ejecutar su aplicación de esta manera:

$ java -jar myapp.jar


Para distribuir sus scripts Python de una manera que no requiera una instalación nativa de Python, también puede probar Nuitka , que básicamente traduce su código Python a código C ++, que luego se compila en un binario nativo verdadero.