Python to a single Java Jar using Jython


Why?

My preferred language is Python, but I need to use a Java library. I need to application to run on other machines that does not have Jython installed. The below steps will generate a JAR version of your python file. (check the reference below for more info)

Assumptions:

-You have java installed
-You have java accessible via terminal (PATH is correct)
-You have jython installed
-You have jython accessible via terminal (PATH is correct)
-You are running Unix/Linux

Steps:

1. Start with a fresh directory (e.g. ws)
2. copy your python file here (the python program that you want to convert to jar, we will name it my_prog.py)
3. create a file and name it Main.java
4. copy the java code below to the Main.java file
5. In the terminal, go your directory (ws) using the command cd.
6. create a new file and name it entrypoint.py
7. type the below in the entrypoint.py file and save
from my_prog import main
8. Execute the below commands in the terminal (one by one)

$ mkdir Package
$ cd Package
$ cp -r $JYTHON_HOME/Lib .
$ unzip $JYTHON_HOME/jython.jar
$ # add your modules to Lib
$ javac ../Main.java -d .
$ cp ../entrypoint.py .
$ cp ../my_prog.py . 
$ jar -cfe output.jar Main *

9. Now you have your jar version of your program ready, type the below to execute
$ java -jar output.jar 

Main.java

import java.io.FileInputStream;
import java.lang.System;
import java.util.Properties;

import org.python.core.Py;
import org.python.core.PyException;
import org.python.core.PyFile;
import org.python.core.PySystemState;
import org.python.util.JLineConsole;
import org.python.util.InteractiveConsole;
import org.python.util.InteractiveInterpreter;

public class Main {
    private static InteractiveConsole newInterpreter(boolean interactiveStdin) {
        if (!interactiveStdin) {
            return new InteractiveConsole();
        }

        String interpClass = PySystemState.registry.getProperty(
        "python.console", "");
        if (interpClass.length() > 0) {
            try {
                return (InteractiveConsole)Class.forName(
            interpClass).newInstance();
            } catch (Throwable t) {
                // fall through
            }
        }
        return new InteractiveConsole();//different than the source    }

    public static void main(String[] args) throws PyException {
        PySystemState.initialize(
            PySystemState.getBaseProperties(), 
            new Properties(), args);

        PySystemState systemState = Py.getSystemState();
        // Decide if stdin is interactive
        boolean interactive = ((PyFile)Py.defaultSystemState.stdin).isatty();
        if (!interactive) {
            systemState.ps1 = systemState.ps2 = Py.EmptyString;
        }

        // Now create an interpreter
        InteractiveConsole interp = newInterpreter(interactive);
        systemState.__setattr__("_jy_interpreter", Py.java2py(interp));
        interp.exec("try:\n import entrypoint\n entrypoint.main()\nexcept SystemExit: pass");
    }
}


Reference:

https://wiki.python.org/jython/JythonFaq/DistributingJythonScripts#How_can_others_use_scripts.2Fapplications_I.27ve_developed.3F 

Comments

Popular Posts