欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  资讯频道

Java 6: 通过新的Scripting引擎使用Python

程序员文章站 2024-03-25 23:25:22
...
你有没有写过和外部进程或者系统交互的Java代码?你有没有希望使用脚本(Scripting)语言来写?如果你使用Java 6,Java 6提供了一个清晰的解决方案在JVM中跑Scripts,并且允许Java代码使用Script组件。

下面是一个Python的例子,借助jython的帮助,我们通过Java接口调用Python组件,使用简单的factory函数,我们能够类似Java对象一样运行scripts。

首先写一个Python scripts,来定义PulsePackage 和 Pulse 类。

class PulsePackage:
   
  def __init__(self, packageFile):
    self.packageFile = packageFile
   
  def extractTo(self, destDir):
    if not os.path.exists(destDir):
      os.makedirs(destDir)
       
    var = {‘destDir’:destDir, ‘packageFile’:self.packageFile}
      if self.packageFile.endswith(‘.zip’):
        os.system(“unzip -qd %(destDir)s %(packageFile)s” % var)
      else:
        os.system(“tar -zxC %(destDir)s -f %(packageFile)s” % var)
       
    return Pulse(os.path.join(destDir, self.getBasename()))
       
class Pulse:

  def __init__(self, baseDir, port=8080):
    “”” snipped ““”
       
  def start(self, wait=True, service=False):
    “”” snipped ““”
       
  def stop(self, timeout=60, service=False):
    “”” snipped ““”



然后我们定义一个 Java 接口描述这些 python classes.

public interface PulsePackage
{
  Pulse extractTo(String target);
}

public interface Pulse
{
  void start();
 
  void stop();
}


然后,我们定义一个factory函数提供在Java tests中运行Python对象权限。

public class JythonPulsePackageFactory
  implements PulsePackageFactory
{
  private File scripts = null;
   
  private Invocable invocableEngine;

  public JythonPulsePackageFactory()
  {
    this.scripts = new File(“scripts”);

    ScriptEngine jythonEngine =
        new ScriptEngineManager().
            getEngineByName(“python”);
       
    // the packageFactory.py script
    // contains our python class
    // definitions, and is loaded
    // here into the script engine.
    Reader script = new FileReader(
      new File(scripts, “packageFactory.py”));
    jythonEngine.eval(script);

    // this invocable engine now
    // allows us access to execute
    // python defined methods.
    invocableEngine =
      (Invocable) jythonEngine;
  }

  public PulsePackage createPackage(File pkg)
    throws Exception
  {
    // the createPackage method is
    // implemented in python, and
    // returns an instance (handle)
    // to python implemented extension
    // of our PulsePackage interface.
    return (PulsePackage)
      invocableEngine.invokeFunction(
          “createPackage”, pkg.getCanonicalPath());
  }
}


最后,魔法发生,我们通过在python script中定义package函数抹去了java和python的鸿沟。

def createPackage(packageFile):
    return PulsePackage(packageFile)


更新 python 类定义,扩展java接口

class Pulse(com.zutubi.pulse.acceptance.Pulse):
  “”” <snipped> ““”

class PulsePackage(com.zutubi.pulse.acceptance.PulsePackage):
  “”” <snipped> ““”


最后的运行结果:

File pkg =  new File(“testing-packages/pulse-2.0.0.zip”);

JythonPulsePackageFactory factory =
    new JythonPulsePackageFactory();

PulsePackage pulsePackage = factory.createPackage(pkg);

File destDir = new File(“tmp”);
Pulse pulse = pulsePackage.extractTo(destDir.getCanonicalPath());
pulse.start();

相关标签: Python Java