zoukankan      html  css  js  c++  java
  • Accessing Jython from Java Without Using jythonc

    JythonMonthly/Articles/September2006/1 - JythonWiki

    Accessing Jython from Java Without Using jythonc

      

    Submitted By: Josh Juneau   

    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:

    • -Main.java

      -JythonFactory.java - Uses the PythonInterpreter to return a Java object

      -EmployeeType.java - An interface which will be implemented by a Jython bean -Employee.py - Jython bean representing an employee

    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 jyinterface.interfaces;
    
    public interface EmployeeType {
    
        public String getEmployeeFirst();
        public String getEmployeeLast();
        public String getEmployeeId();
    
    }

    The Jython bean "Employee.py" is just a simple Jython object which implements the Java interface "EmployeeType.java":

     

    # Jython source file
    from jyinterface.interfaces import EmployeeType
    
    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

    Next, the most powerful code for this technique is the "JythonFactory.java" class. This code defines a method which interprets a Jython module into Java and returns for use within Java code. The best part about creating a factory class such as this one is reuse! The factory can be coded in many different ways, but this way allows for reuse because you can essentially pass any Java interface/Jython module to it.

     

    package jyinterface.factory;
    
    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;
       }
    }

    As we stated previously, a Java interface/Jython module combo needs to be passed to the getJythonObject method in order to return the resulting code. In the following piece of code, you can see how this is done. Simply pass in two strings:

    1. Fully qualified name of the Java Interface
    2. Full path to the Jython code module

    Here is the "Main.java" code:

     

    package jyinterface;
    
    import jyinterface.interfaces.EmployeeType;
    import jyinterface.factory.JythonFactory;
    import org.python.util.PythonInterpreter;
    
    
    public class Main {
    
        EmployeeType et;
    
        /** Creates a new instance of Main */
        public Main() {
        }
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            JythonFactory jf = JythonFactory.getInstance();
            EmployeeType eType = (EmployeeType) jf.getJythonObject(
                                   "jyinterface.interfaces.EmployeeType", "<<path to module>>/Employee.py");
            System.out.println("Employee Name: " + eType.getEmployeeFirst() + " " +
                        eType.getEmployeeLast());
            System.out.println("Employee ID: " + eType.getEmployeeId());
    
        }
    }

    This technique is powerful because it allows an application to use code which can be interchanged or dynamically updated without re-deployment or re-compile. It also follows a great Java practice which is code against Java interfaces!! One downfall to this approach is that the code is interpreted every time it is invoked, so the performance may not be as good as using a jythonc compiled piece of code. It obviously depends upon the requirements of the application, but the usefulness of this technique may outweigh the performance factor in many cases.

    Next time you plan to create a Java application that contains some Jython code, give this technique a try...

  • 相关阅读:
    EF深入系列--细节
    EF深入系列--Code First
    WebApi深入学习--特性路由
    转:asp.net TreeView CheckChanged 事件浅谈
    Entity Framework 中的in操作实例
    解决IE8 内置JSON.stringify,中文变unicode的问题
    解决SQL Server的cannot resolve the collation conflict问题
    sqlserver 解析Json字符串
    EF性能调优
    IIS 发布mvc 403.14
  • 原文地址:https://www.cnblogs.com/lexus/p/2372388.html
Copyright © 2011-2022 走看看