Run java with python

Saved searches

Use saved searches to filter your results more quickly

You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.

License

laffra/pava

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Sign In Required

Please sign in to use Codespaces.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching GitHub Desktop

If nothing happens, download GitHub Desktop and try again.

Launching Xcode

If nothing happens, download Xcode and try again.

Launching Visual Studio Code

Your codespace will open once ready.

There was a problem preparing your codespace, please try again.

Latest commit

Git stats

Files

Failed to load latest commit information.

README.md

Pava loads Java class files, decompiles the bytecodes, and emits Python source. This allows Java code to be executed inside the Python VM.

Pava is a mirror of Jython, with the difference that with Pava, Python is the dominant language, not Java.

Pava converts all the Java bytecodes, including the entire Java runtime in rt.jar, caches the result, and allows the use of Java classes as if they were implemented in Python directly.

Assuming we have a Java example looking like this:

package helloworld public class HelloWorld < public static void main(String[] args) < System.out.println("Hello World!"); >> 

This Java code can be invoked unchanged using Pava as follows:

import helloworld helloworld.HelloWorld.main__java_lang_String____() 

Note the generated signature for the main function. It includes the type names of all the arguments to support method overloading in the Java language.

Of course, the Python VM needs to be instructed where to find the Java class files. This is done by informing pava of the classpath to use:

import pava pava.set_classpath(['. the location of the Java classfiles. ']) 

How does Pava work internally?

Pava execution happens in two phases. In the first phase, before anything really runs, the Java classpath is processed and classfiles are transpiled. During this phase, for each class file found on the classpath, Pava performs the following steps:

  • Load the class file
  • If needed, create a Python module with the same name as the Java package
  • Generate a Python class in the module
  • Add a Python method for each Java method found
  • Transpile each of the Java bytecodes into the corresponding Python source
  • Add a Python class attribute for each Java field found
  • Handle and to properly initialize the Python fields

During phase two, which is really during runtime execution of the code, nothing special really happens:

  • The generated code, which is now regular Python code, is simply executed
  • The Java classloading behavior is mimicked by lazy loading of Python modules and classes

Compilation of HelloWorld

Below is the resulting Python source for the HelloWorld Java program shown above. At the right side, the original Java bytecodes are shown:

1. import java 2. 3. class HelloWorld(java.lang.Object): 4. def __java_init______(self): 5. # 0 aload_0 6. java.lang.Object.__java_init______(self) # 1 invokespecial java.lang.Object.__java_init______() 7. return self # 4 return 8. 9. @classmethod 10. def main__java_lang_String____(cls, a1): 11. # 0 getstatic java.lang.System.out 12. # 3 ldc Hello World 13. java.lang.System.out.println__java_lang_String__('Hello World') 14. # 5 invokevirtual java.io.PrintStream.println__java_lang_String__(java.lang.String) 15. return None # 8 return 

There are a number of noteworthy constructs in this generated Python code:

  • The HelloWorld class is a subclass of java.lang.Object . This relationship is preserved in the generated Python code as well.
  • The default contructor, generated by the Java compiler, is named . That name is converted to __java_init__ to generate a valid Python name. The name also includes a description of the method signature, in this case 4 underscores, representing a void method without arguments.
  • The main method at line 10 is declared as a static method in Java. This equates to a classmethod in Python. Its signature includes the argument types being an array of strings.
  • At line 13, a virtual method called println is invoked on a static field called out , declared by a class called System . In the Java source code, no package name is given for System , as it is defined in the package java.lang . In the generated Python code, packages become modules, classes are defined in a module, and methods are declared on a class the same way Python classes are.
  • Finally, the HelloWorld.main method is a void function. In other words, it does not return anything. In Python, however, all functions return a result, where the default return value is None. This means line 15 could be omitted in the Python code generation step.

Pava is in very early stage of development. Next steps are:

  • Implement the few remaining bytecodes, such as multianewarray
  • Implement do-while loops, which have complicated goto’s in Python bytecodes
  • Handle clinit to properly initialize static fields.
  • Allow dynamic method lookup to support short names for overloaded Java methods.
  • Write more tests for long/double/float/math operations.
  • Run the test suite provided in the openjdk project.

Источник

Integrating Java with Python

While programming in a language, a developer may feel the need to use some functionality that may have better support in another language. For example, suppose, an application has already been developed in Java, and we wish to use it in Python code. To invoke an existing Java application in Python, we need a bridge between Python and Java. Packages like Py4j, Pyjnius, Jpype, javabridge, and JCC help invoke Java programs from Python. Also, since Java provides a wide variety of collections, we can directly use them in a Python program by including their java packages in the program. We will make use of py4j for invoking Java functionality from Python. It can be installed by executing the following command from the command line:

After this, we need to improve the IDE in which we will be writing our code. For example, if we are writing our Java program in Eclipse, we need to include the jar file of py4j in the Java project. It is important to point out that py4j supports Java version 6 and above only. Let us examine a simple Java program HelloClass.java that has a method Message which returns Hello.

To make the GFG accessible in a Python program, two things are required. First, the Python program should be able to access the Java Virtual Machine (JVM) running the Java program. This requires an instance of the GatewayServer class available in the library py4j that makes this communication possible. Secondly, an entry point should be mentioned in the call to the constructor of the class GatewayServer. This entry point can be any object we wish to deal with in a Python program. In our case, an object of GFG serves as an entry point (line 10). Here it is important to mention that a Python program will be able to use a Java program only if it (a Java program) is ready to accept incoming requests. Therefore, in line 11, we start the gateway using the method start, Also, for communication to take place, the Java program must be compiled and executed before the Python program.

