月曜日 11 10, 2014

ECMAScript 6 の Block Scope

はじめに

JDK 8u40 から、Nashorn で ECMAScript 6 のブロックスコープが使えるようになります。

弓括弧(波括弧)で変数スコープを作成できるようになり、let でスコープローカルな変数を定義できます。

$ ./bin/jjs --language=es6
jjs> { var a = 'a'; let b = 'b' } print(a); print(b)
a
<shell>:1 ReferenceError: "b" is not defined
jjs> quit()

この例では、ブロックスコープ内でのみ有効な変数 b を定義しています。
var で宣言した変数 a はブロックスコープの外からも参照出来ますが、let で宣言した変数 b はブロックスコープの内側でのみ有効になっています。

JDK 8u40 Early Access 版のインストール

JDK 8u40 は Early Access 版が公開されていますので、すぐにお試しいただくことが可能です。

JDK 8u40 EA 版は こちら からダウンロード出来ます。

ダウンロードしたら、アーカイブを展開します。

$ tar zxf jdk-8u40-ea-bin-b12-linux-x64-28_oct_2014.tar.gz
$ cd jdk1.8.0_40/

ES6 の 機能を使用するには jjs コマンドに --language=es6 オプションを追加します。

$ ./bin/jjs -h
...
    --language (Specify ECMAScript language version.)
        param: [es5|es6]   default: es5
...
$ ./bin/jjs --language=es6
jjs> 

let の挙動

let で変数を宣言すると、その変数を弓括弧で作成したスコープの内側に閉じ込めることが出来ます。

let の場合:

jjs> { let foo = 'foo'; print(foo) } print(foo)
foo
<shell>:1 ReferenceError: "foo" is not defined
jjs> quit()

二回目の print(foo) はブロックスコープの外側で実行されているため、参照エラーになりました。

一方、var で変数を宣言した場合はブロックスコープの外からもアクセスできます。

var の場合:

jjs> { var foo = 'foo'; print(foo) } print(foo)
foo
foo
jjs> quit()

これで変数のスコープを作りたいときに関数スコープ (function(){ ... })() で代用する必要がなくなりました。
変数スコープを作成したい場合は弓括弧を使用し、var の代わりに let で変数を宣言します。

let を使用すると、for 文で使用する一時変数が外に漏れることもなくなります。

let の場合:

jjs> for(let i = 0; i < 3; i++) { print(i) }; print(i)
0
1
2
<shell>:1 ReferenceError: "i" is not defined
jjs> quit()

for 文の外側では変数 i を参照することが出来ないため、最後の print(i) はエラーになります。

var の場合:

$ ./bin/jjs --language=es6
jjs> for(var i = 0; i < 3; i++) { print(i) }; print(i)
0
1
2
3
jjs> quit()

var の場合は変数をスコープ内に閉じ込めることができないため、for 文の外側でも参照出来ています。

let は便利ですね。

おわりに

Nashorn への ES6 Block Scope の取り込みは JEP 203 で進められました。
こちら も合わせてご参照ください。

Nashorn の let のテストケースは JDK-8057678 で作成されています。

ECMAScript 6 の仕様はドラフト段階で、まだ確定はしていません。ご注意ください。
ECMAScript 6 のドラフトは こちら から辿れます。

是非お試しください。

水曜日 6 04, 2014

Nashorn から JDBC で Oracle DB に接続する・その 3

はじめに

Nashorn 用の JavaScript プログラムから JDBC で Oracle DB に接続する手順のご紹介の続きです。今回は Oracle DB に接続して SQL を実行する手順をご紹介します。

前回までの記事を読まれていない方は、こちらこちらをご覧下さい。

このドキュメントの URL は https://blogs.oracle.com/nashorn_ja/entry/nashorn_jdbc_3 です。

JDBC によるデータベースの接続テスト

JDBC 開発者ガイドにあるプログラムを元に Nashorn で動作する JavaScript のプログラムを作成します。

元のプログラムは JDBC OCI ドライバを使用してデータベースへの接続確認をするプログラムです。

プログラム

元の Java のプログラムをほとんどそのまま Nashorn の JavaScript に置き換えたコードがこちらです。

// Invoke jjs with -scripting option.

/*
 * This sample can be used to check the JDBC installation.
 * Just run it and provide the connect information. It will select
 * "Hello World" from the database.
 */

var OracleDataSource = Java.type("oracle.jdbc.pool.OracleDataSource");

