您的位置: 新闻频道 Java新闻

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

2008-07-15 by 副主编 QQbyte
评论(11) 有1837人浏览 scripting python
你有没有写过和外部进程或者系统交互的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();

来自:alittlemadness.com

评论 共 11 条 发表评论

meng9999 2008-08-10 11:55
这个实现是不错,就是性能上,应该会有点问题, 我原来也用 java写接口,然后用groovy写实现,在java里头动态调用grovvy的方法; 可是没有敢在项目中应用;
ray_linn 2008-07-16 21:37
这么复杂,顶什么用?
kingwang520 2008-07-16 17:16
海纳百川 有容乃大
qsrock 2008-07-16 09:43
这样很麻烦,问题是有没有用啊
linginfanta 2008-07-16 09:38
没有看懂。
helyho 2008-07-16 00:04
虽然没有看的完全明白(本人不懂python),但是我认可他很牛
williamy 2008-07-15 23:08
支持JVM平台化,不然以后怎么混
yunsong 2008-07-15 19:10
就应该这样,做平台
hellas 2008-07-15 18:11
java好是好,就是配置太麻烦,太笨重,不像python,清清爽爽的。
ln1058 2008-07-15 18:07
太强大了
支持
QQbyte 2008-07-15 16:56
Java越来越象一个平台,可以跑各种语言,而不是一种语言而已。

发表评论

您还没有登录,请登录后发表评论