Preface
You may or may not know that it is possible to access Jython code from Java without compiling it using the jythonc utility. This technique is possible using a mixture of Java interfaces and usage of the PythonInterpreter. As a matter of fact, I believe that using this technique correctly is more effective than using jythonc.
To put it simply, to use this technique you must create a "factory" method which uses the PythonInterpreter class to interpret a .py module for use within Java code. Any Java code that uses the Jython code should be coded against an interface which is implemented by the Jython code.
In order to provide a fully functional example, I've created a simple application with hard-coded data. This application shows the potential for using this technique within your Java applications to have the ability for use of dynamic Jython objects.
The application is simply called "jyinterface" and it contains four pieces of code:
Step By Step
We'll start by coding the "EmployeeType.java" interface which is what our Java code will use in order to interact with the Jython object:
- package test.jython;
- public interface EmployeeType {
- public String getEmployeeFirst();
- public String getEmployeeLast();
- public String getEmployeeId();
- public String getPID();
- }
- # Jython source file
- from test.jython import EmployeeType
- import os
- class Employee(EmployeeType):
- def __init__(self):
- self.first = "Josh"
- self.last = "Juneau"
- self.id = "myempid"
- def getEmployeeFirst(self):
- return self.first
- def getEmployeeLast(self):
- return self.last
- def getEmployeeId(self):
- return self.id
- def getPID(self):
- return str(os.getpid())
- package test.jython;
- import org.python.util.PythonInterpreter;
- public class JythonFactory {
- private static JythonFactory instance = null;
- public synchronized static JythonFactory getInstance() {
- if (instance == null) {
- instance = new JythonFactory();
- }
- return instance;
- }
- public static Object getJythonObject(String interfaceName, String pathToJythonModule) {
- Object javaInt = null;
- PythonInterpreter interpreter = new PythonInterpreter();
- interpreter.execfile(pathToJythonModule);
- String tempName = pathToJythonModule.substring(pathToJythonModule
- .lastIndexOf("/") + 1);
- tempName = tempName.substring(0, tempName.indexOf("."));
- System.out.println(tempName);
- String instanceName = tempName.toLowerCase();
- String javaClassName = tempName.substring(0, 1).toUpperCase()
- + tempName.substring(1);
- String objectDef = "=" + javaClassName + "()";
- interpreter.exec(instanceName + objectDef);
- try {
- Class JavaInterface = Class.forName(interfaceName);
- javaInt = interpreter.get(instanceName).__tojava__(JavaInterface);
- } catch (ClassNotFoundException ex) {
- ex.printStackTrace(); // Add logging here
- }
- return javaInt;
- }
- }
Here is the "Main.java" code:
- package test.jython;
- public class Main {
- public static void main(String[] args) {
- JythonFactory jf = JythonFactory.getInstance();
- EmployeeType eType = (EmployeeType) jf.getJythonObject(
- "test.jython.EmployeeType", "src/test/jython/Employee.py");
- System.out.println("Employee Name: " + eType.getEmployeeFirst() + " " +
- eType.getEmployeeLast());
- System.out.println("Employee ID: " + eType.getEmployeeId());
- System.out.printf("Test output: %s\n", eType.getPID());
- }
- }
Next time you plan to create a Java application that contains some Jython code, give this technique a try...
沒有留言:
張貼留言