function main() {

  // Prompt the user for connect information
  print("Please enter information to test connection to the database");

  var user, password, database;

  user = readLine("user: ");
  slash_index = user.indexOf('/');
  if (slash_index != -1)
  {
    password = user.substring(slash_index + 1)
    user = user.substring(0, slash_index);
  }
  else
    password = readLine("password: ");
  database = readLine("database(a TNSNAME entry): ");

  java.lang.System.out.print("Connecting to the database...");
  java.lang.System.out.flush();
  print("Connecting...");
  // Open an OracleDataSource and get a connection
  var ods = new OracleDataSource();
  ods.setURL("jdbc:oracle:oci:@" + database);
  ods.setUser(user);
  ods.setPassword(password);
  var conn = ods.getConnection();
  print("connected.");

  // Create a statement
  var stmt = conn.createStatement();

  // Do the SQL "Hello World" thing
  var rset = stmt.executeQuery("select 'Hello World' from dual");

  while (rset.next())
    print(rset.getString(1));
  // close the result set, the statement and the connection
  rset.close();
  stmt.close();
  conn.close();
  print("Your JDBC installation is correct.");
}

main();
  • oracle.jdbc.pool.OracleDataSource を Java.type() に渡して、Nashorn 側でインスタンスが作成可能なオブジェクトにしています。
  • Java の System.out.println() と System.out.flush() は java.lang. を先頭に付けて呼び出しています。
  • Java のプログラムに合った readEntry() メソッドは Nashorn の readLine() 関数で置き換えています。

Java のメソッドであることをほとんど意識することなく、JavaScript から呼び出せていることが分かります。

プログラムの実行

JDBC OCI ドライバを使用する場合は、事前に LD_LIBRARY_PATH 環境変数を設定する必要があります。

また、Nashorn の readLine() 関数を使用するため、jjs コマンドに -scripting オプションを付けて実行しています。

$ export LD_LIBRARY_PATH=${ORACLE_HOME}/lib
$ jjs -scripting -cp ${ORACLE_HOME}/jdbc/lib/ojdbc6.jar JdbcCheckup.js
Please enter information to test connection to the database
user: test
password: test
database(a TNSNAME entry): orcl
Connecting to the database...Connecting...
connected.
Hello World
Your JDBC installation is correct.

JDBC OCI ドライバを使用して、データベースに "select 'Hello World' from dual" という SQL を発行することができました。

リモートのマシンに接続する場合は、database の入力を :: の様に指定して下さい。

より JavaScript 的なコード

先ほどのコードは Java のプログラムをほとんどそのままなぞっているため、とても Java 的なコードになっていましたが、適宜 JavaScript で書きやすい書き方に置き換えてお使い下さい。

var OracleDataSource = Java.type("oracle.jdbc.pool.OracleDataSource");

var jdbc = {

  user: function(u) {

    this.user = u;
    return this;

  },

  password: function(p) {

    this.password = p;
    return this;

  },

  database: function(d) {

    this.database = d;
    return this;

  },

  open: function() {

    var ods = new OracleDataSource();
    ods.setURL("jdbc:oracle:oci:@" + this.database);
    ods.setUser(this.user);
    ods.setPassword(this.password);

    this.conn = ods.getConnection();
    return this;

  },

  close: function() {

    this.rset.close();
    this.stmt.close();
    this.conn.close();

    return this;

  },

  executeQuery: function(q) {

    this.stmt = this.conn.createStatement();
    this.rset = stmt.executeQuery(q);

    return this;

  },

  resultSet: function() {

    return this.rset;

  }

}

function main() {

  var user = readLine("user: ");
  var password = readLine("password: ");
  var database = readLine("database: ");

  var j = new jdbc();
  var rset = j.user(user).password(password).database(database). \
             open().executeQuery(query).resultSet(); 

  while (rset.next()) {

    print(rset.getString(1));

  }
  j.close();

}

main();

この様な形で、JDBC の API を JavaScript のライブラリのように扱うことが簡単に出来ます。

まとめ

今回は Oracle DB に接続して SQL を実行する手順をご紹介しました。

Java で JDBC のプログラムを書いたことがある方であれば、とても簡単に Nashorn 向けのプログラムを書くことが出来ることがご理解いただけたと思います。

火曜日 6 03, 2014

Nashorn から JDBC で Oracle DB に接続する・その 2

はじめに

Nashorn 用の JavaScript プログラムから JDBC で Oracle DB に接続する手順のご紹介の続きです。今回はリモートマシンから接続する方法と、JDBC のライブラリのバージョンを出力するもう一つの方法をご紹介します。

前回の記事を読まれていない方はまずこちらをご覧下さい。

この記事の URL は https://blogs.oracle.com/nashorn_ja/entry/nashorn_jdbc_2 です。

リモートマシンから JDBC で接続する

