pemjax 0.2.3
PemJaX
License: https://www.apache.org/licenses/LICENSE-2.0
Requires Python: >=3.8

# PemJaX

## What is it?

PemJa is an open source cross language call framework based on FFI. It aims to provide a high-performance

framework of calling between different languages.

PemJaX is an extension of PemJa , specifically designed to support WindowsOS. 
This package inherits all the functionalities of PemJa and introduces necessary modifications and
enhancements to ensure seamless operation in WindowsOS.

## Where to get it

Python binary installers for the latest released version are available at the [Python package index](https://pypi.org/project/pemjax)

```bash
pip install pemjax
```

Java Maven Dependency
```
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>pemja</artifactId>
    <version>{version}</version>
</dependency>
```

## Dependencies

- [NumPy - Adds support for large, multi-dimensional arrays, matrices and high-level mathematical functions to operate on these arrays](https://www.numpy.org)

## Installation from sources

Prerequisites for building PemJa:
* Unix-like environment (we use Linux, Mac OS X), Windows
* Git
* Maven (we recommend version 3.2.5 and require at least 3.1.1)
* Java 8 or 11 (Java 9 or 10 may work) with $JAVA_HOME correctly set
* Python >= 3.8 (we recommend version 3.8, 3.9, 3.10, 3.11)


**NOTE for windows:**
* Microsoft Visual C++ 14.0 or greater is required. Get it with ["Microsoft C++ Build Tools"](https://www.microsoft.com/en-in/download/details.aspx?id=48159)
* The compressed package in folder *dist* must be uncompressed and use the following command to install ```pip install dist/$packageName$```


```
git clone https://github.com/IGinX-THU/pemja.git
cd pemja
mvn clean package -DskipTests
pip install -r dev/dev-requirements.txt
python setup.py sdist
pip install dist/*.tar.gz
```

## Usage

```java
String path = ...;
PythonInterpreterConfig config = PythonInterpreterConfig
    .newBuilder()
    .setPythonExec("python3") // specify python exec, use "python" on Windows
    .addPythonPaths(path) // add path to search path
    .build();

PythonInterpreter interpreter = new PythonInterpreter(config);

// set & get
interpreter.set("a", 12345);
interpreter.get("a"); // Object
interpreter.get("a", Integer.class); // Integer

// exec & eval
interpreter.exec("print(a)");

// invoke functions
interpreter.exec("import str_upper");
String result = interpreter.invoke("str_upper.upper", "abcd");
// Object invoke(String name, Object... args);
// Object invoke(String name, Object[] args, Map<String, Object> kwargs);

// invoke object methods
/*
// invoke.py
class A:
       def __init__(self):
           self._a = 0
   
       def get_value(self):
           return self._a
   
       def add(self, n):
           self._a += n
   
       def add_all(self, *args):
           for item in args:
               self._a += item
               return self._a
   
       def minus(self, n):
           self._a -= n
           return self._a
*/

interpreter.exec("import invoke");
interpreter.exec("a = invoke.A()");
interpreter.invokeMethod("a", "add", 3);
interpreter.invokeMethod("a", "minus", 2);
interpreter.invokeMethod("a", "add_all", 1, 2, 3);


// python callback java methods
/*
// invoke_callback.py
from pemja import findClass

StringBuilder = findClass('java.lang.StringBuilder')
Integer = findClass('java.lang.Integer')

def callback_java():
    sb = StringBuilder()
    sb.append('pemja')
    sb.append('java')
    sb.append('python')
    sb.append(Integer.toHexString(Integer.MAX_VALUE))
    return sb.toString()
*/
interpreter.exec("import call_back")
print(interpreter.invoke("call_back.callback_java"))
```