Tuesday, April 19, 2016

Java Uygulamalarından Python Betiklerinin Çalıştırılması

Java uygulamalarından Python betiklerinin çalıştırılması için birden fazla yöntem bulunuyor. Bu yazıda bu yöntemler incelenecektir.



Jython Kullanımı

Jython projesi, Python dilinin Java platformundaki bir gerçeklemesidir. Jython'un güncel sürümü, Python dilinin 2.7 sürümünü destekliyor. Jython sayesinde Java platformunda Python dilinde yazılmış betikleri doğrudan çalıştırabilirsiniz. Bunun için ilk olarak projesinin sayfasından jython-standalone-2.7.0.jar dosyasını indirmelisiniz. Bundan sonra sample.py isimli Python betiğini Java uygulamamız içinden PythonInterpreter sınıfı aracılığı ile kolaylıkla çalıştırabiliriz:
package com.example.exercise;

import java.util.Properties;

import org.python.util.PythonInterpreter;

public class JythonExample {
 private static PythonInterpreter interpreter;

 public static void main(String[] args) throws Exception {
  Properties properties = System.getProperties();
  properties.setProperty("python.console.encoding", "UTF-8");
  PythonInterpreter.initialize(properties,properties, new String[0]);
  interpreter = new PythonInterpreter();
  interpreter.set("firstName", "Jack");
  interpreter.set("lastName", "Bauer");
  interpreter.execfile("bin/sample.py");
 }

}
sample.py:
print "Hello " + firstName + ", " + lastName +" !"
Java uygulamasından Python betiğine interpreter.set() metodu aracılığı parametre aktarabilir, interpreter.get() metodu aracılığı ile de çalışma sonrasında değişkenlerin değerlerine ulaşabiliriz. Bu yöntemde, en fazla zamanı PythonInterpreter sınıfından nesneyi yarattığımız satır alacaktır: interpreter = new PythonInterpreter();. Bir kez PythonInterpreter nesnesini yarattıktan sonra çalıştırmak hızlıdır. Bu yöntemde, Java uygulamasının çalıştırıldığı makinada Python kurulu olmasına gerek bulunmaz. Java uygulamalarının çalıştırılabildiği herhangi bir makinada Java uygulamamız ve Python betiği çalışacaktır. Jython kütüphanesine maven projesinden erişebilmek için pom.xml dosyasına aşağıdaki bağımlılığı tanımlamak yeterli olacaktır:
<dependency>
 <groupId>org.python</groupId>
 <artifactId>jython-standalone</artifactId>
 <version>2.7.0</version>
</dependency>


ProcessBuilder Kullanımı

İnceleyeceğimiz ikinci yöntem JDK içinde yer alan ProcessBuilder sınıfını kullanmaktır. Java uygulamasından çalıştıracağımız Python betiği (sample.py) aşağıda verilmiştir.
sample.py:
from sys import argv

script, firstName, lastName = argv

print "Hello " + firstName + ", " + lastName +" !"
Şimdi, bu betiği çalıştıracağımız Java uygulamasına bakalım:
package com.example.exercise;

import java.io.File;
import java.util.Map;

public class PythonProcessExample {

 public static void main(String[] args) throws Exception {
  ProcessBuilder pb = new ProcessBuilder("cmd", "/C", "bin\\sample.py",
    "Jack", "Bauer");
  pb.redirectError(new File("src", "err.txt"));
  pb.redirectOutput(new File("src", "out.txt"));
  Map<String, String> env = pb.environment();
  String path = "C:\\opt64\\python27;" + env.get("Path");
  env.put("Path", path);
  Process process = pb.start();
  process.waitFor();
 }

}
Burada ProcessBuilder sınıfının kurucusuna çalıştırmak isteğimiz Python betiği için komutu parametreleri ile birlikte veriyoruz:
cmd /C bin\sample.py Jack Bauer
Bu yöntemde Java uygulamasını çalıştırdığımız makinada Python ortamının kurulu olması ve komuta erişelebilmesi için ise PATH sistem değişkeninde python komutunun kurulu olduğu dizinin yer alması gerekir. Eğer PATH sistem değişkeninde yer almıyor ise pb.environment() çağrısı ile erişebildiğimiz sistem değişkenlerinden PATH'e gerekli ayarın yapılması gerekir:
Map<String, String> env = pb.environment();
String path = "C:\\opt64\\python27;" + env.get("Path");
env.put("Path", path);
Bu yöntemde betik içindeki değişkenlere atama yapmak için komut satırını kullandık:
from sys import argv
script, firstName, lastName = argv

Scripting API Kullanımı

İnceleyeceğimiz üçüncü yöntem Java SE 6 ile gelen Scripting API (JSR-223) kullanmak olacaktır. Scripting API sayesinde 20 civarında farklı dilde yazılmış uygulamayı Java SE platformu üzerinde çalıştırabiliyoruz. Ancak CLASSPATH'e önce kullanmak istediğimiz dil için Scripting API gerçeklemesini koymamız gerekir. JDK 6+ içinde Javascript gerçeklemesi hazır olarak gelir. Java 7'de gelen Javascript için yazılmış yeni gerçeklemenin kod adı Nashorn'dur. Java'dan Scripting API aracılığı ile çalıştırabileceğimiz dillerin listesine aşağıdaki basit kodla ulaşabiliriz:
ScriptEngineManager factory = new ScriptEngineManager();
 for (ScriptEngineFactory scriptEngineFactory: factory.getEngineFactories())
      System.out.println(scriptEngineFactory.getEngineName());
Şimdi Python betiğini Jython gerçeklemesini Scripting API üzerinden kullanarak çalıştıralım:
package com.example.exercise;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Properties;

import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class ScriptingApiExample {

 public static void main(String[] args) throws Throwable {
  Properties properties = System.getProperties();
  properties.setProperty("python.console.encoding", "UTF-8");

  ScriptEngineManager factory = new ScriptEngineManager();
  for (ScriptEngineFactory scriptEngineFactory
                         : factory.getEngineFactories())
       System.out.println(scriptEngineFactory.getEngineName());
  ScriptEngine jytonEngine = factory.getEngineByExtension("py");
  jytonEngine.put("firstName", "Jack");
  jytonEngine.put("lastName", "Bauer");
  jytonEngine.eval(new FileReader(new File("bin", "sample.py")));
 }

}
Bu yöntemde, Java uygulamasının çalıştırıldığı makinada Python kurulu olmasına gerek bulunmaz. Java uygulamalarının çalıştırılabildiği herhangi bir makinada Java uygulamamız ve Python betiği çalışacaktır.

No comments:

Post a Comment