Search code examples
pythonjavajava-native-interfacenativejava-native-library

Is it possible to make a native in pure Java using python?


Using JNI, or Java Native Interface, it is possible to use c++/c types and functions in Java. I want to do something similar with Python. There are many libraries for executing Python code from Java such as Jython, but I don't want to use any libraries.

Technically, a dll file is just compiled machine code, so if c/c++ can be compiled into that, then so can Python. Is it possible to use types and functions from Python using Java's built-in native interface? Here is an example of what I'm trying to accomplish:

In Python: (A file called hello.py)

import math

class ATestClass:
    def run_something_very_important(self, a: float, b: float) -> float:
        print("Hello!")
        return math.cos(a * b)

The resulting DLL file would be hello.dll

And then this would be the code in Java: (In a file called hello.java)

public class hello {
    public native float run_something_very_important(float a, float b);

    static {
        System.loadLibrary("hello.dll");
    }
}

Solution

  • The problem is libraries. Languages like java and python are designed for a 'batteries included' mode -- the entire stack is fundamentally designed based on the idea that the entire infrastructure and core library set is just there. For example, in java (and python is similar), even a one-liner System.out.println("Hello, World!") app loads in a whole heap of I/O control systems, loads in a pluggable framework system in order to then use this to query the classpath for available charsets, and has a charset support system just to render that string. In the big picture, considering we live in 2021 and your average computer is literally capable of executing in a single second what a million Commodore 64 computers could calculate in an entire day - this is sensible. We DO have room to have a system that can render strings written in various languages, instead of making computers that do not and never really can be made to work in a place that doesn't share an alphabet with what it shipped with.

    That notion (of 'standing on the shoulders of giants') is pretty much baked right into these platforms.

    Therefore, 'translating' a python one-liner that just prints a string into a DLL that is tiny and doesn't also encode half of the python standard lib stack just is not available. It's not really impossible, but it is quite difficult (requires rewriting pretty much every core lib into something stand-alone), and seems mostly useless: That's not going to actually make stuff any faster, and it is pretty much guaranteed to not actually act like proper up-to-spec java or python: That kind of code won't really support the various features that python or java does have out of the box. It's that or have extremely (hard-AI level) intelligent code that figures out precisely that the code you wrote doesn't rely on these more advanced features and therefore one can fathom a fairly simplistic batch of C/machine code that doesn't rely on complicated libraries at all - and this compiler would be capable of producing it if available. Point is: Incredibly difficult to do that correctly.

    The 'cost' to make such a tool is incredibly high. The benefits are tiny. Why in the blazes do you want to 'avoid' libraries? Yes, it SEEMS to us humans utterly stupid to demand a full megabyte of 'libraries' just to print 'Hello!' - that's the total memory capability of 16 Commodore 64s!!! - but the amount of coffee you waste simply by spilling a grain of it on your countertop would seem equally incredibly stupid to an ant. You aren't an ant, and that computer of yours aint a C64. Wasting a megabyte on a pointless library Just. Does. Not. Matter. It's like peeing in the ocean near The Hague and concluding that this must be raising the ocean level in Long Island. Sure, yeah. Technically. You'll never be able to measure it and it is beyond nuts to worry about that sort of thing.

    Conclusion: Folks who know their stuff is required to build such a complicated tool. Because they know their stuff, they know that whole 'depends on a few libraries' thing just doesn't add up to anything relevant, and so they won't bother doing that.

    Real-Time java and GraalVM are probably the closest attempts in the java world to convert java code into stuff that will run in reliable C-style simplistic, machine-code-translatable chunks.

    There are also languages that aren't java or python but copy most of the syntax of java or python which are intended to run on extremely simple stuff. In the distant past, java had different 'profiles' (defining behaviours you could rely on, core library availability, and a few other things), notably including a micro-profile for running on at-the-time tiny candybar phones and smartcards and the like, but that part of java seems to have mostly died out (yup, what you want is something very few people seem to be interested in, unfortunately). I'm not aware of any such libraries for python though.

    TL;DR: Nope, doesn't exist, never will. You're worrying about the wrong thing.