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 类。
然后我们定义一个 Java 接口描述这些 python classes.
然后,我们定义一个factory函数提供在Java tests中运行Python对象权限。
最后,魔法发生,我们通过在python script中定义package函数抹去了java和python的鸿沟。
更新 python 类定义,扩展java接口
最后的运行结果:
下面是一个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();