Источник

Py4J – мост между Python и Java

Название Py4J можно встретить разве что в списке библиотек, используемых PySpark, но не стоит недооценивать данный инструмент, который обеспечивает совместную работу Python и Java. В этой статье будет кратко описана работа Py4J, рассмотрен пример использования и перечислены сильные и слабые стороны библиотеки. В конце будут описаны альтернативные способы связи Java и Python.

Py4J позволяет программам, работающим в интерпретаторе Python, динамически обращаться к объектам Java внутри JVM. Методы вызываются так, как если бы объекты Java находились в интерпретаторе Python, а доступ к коллекциям Java можно было получить с помощью стандартных методов коллекций Python. Py4J также позволяет программам Java вызывать объекты Python, но на этом возможности библиотеки не заканчиваются. Py4J позволяет создавать из Python классические коллекции Java, а именно Array, List, Set и Map. Также можно конвертировать Python коллекции в Java коллекции. Ещё из Python возможно реализовывать интерфейсы, которые описаны в Java.

Существует несколько альтернатив, например, Jython. В отличие от него, Py4J не выполняет код Python в JVM, поэтому при использовании Py4J можно работать со всеми библиотеками классического Cython. Ещё есть JPype, но Py4J не связывает потоки Python и Java, также он использует сокеты, а не JNI для связи с JVM.

Главным минусом Py4J является скорость передачи данных между Python и Java. Так как общение происходит посредством сокетов, передавать данные, размером больше чем несколько мегабайт, будет плохой идеей, для этой цели существуют другие решения. Главная задача Py4J – обеспечить доступ к объектам Java и сохранить возможность использования Python библиотек.

Пример работы

Для примера будет создано три Java класса и один Python скрипт для проверки работы. Класс Dict, в котором реализована логика работы с HashMap, Класс DictEntryPoint, в котором реализована точка входа, чтобы Python мог взаимодействовать с объектом класса Dict. Также нужен класс Program, в котором происходит запуск сервера.

Для успешной работы Py4J нужно настроить точку входа, в которой создать необходимые для работы объекты, и запустить GatewayServer, который обеспечивает связь Python с JVM через сокет локальной сети. Далее можно спокойно использовать Java код из Python.

 package py4j_example; import java.util.HashMap; public class Dict < private HashMapdict = new HashMap<>(); /** * Добавление элемента по ключу */ public void add(Integer key, String value) < dict.put(key, value); >/** * Добавляет значение в конец HashMap */ public void add(String value) < dict.put(dict.size(), value); >/** * Удаляет значение по ключу */ public String remove(Integer key) < return dict.remove(key); >/** * Возвращает значение по ключу */ public String get(Integer key) < return dict.get(key); >/** * Возвращает длину HashMap */ public int length() < return dict.size(); >/** * Пересоздаёт HashMap */ public void clear() < dict = new HashMap<>(); add("Запись из Java"); > > 
 package py4j_example; import py4j.GatewayServer; public class DictEntryPoint < private final Dict dict; /** * Создаёт объект класса Dict */ public DictEntryPoint() < this.dict = new Dict(); >/** * Возвращает объект класса Dict */ public Dict getDict() < return this.dict; >> 
 package py4j_example; import py4j.GatewayServer; public class Program < public static void main(String[] args) < /* Создание и запуск сервера */ GatewayServer gatewayServer = new GatewayServer(new DictEntryPoint()); gatewayServer.start(); System.out.println("Gateway Server Started"); >> 

Вывод должен быть примерно такой. После запуска Program.java можно приступить к написанию Python кода для подключения к JVM.

 Connected to the target VM, address: '127.0.0.1:58425', transport: 'socket' Gateway Server Started 
 from py4j.java_gateway import JavaGateway def add_some_values(dict): # Создание списка имён и их запись в dict names = ["Вася", "Аня", "Лена", "Никита"] for name in names: dict.add(name) # Удаление значения по ключу 4 deleted = dict.remove(4) # Вывод содержимого dict for i in range(dict.length()): print(i, "\t", dict.get(i)) print("\nУдалённый элемент =", deleted) return 1 def main(): # Инициализация JavaGateway gateway = JavaGateway() # Получение доступа к объекту класса Dict dict = gateway.entry_point.getDict() add_some_values(dict) # Очистка Dict dict.clear() return 0 if __name__ == "__main__": main() 

После запуска Application.py в консоль выводится следующее:

 0 Запись из Java 1 Вася 2 Аня 3 Лена Удалённый элемент = Никита 

По ключу 0 находится элемент, добавленный из Java, а имена людей были добавлены с помощью Python.

Заключение

Py4J позволяет быстро и легко взаимодействовать с объектами Java из Python, организовывать двустороннее управление коллекциями и работать с интерфейсами в двух языках, соединяя интерпретатор и JVM сокетами. Он отлично подойдёт для задач, требующих минимальных ограничений на использование Python, но при этом не отличается высокой производительностью.

На правах рекламы

VDSina предлагает быстрые серверы в аренду под любые задачи, огромный выбор операционных систем для автоматической установки, есть возможность установить любую ОС с собственного ISO, удобная панель управления собственной разработки и посуточная оплата.

Источник

Читайте также:  Java set display mode
Оцените статью