前回の記事ではローカルマシンの ${ORACLE_HOME}/jdbc/lib/ojdbc6.jar を使用しましたが、リモートマシンから接続する場合は別途 JDBC のドライバが必要になります。

こちらから ojdbc6.jar をダウンロードしてください。

プログラムの方もリモートに接続できるよう、コネクトストリングを書き換えます。

var OracleDataSource = Java.type("oracle.jdbc.pool.OracleDataSource");
var ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:test/test@dbsrv:1521:orcl");
var conn = ods.getConnection();
var meta = conn.getMetaData();
print("JDBC driver version is " + meta.getDriverVersion());

ダウンロードした JDBC のドライバを jjs コマンドの -cp オプションで指定してスクリプトを実行します。

$ jjs -cp ojdbc6.jar version.js
JDBC driver version is 11.2.0.3.0

ローカルから実行した場合と同じ結果を得ることができました。

JAR ファイルの Main Class の実行によるバージョンの表示

続いて、JDBC のライブラリのバージョンを出力するもう一つの方法をご紹介します。

こちらにある通り、java -jar ojdbc6.jar でも JDBC ドライバのバージョンを確認できます。

$ java -jar ojdbc6.jar 
Oracle 11.2.0.3.0 JDBC 4.0 compiled with JDK6 on Thu_Jul_11_15:43:23_PDT_2013
#Default Connection Properties Resource
#Fri May 30 10:37:32 JST 2014

この処理は JAR ファイルのマニフェストの Main-Class に指定されているクラスの main(String[]) メソッドに実装されています。同じ処理を Nashorn からも呼び出してみましょう。

JAR ファイルの Main-Class を調べる

まず Main-Class が何であるかを調べます。

jar コマンドで JAR ファイルを展開し、META-INF/MANIFEST.MF ファイルを開いて、記載されている Main-Class を確認します。

$ jar xf ojdbc6.jar
$ grep Main-Class META-INF/MANIFEST.MF 
Main-Class: oracle.jdbc.OracleDriver

Main-Class は oracle.jdbc.OracleDriver であることが分かりました。

Main-Class の実行

先ほど確認した oracle.jdbc.OracleDriver クラスの main メソッドを Nashorn から実行します。

$ jjs -cp ojdbc6.jar 
jjs> var OracleDriver = Java.type("oracle.jdbc.OracleDriver");
jjs> var StringArray = Java.type("java.lang.String[]");
jjs> OracleDriver.main(new StringArray(0))
Oracle 11.2.0.3.0 JDBC 4.0 compiled with JDK6 on Thu_Jul_11_15:43:23_PDT_2013
#Default Connection Properties Resource
#Fri May 30 10:55:22 JST 2014

null
jjs> 

java コマンドで JAR ファイルを実行した際と同じ出力を得ることができました。

Java の配列型を使用する場合は、事前に Java.type() 関数を使用して JavaClass オブジェクトを作成しておく必要があります。

まとめ

Nashorn を使ってリモートマシンから JDBC で Oracle DB に接続する方法、JAR ファイルの Main-Class を呼び出す手順をご紹介しました。

次回は Oracle DB に接続して SQL を実行する手順をご紹介します。

月曜日 6 02, 2014

Nashorn から JDBC で Oracle DB に接続する

はじめに

これから何回かに分けて、Nashorn 用の JavaScript プログラムから JDBC の API を呼び出し、Oracle DB に接続する基本的な手順をご紹介していきます。

初回はプログラムを動かすための事前準備と、JDBC の API を呼び出す方法をご紹介します。

このドキュメントの URL は https://blogs.oracle.com/nashorn_ja/entry/nashorn_jdbc_1 です。

実行環境

接続先の DB として、Oracle Linux 6.5 上に Oracle 11.2.0.3.0 がインストールしてあります。

JDBC のクライアントプログラムは DB サーバと同一マシン上で動かします。

処理内容

『Oracle Database JDBC 開発者ガイド』のサンプルプログラムを元にして、Nashorn 用の JavaScript のプログラムを作成し、そのプログラムの中から JDBC で Oracle DB に接続します。

  • Nashorn 用の JavaScript プログラムから JDBC で Oracle DB に接続します
  • JavaScript プログラムは DB サーバと同一マシン上で実行します
  • JavaScript プログラムは oracle ユーザで実行します

JavaScript プログラムを DB サーバと同一マシン上で実行するのは説明をシンプルにするためですが、DB サーバとは別のマシンから JavaScript で接続する方法もほとんど同じ手順で実現できます。

oracle ユーザ以外のユーザで JDBC 接続する場合もほとんど同じ手順で実行できます。

事前準備

DB ユーザの作成

