WrapPyJ - Autoβgenerate Java wrappers for any Python library β seamless, zeroβglue interoperability.
WrapPyJ is a Java wrappers generator for Python libraries, enabling seamless integration of Python functionality within Java applications. This project consists of generator module that work together to provide a complete solution for Python-Java interoperability.
<dependency>
<groupId>tech.thegamedefault.wrappyj</groupId>
<artifactId>generator</artifactId>
<version>1.0.0</version>
</dependency>WrapPyJ is organized as a multi-module Maven project with the following structure:
WrapPyJ/
βββ generator/ # Core wrapper generation engine
βββ example-generator/ # Example of generating wrappers
βββ example-wrapper-usage/ # Example of using generated wrappers
βββ src/main/java/.../generated/ # Generated wrapper classes
Core Engine for Python Library Analysis and Java Wrapper Generation
WrapPyJGenerator: Main entry point for wrapper generationWrapPyJApp: To be used once Java wrappers are generated, to initialize required dependencies.
PythonRuntimeManager: Handles Python runtime initialization and dependenciesPythonAnalyser: Analyzes Python library structure and metadata-
WPJInterpreter: Manages Python interpreter instances via JEP
JavaWrapperGenerator: Generates Java wrapper classes using JavaPoet
- Automatic Analysis: Scans Python libraries to understand their structure
- Java Code Generation: Creates type-safe Java wrapper classes
- Dependency Management: Handles Python package dependencies
- Cross-Platform Support: Works on Linux, macOS, and Windows
- JEP (Java Embedded Python): For Python-Java interop
- JavaPoet: For Java code generation
- Spring Boot: For application framework
- Jackson: For JSON processing
- Lombok: For reducing boilerplate code
List<GeneratorRequest> requests = List.of(
GeneratorRequest.builder()
.importDependencyName("numpy")
.library("numpy")
.outputPath("./src/main/java")
.basePackage("com.example.wrappers")
.build()
);
WrapPyJGenerator.generate(requests);
WrapPyJApp.init(List.of("pandas", "numpy", "matplotlib"));Demonstration of Wrapper Generation Process
This module showcases how to use the generator to create Java wrappers for popular Python libraries.
- Multi-library Generation: Generates wrappers for numpy, pandas, and matplotlib
- Selective Generation: Shows how to include only specific functions/classes
- Build Integration: Demonstrates Maven integration for automated generation
- NumPy: Scientific computing library wrapper
- Pandas: Data manipulation and analysis wrapper
- Matplotlib: Plotting and visualization wrapper
- Automated Build Process: Wrappers are generated during Maven compilation
- Customizable Output: Configurable output paths and package names
- Selective Inclusion: Can generate wrappers for specific parts of libraries
List<GeneratorRequest> requests = List.of(
GeneratorRequest.builder()
.importDependencyName("numpy")
.library("numpy")
.build(),
GeneratorRequest.builder()
.importDependencyName("pandas")
.library("pandas")
.build(),
GeneratorRequest.builder()
.importDependencyName("matplotlib")
.library("matplotlib.pyplot")
.build()
);Demonstration of Using Generated Wrappers
This module shows how to use the generated Java wrappers in real applications, providing practical examples of Python-Java integration.
// Perform mathematical operations using NumPy
Object result = JNumpy.sum(List.of(1, 2, 3, 4, 5));
long actual = ((long[]) result)[0];// Read CSV and perform data analysis
JDataFrame df = new JDataFrame(JPandas.read_csv(CSV_PATH));
Object head = df.head();
Object desc = df.describe();
Object groupBy = new JDataFrame(df.groupby("active")).sum();// Create plots and save images
Object xs = JNumpy.linspace(0, 6.28, 100);
Object ys = JNumpy.sin(xs);
JPyplot.plot(xs, ys);
JPyplot.title("Sine wave (from Java)");
JPyplot.savefig("./sine.png");- Spring Boot Integration: Shows how to integrate wrappers in Spring applications
- Real-world Examples: Practical use cases for data analysis and visualization
- Resource Management: Proper initialization and cleanup of Python interpreters
- Error Handling: Demonstrates robust error handling patterns
- Java 19 or higher
- Maven 3.6+
- Python 3.10+ (embedded in the project)
-
Clone the repository
git clone <repository-url> cd WrapPyJ
-
Build the project
mvn clean install
-
Generate wrappers (optional - already included)
cd example-generator mvn clean compileNote: The wrapper generation uses the Maven exec plugin to automatically run during the compile phase. See the Custom Wrapper Generation section for details on setting up your own generator.
-
Run the example application
cd example-wrapper-usage mvn spring-boot:run
The recommended way to generate wrappers is using the Maven exec plugin, as demonstrated in the example-generator module.
Create a Java class similar to WrapPyJGeneratorExample:
package com.yourcompany.generator;
import java.util.List;
import tech.thegamedefault.wrappyj.generator.WrapPyJGenerator;
import tech.thegamedefault.wrappyj.generator.WrapPyJGenerator.GeneratorRequest;
public class YourLibraryGenerator {
private static final List<GeneratorRequest> GENERATOR_REQUESTS = List.of(
GeneratorRequest.builder()
.importDependencyName("your-library")
.library("your.library.module")
.outputPath("./src/main/java")
.basePackage("com.yourcompany.wrappers")
.includeOnly(List.of("function1", "function2")) // Optional
.build()
);
public static void main(String[] args) {
WrapPyJGenerator.generate(GENERATOR_REQUESTS);
}
}Add the exec-maven-plugin to your pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>com.yourcompany.generator.YourLibraryGenerator</mainClass>
<classpathScope>compile</classpathScope>
</configuration>
</execution>
</executions>
</plugin>Execute the generation as part of your Maven build:
mvn clean package exec:javaOr run it during the compile phase:
mvn clean compileYou can also run the generator directly in Java code:
List<GeneratorRequest> requests = List.of(
GeneratorRequest.builder()
.importDependencyName("your-library")
.library("your.library.module")
.outputPath("./src/main/java")
.basePackage("com.yourcompany.wrappers")
.includeOnly(List.of("function1", "function2")) // Optional
.build()
);
WrapPyJGenerator.generate(requests);- Output Path: Where generated Java files will be placed
- Base Package: Java package name for generated classes
- Include Only: Specific functions/classes to include (optional)
- Import Dependencies: Python package names to install
- Python Interpreter: Managed automatically by JEP
- Memory Management: Automatic cleanup of Python objects
- Error Handling: Comprehensive exception handling
Generated wrappers follow a consistent pattern:
generated/
βββ library_name/
β βββ JLibraryName.java # Main library wrapper
β βββ JClassName.java # Class wrappers
β βββ JFunctionName.java # Function wrappers
Each wrapper provides:
- Type-safe method calls to Python functions [** Not supported for all libraries, part of next milestone]
- Automatic parameter conversion between Java and Python types
- Exception handling for Python errors
- Resource management for Python objects
- Analysis Phase: PythonAnalyser scans the target library
- Generation Phase: JavaWrapperGenerator creates Java classes
- Integration Phase: Generated wrappers are used in Java applications
- Runtime Phase: WPJInterpreter manages Python execution
- Python Import Errors: Ensure Python packages are installed
- Memory Issues: Check JEP memory configuration
- Type Conversion: Verify parameter types match expected Python types
Enable debug logging to see detailed generation and execution information.
- Lazy Loading: Python modules are loaded only when needed
- Object Pooling: Reuses Python interpreter instances
- Memory Management: Automatic cleanup of Python objects
- Batch Operations: Efficient handling of multiple operations
- Sandboxed Execution: Python code runs in controlled environment
- Input Validation: Automatic validation of parameters
- Resource Limits: Configurable limits on Python operations
This project is licensed under the terms specified in the LICENSE file.
Contributions are welcome! Please see our Contributing Guidelines for detailed information on:
- π οΈ Development setup and environment configuration
- π Coding standards and best practices
- π§ͺ Testing guidelines and requirements
- π Pull request process and review checklist
- π Issue reporting templates
- π Release process and versioning
- π₯ Community guidelines and code of conduct
We appreciate all contributions, from bug reports to feature requests to code improvements!
For support and questions:
- Create an issue in the repository
- Check the documentation
- Review the example modules for usage patterns
WrapPyJ - Autoβgenerate Java wrappers for any Python library β seamless, zeroβglue interop.