接続する先の DB 上にユーザを作成します。

SQL> create user test identified by "test";
SQL> grant connect, resource to test;

Java 8 のダウンロード

ここから JDK 8 をダウンロードします。この文書を書いた時点の最新バージョンは 8u5 でした。

Java 8 のインストール

ダウンロードした JDK を yum コマンドでインストールします。

# yum install ./jdk-8u5-linux-x64.rpm

JDK がインストールされていることを確認します。

# java -version
java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)

Nashorn の動作確認

oracle ユーザでログインし、PATH を設定します。

$ vi ~/.bash_profile
PATH=${PATH}:/usr/java/latest/bin
export PATH
$ . ~/.bash_profile

jjs コマンドが実行できる事を確認します。

$ jjs -fv 
nashorn full version 1.8.0_05-b13

事前準備はこれで完了です。

JDBC のドライバのバージョンの確認

JDBC の動作確認として、JDBC 開発者ガイド にあるサンプルコードを Nashorn 用の JavaScript プログラムに変換して実行してみます。

元のサンプルコードは JDBC ライブラリののバージョンを出力するプログラムです。

スクリプトファイルとして実行

JavaScript のファイルを作成し、jjs コマンドにそのファイル名(ここでは version.js)を渡してあげると Nashorn で JavaScript プログラムを実行することができます。

JDBC を使用する際は jjs コマンドに -cp オプションで JDBC ドライバの JAR ファイルを指定します。

$ vi version.js
var OracleDataSource = Java.type("oracle.jdbc.pool.OracleDataSource");
var ods = new OracleDataSource();
ods.setURL("jdbc:oracle:thin:test/test@localhost:1521:orcl");
var conn = ods.getConnection();
var meta = conn.getMetaData();
print("JDBC driver version is " + meta.getDriverVersion());
$ jjs -cp ${ORACLE_HOME}/jdbc/lib/ojdbc6.jar version.js 
JDBC driver version is 11.2.0.3.0

ご覧の通り、JavaScript のスクリプトから JDBC ドライバのバージョン (11.2.0.3.0) が確認できました。

Java.type() 関数で作成した JavaClass オブジェクトを new することで Java のオブジェクトを作成することができます。それ以外は元の Java プログラムとほとんど変わりがありません。

型指定が無い分、プログラムは多少シンプルになっています。コンパイルが不要なのでプログラムの修正も簡単です。

実行速度が重要だったり、静的な型付けでコンパイル時にエラーを捕捉したい場合は Java を使用し、プロトタイピングでは JavaScript を使用してトライアンドエラーを繰り返すといった使い方が可能です。

対話的な実行

スクリプトファイルを指定しないで jjs コマンドを実行すると、Nashorn のシェルにアクセスできます。jjs> がプロンプトです。そこにプログラムを入力していきます。

$ jjs -cp ${ORACLE_HOME}/jdbc/lib/ojdbc6.jar 
jjs> var OracleDataSource = Java.type("oracle.jdbc.pool.OracleDataSource");
jjs> var ods = new OracleDataSource();
jjs> ods.setURL("jdbc:oracle:thin:test/test@localhost:1521:orcl");
null
jjs> var conn = ods.getConnection();
jjs> var meta = conn.getMetaData();
jjs> print("JDBC driver version is " + meta.getDriverVersion());
JDBC driver version is 11.2.0.3.0

対話的な実行でも JDBC ドライバのバージョン (11.2.0.3.0) が確認できました。

対話的な実行の利点はプログラムの実行結果を逐一確認できることです。問題が発生したらその場で修正することが可能です。JDBC の学習やプロトタイピングで効果を発揮します。

まとめ

Nashorn のプログラムから JDBC の API を使用するための事前準備と API を呼び出す方法をご紹介しました。

スクリプトによる JavaScript プログラムの実行方法と対話的なプログラムの実行方法をご説明しました。

次回はリモートマシンから JDBC で DB に接続する方法、今回と違う手順で JDBC のライブラリのバージョンを表示する方法をご紹介します。

参考文献

水曜日 3 19, 2014

Java 8 GA!

Java 8 が リリース されました!
これが Nashorn の最初のリリースになります。

Nashorn の JavaScript インタラクティブ・シェルを起動するコマンドは jjs です。
jjs コマンドは JRE 8 と JDK 8 の両方に含まれています。

Nashorn を使用したスクリプティングの方法は こちら をご覧下さい。
jjs コマンドのリファレンスは ここ にあります。

About

JavaVM 用 JavaScript エンジンの Nashorn について情報発信しているブログです。Nashorn の読み方はナズホーンです。

Search

Categories
Archives
« 5月 2015
     
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
      
Today