2014年3月30日

[Java] Get all countries using Java SE 8 Locale

原文はこちら。
https://blogs.oracle.com/brunoborges/entry/get_all_countries_using_java

以下のようなエントリを見て、以前同じようなエントリを投稿したなぁ、と考えていました。
Get all the country using Java Locale List
http://www.javatutorialscorner.com/2014/02/get-all-county-using-java-locale-list.html
package com.javatutorialscorner.util;

import java.util.Locale;

public class JavaCountyList {

 /**
  * @param args
  */
 public static void main(String[] args) {
  // TODO Auto-generated method stub
  String[] locales = Locale.getISOCountries();
  for (String country : locales) {
   Locale locale = new Locale("", country);
   System.out.println("Country : " + locale.getDisplayCountry()
     + " \t\t\t\t:\t Country Code : " + locale.getCountry());
  }

 }

}
このコードを実行すると、こんな感じの結果になります。
Country : Andorra     :  Country Code : AD
Country : United Arab Emirates     :  Country Code : AE
Country : Afghanistan     :  Country Code : AF
Country : Antigua and Barbuda     :  Country Code : AG
Country : Anguilla     :  Country Code : AI
Country : Albania     :  Country Code : AL
Country : Armenia     :  Country Code : AM
Country : Netherlands Antilles     :  Country Code : AN
Country : Angola     :  Country Code : AO
Country : Antarctica     :  Country Code : AQ
Country : Argentina     :  Country Code : AR
Country : American Samoa     :  Country Code : AS
Country : Austria     :  Country Code : AT
Country : Australia     :  Country Code : AU
Country : Aruba     :  Country Code : AW
Country : Åland Islands     :  Country Code : AX
Country : Azerbaijan     :  Country Code : AZ
Country : Bosnia and Herzegovina     :  Country Code : BA
Country : Barbados     :  Country Code : BB
Country : Bangladesh     :  Country Code : BD
Country : Belgium     :  Country Code : BE
Country : Burkina Faso     :  Country Code : BF
Country : Bulgaria     :  Country Code : BG
Country : Bahrain     :  Country Code : BH
Country : Burundi     :  Country Code : BI
Country : Benin     :  Country Code : BJ
Country : Saint Barthélemy     :  Country Code : BL
Country : Bermuda     :  Country Code : BM
Country : Brunei     :  Country Code : BN
Country : Bolivia     :  Country Code : BO
Country : Bonaire, Sint Eustatius and Saba     :  Country Code : BQ
Country : Brazil     :  Country Code : BR
Country : Bahamas     :  Country Code : BS
Country : Bhutan     :  Country Code : BT
Country : Bouvet Island     :  Country Code : BV
Country : Botswana     :  Country Code : BW
Country : Belarus     :  Country Code : BY
Country : Belize     :  Country Code : BZ
Country : Canada     :  Country Code : CA
Country : Cocos Islands     :  Country Code : CC
Country : The Democratic Republic Of Congo     :  Country Code : CD
Country : Central African Republic     :  Country Code : CF
Country : Congo     :  Country Code : CG
Country : Switzerland     :  Country Code : CH
Country : Côte d'Ivoire     :  Country Code : CI
Country : Cook Islands     :  Country Code : CK
Country : Chile     :  Country Code : CL
Country : Cameroon     :  Country Code : CM
Country : China     :  Country Code : CN
Country : Colombia     :  Country Code : CO
Country : Costa Rica     :  Country Code : CR
Country : Cuba     :  Country Code : CU
Country : Cape Verde     :  Country Code : CV
Country : Curaçao     :  Country Code : CW
Country : Christmas Island     :  Country Code : CX
Country : Cyprus     :  Country Code : CY
Country : Czech Republic     :  Country Code : CZ
Country : Germany     :  Country Code : DE
Country : Djibouti     :  Country Code : DJ
Country : Denmark     :  Country Code : DK
Country : Dominica     :  Country Code : DM
Country : Dominican Republic     :  Country Code : DO
Country : Algeria     :  Country Code : DZ
Country : Ecuador     :  Country Code : EC
Country : Estonia     :  Country Code : EE
Country : Egypt     :  Country Code : EG
Country : Western Sahara     :  Country Code : EH
Country : Eritrea     :  Country Code : ER
Country : Spain     :  Country Code : ES
Country : Ethiopia     :  Country Code : ET
Country : Finland     :  Country Code : FI
Country : Fiji     :  Country Code : FJ
Country : Falkland Islands     :  Country Code : FK
Country : Micronesia     :  Country Code : FM
Country : Faroe Islands     :  Country Code : FO
Country : France     :  Country Code : FR
Country : Gabon     :  Country Code : GA
Country : United Kingdom     :  Country Code : GB
Country : Grenada     :  Country Code : GD
Country : Georgia     :  Country Code : GE
Country : French Guiana     :  Country Code : GF
Country : Guernsey     :  Country Code : GG
Country : Ghana     :  Country Code : GH
Country : Gibraltar     :  Country Code : GI
Country : Greenland     :  Country Code : GL
Country : Gambia     :  Country Code : GM
Country : Guinea     :  Country Code : GN
Country : Guadeloupe     :  Country Code : GP
Country : Equatorial Guinea     :  Country Code : GQ
Country : Greece     :  Country Code : GR
Country : South Georgia And The South Sandwich Islands     :  Country Code : GS
Country : Guatemala     :  Country Code : GT
Country : Guam     :  Country Code : GU
Country : Guinea-Bissau     :  Country Code : GW
Country : Guyana     :  Country Code : GY
Country : Hong Kong     :  Country Code : HK
Country : Heard Island And McDonald Islands     :  Country Code : HM
Country : Honduras     :  Country Code : HN
Country : Croatia     :  Country Code : HR
Country : Haiti     :  Country Code : HT
Country : Hungary     :  Country Code : HU
Country : Indonesia     :  Country Code : ID
Country : Ireland     :  Country Code : IE
Country : Israel     :  Country Code : IL
Country : Isle Of Man     :  Country Code : IM
Country : India     :  Country Code : IN
Country : British Indian Ocean Territory     :  Country Code : IO
Country : Iraq     :  Country Code : IQ
Country : Iran     :  Country Code : IR
Country : Iceland     :  Country Code : IS
Country : Italy     :  Country Code : IT
Country : Jersey     :  Country Code : JE
Country : Jamaica     :  Country Code : JM
Country : Jordan     :  Country Code : JO
Country : Japan     :  Country Code : JP
Country : Kenya     :  Country Code : KE
Country : Kyrgyzstan     :  Country Code : KG
Country : Cambodia     :  Country Code : KH
Country : Kiribati     :  Country Code : KI
Country : Comoros     :  Country Code : KM
Country : Saint Kitts And Nevis     :  Country Code : KN
Country : North Korea     :  Country Code : KP
Country : South Korea     :  Country Code : KR
Country : Kuwait     :  Country Code : KW
Country : Cayman Islands     :  Country Code : KY
Country : Kazakhstan     :  Country Code : KZ
Country : Laos     :  Country Code : LA
Country : Lebanon     :  Country Code : LB
Country : Saint Lucia     :  Country Code : LC
Country : Liechtenstein     :  Country Code : LI
Country : Sri Lanka     :  Country Code : LK
Country : Liberia     :  Country Code : LR
Country : Lesotho     :  Country Code : LS
Country : Lithuania     :  Country Code : LT
Country : Luxembourg     :  Country Code : LU
Country : Latvia     :  Country Code : LV
Country : Libya     :  Country Code : LY
Country : Morocco     :  Country Code : MA
Country : Monaco     :  Country Code : MC
Country : Moldova     :  Country Code : MD
Country : Montenegro     :  Country Code : ME
Country : Saint Martin     :  Country Code : MF
Country : Madagascar     :  Country Code : MG
Country : Marshall Islands     :  Country Code : MH
Country : Macedonia     :  Country Code : MK
Country : Mali     :  Country Code : ML
Country : Myanmar     :  Country Code : MM
Country : Mongolia     :  Country Code : MN
Country : Macao     :  Country Code : MO
Country : Northern Mariana Islands     :  Country Code : MP
Country : Martinique     :  Country Code : MQ
Country : Mauritania     :  Country Code : MR
Country : Montserrat     :  Country Code : MS
Country : Malta     :  Country Code : MT
Country : Mauritius     :  Country Code : MU
Country : Maldives     :  Country Code : MV
Country : Malawi     :  Country Code : MW
Country : Mexico     :  Country Code : MX
Country : Malaysia     :  Country Code : MY
Country : Mozambique     :  Country Code : MZ
Country : Namibia     :  Country Code : NA
Country : New Caledonia     :  Country Code : NC
Country : Niger     :  Country Code : NE
Country : Norfolk Island     :  Country Code : NF
Country : Nigeria     :  Country Code : NG
Country : Nicaragua     :  Country Code : NI
Country : Netherlands     :  Country Code : NL
Country : Norway     :  Country Code : NO
Country : Nepal     :  Country Code : NP
Country : Nauru     :  Country Code : NR
Country : Niue     :  Country Code : NU
Country : New Zealand     :  Country Code : NZ
Country : Oman     :  Country Code : OM
Country : Panama     :  Country Code : PA
Country : Peru     :  Country Code : PE
Country : French Polynesia     :  Country Code : PF
Country : Papua New Guinea     :  Country Code : PG
Country : Philippines     :  Country Code : PH
Country : Pakistan     :  Country Code : PK
Country : Poland     :  Country Code : PL
Country : Saint Pierre And Miquelon     :  Country Code : PM
Country : Pitcairn     :  Country Code : PN
Country : Puerto Rico     :  Country Code : PR
Country : Palestine     :  Country Code : PS
Country : Portugal     :  Country Code : PT
Country : Palau     :  Country Code : PW
Country : Paraguay     :  Country Code : PY
Country : Qatar     :  Country Code : QA
Country : Reunion     :  Country Code : RE
Country : Romania     :  Country Code : RO
Country : Serbia     :  Country Code : RS
Country : Russia     :  Country Code : RU
Country : Rwanda     :  Country Code : RW
Country : Saudi Arabia     :  Country Code : SA
Country : Solomon Islands     :  Country Code : SB
Country : Seychelles     :  Country Code : SC
Country : Sudan     :  Country Code : SD
Country : Sweden     :  Country Code : SE
Country : Singapore     :  Country Code : SG
Country : Saint Helena     :  Country Code : SH
Country : Slovenia     :  Country Code : SI
Country : Svalbard And Jan Mayen     :  Country Code : SJ
Country : Slovakia     :  Country Code : SK
Country : Sierra Leone     :  Country Code : SL
Country : San Marino     :  Country Code : SM
Country : Senegal     :  Country Code : SN
Country : Somalia     :  Country Code : SO
Country : Suriname     :  Country Code : SR
Country : Sao Tome And Principe     :  Country Code : ST
Country : El Salvador     :  Country Code : SV
Country : Sint Maarten (Dutch part)     :  Country Code : SX
Country : Syria     :  Country Code : SY
Country : Swaziland     :  Country Code : SZ
Country : Turks And Caicos Islands     :  Country Code : TC
Country : Chad     :  Country Code : TD
Country : French Southern Territories     :  Country Code : TF
Country : Togo     :  Country Code : TG
Country : Thailand     :  Country Code : TH
Country : Tajikistan     :  Country Code : TJ
Country : Tokelau     :  Country Code : TK
Country : Timor-Leste     :  Country Code : TL
Country : Turkmenistan     :  Country Code : TM
Country : Tunisia     :  Country Code : TN
Country : Tonga     :  Country Code : TO
Country : Turkey     :  Country Code : TR
Country : Trinidad and Tobago     :  Country Code : TT
Country : Tuvalu     :  Country Code : TV
Country : Taiwan     :  Country Code : TW
Country : Tanzania     :  Country Code : TZ
Country : Ukraine     :  Country Code : UA
Country : Uganda     :  Country Code : UG
Country : United States Minor Outlying Islands     :  Country Code : UM
Country : United States     :  Country Code : US
Country : Uruguay     :  Country Code : UY
Country : Uzbekistan     :  Country Code : UZ
Country : Vatican     :  Country Code : VA
Country : Saint Vincent And The Grenadines     :  Country Code : VC
Country : Venezuela     :  Country Code : VE
Country : British Virgin Islands     :  Country Code : VG
Country : U.S. Virgin Islands     :  Country Code : VI
Country : Vietnam     :  Country Code : VN
Country : Vanuatu     :  Country Code : VU
Country : Wallis And Futuna     :  Country Code : WF
Country : Samoa     :  Country Code : WS
Country : Yemen     :  Country Code : YE
Country : Mayotte     :  Country Code : YT
Country : South Africa     :  Country Code : ZA
Country : Zambia     :  Country Code : ZM
Country : Zimbabwe     :  Country Code : ZW 
以前のエントリではJava SE 8のLambdaとStream APIを使っていました。それでは、"display country"プロパティでロケールを並べ替える呼び出しを含むコードをご紹介しましょう。
package foo;

import java.util.Arrays;
import java.util.Locale;

/**
 * @author bruno borges
 */
public class Foo {

    public static void main(String[] args) {
        final String formatOutput = "Country : %s \t\t\t\t:\t Country Code : %s";

        List<String> list = 
           Arrays.asList(Locale.getISOCountries())
            .stream()
            .map(c -> new Locale("", c))
            .sorted((c0, c1) -> c0.getDisplayCountry().compareTo(c1.getDisplayCountry()))
            .map(l -> String.format(formatOutput, l.getDisplayCountry(), l.getCountry()))
            .collect(Collectors.toList());

        list.forEach(System.out::println);
    }

}
標準出力ではなく結果をリストに保存したい場合には、最後の
forEach

collect(Collectors.toList());
に変更して、変数に割り当てましょう。

2014年3月25日

[Java] Tyrus 1.5 released! Just in time for Java 8

原文はこちら。
https://blogs.oracle.com/theaquarium/entry/tyrus_1_5_released_just


1i=1njiλeλ2λ=1i=1ne(n1)λ2n1=1ne(n1)λ2n1


Tyrus 1.5(JSR 356 WebSockets APIの参照実装)がリリースされました。
Project Tyrus
JSR 356: Java API for WebSocket - Reference Implementation
http://tyrus.java.net/
バグ修正や機能改善だけでなく、最も重要なこととして、Java 8上での実行が修正されたことでしょう。そのほかにも、


JDK 8の問題に戻りますが、良い点は、Tyrus 1.5では継承された注釈付きメソッドのサポートが修正された、という点です。このことについて興味があれば、新しいTyrus 1.5について記載したPavel Bucekのエントリをチェックして下さい。
Tyrus 1.5
https://blogs.oracle.com/PavelBucek/entry/tyrus_1_5
ああ、上の数式はどうなっているのかを知りたいですか?読者の皆さんがWebSocket開発者ってことなので、2者が同時に話す確率はどれほどかを知りたいのだと思いまして…。
Probability two people will talk at the same time
http://math.stackexchange.com/questions/228319/probability-two-people-will-talk-at-the-same-time

2014年3月23日

[Java, JavaScript] Oracle Nashorn: A Next-Generation JavaScript Engine for the JVM

原文はこちら。
http://www.oracle.com/technetwork/articles/java/jf14-nashorn-2126515.html

コマンドラインツールおよびJavaアプリケーションにおける組み込みインタプリタとしてOracle Nashornを使うシナリオ

Java SE 7まで、JDKには、Mozilla RhinoベースのJavaScriptスクリプティングエンジンが同梱されていましたが、Java SE 8では、JSR 292とinvokedynamicに基づいているOracleのNashornと呼ばれる新しいエンジンが同梱されています。ECMAで規格されたJavaScriptの仕様により一層適合しており、invokedynamicでバインドされたCallsiteにより、より優れたランタイム性能を提供します。
Rhino (Mozilla Developer Network)
https://developer.mozilla.org/en-US/docs/Rhino
JSR 292: Supporting Dynamically Typed Languages on the JavaTM Platform
https://jcp.org/en/jsr/detail?id=292
この記事では、Oracle Nashornを様々な方法で利用する方法をご紹介します。jjsコマンドラインツールを使ってスタンドアロンエンジンを使うだけでなく、Javaアプリケーション内の組み込みスクリプティングエンジンとしてOracle Nashornを利用する方法を取り扱います。JavaとJavaScriptの相互運用性や、両言語のシームレスな統合による、Javaのデータ型をJavaScriptから実装したり拡張したりできることをご紹介します。
このサンプルは最新のJDK 8早期アクセスリリースを使って実行できます。また、OpenJDK 8のカスタムビルドを使うこともできます。
JDK™ 8 Early Access Releases
https://jdk8.java.net/download.html
JDK 8
http://openjdk.java.net/projects/jdk8/
OpenJDKビルドインフラストラクチャのおかげで、非常に簡単にカスタムビルドを作成できます。例えば、XCodeのコマンドラインツールがインストールされていれば、Mac OS X上で以下のコマンドで作成できます。
$ sh configure && make images
[訳注]
ご存知の通り、既にJDK 8がリリースされているので、実際の動作確認はOracle JDK 8で実施しています。また、原文のコードでは動作しない部分があったため、一部修正したコードを掲載しています。

It's Just JavaScript

Oracle Nashornを使い始めるための簡単な方法は、コマンドラインからJavaScriptプログラムを実行することですが、その目的で、OracleのJDKまたはOpenJDKのビルドには、jjsと呼ばれるコマンドラインツールが含まれています。このツールは、よく知られたjavajavacjarツールと一緒に、JDKインストールディレクトリのbin/フォルダにあります。
var hello = function() {
  print("Hello Nashorn!");
};

hello();
こんな感じで評価は簡単です。
$ jjs hello.js
Hello Nashorn!
$
コード1
var data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

var filtered = data.filter(function(i) {
  return i % 2 == 0;
});
print(filtered);

var sumOfFiltered = filtered.reduce(function(acc, next) {
  return acc + next;
}, 0);
print(sumOfFiltered);
Oracle NashornはECMA準拠の言語実装ですので、コード1のような、もっと複雑なスニペットを実行することができます。このスニペットは、偶数だけをもとのリストから残して出力し、その偶数の合計を出力します。
2,4,6,8,10
30
Oracle Nashornは runs ECMA準拠のJavaScriptを実行しますが、Webブラウザで通常アクセス可能なオブジェクト(例えばconsolewindowなど)は利用できない、ということは知っておくべき重要なことでしょう。

Scripting Extensions

jjs -helpを実行してjjsコマンドの包括的なリストを取得すると、いくつかの興味深い機能があることにお気づきになることでしょう。
  • JavaFXアプリケーションとしてスクリプトを実行することができます。
  • JavaScriptのstrictモードを有効にすることができます。
  • Java仮想マシン(JVM)用に追加のクラスパス要素を指定することができます。
  • 興味深いスクリプティングモードを有効にすることができます。
jjsを使って(PythonやRuby、またはBashのように)JavaScriptで記述されたシステムスクリプトを実行することを考えているなら、スクリプティングモードは興味深いことでしょう。スクリプティングモードは主に2個の言語拡張(ヒアドキュメントとシェル呼び出し)で構成されています。

ヒアドキュメント

ヒアドキュメントは単なる複数行の文字列であり、BashやPerl、Rubyプログラマーにとっては慣れ親しんだ構文を使います(コード2)。テキストは<<で始まり、特別な終端マーカー(今回はEOF)が続きます。書式設定は終端マーカーまでそのまま残されています。また、JavaScriptの式を${...}の式に埋め込むことができます。このプログラムを実行すると、コード3に示すような出力が得られます。
コード2
var data = {
 foo: "bar",
 time: new Date()
};

print(<<EOF);
So...
       foo = ${data.foo}
and the current time is
       ${data.time}
EOF
コード3
$  jjs -scripting heredocs.js
So...
      foo = bar
and the current time is
      Thu Aug 01 2013 16:21:16 GMT+0200 (CEST)
$ 
ご注意いただきたいのは、スクリプトモードでは、二重引用符で囲まれた文字列が評価対象の式を埋め込むことができるということです。例えば、"Hello ${name}" はnameの値に対して評価します('Hello ${name}'は評価しません)。

シェル呼び出し

シェル呼び出しを使うと、コマンドがback-tick文字の間にあるような外部プログラムの呼び出しができます。以下の例を考えてみましょう。
var lines = 
`ls -lsa`.split("\n");
for each (var line in lines) {
  print("|> " + line);
} 
この例ではls -lsaコマンドを実行しています。シェル呼び出しは、文字列として標準コンソール出力を返しますが、その中で行を分割し、先頭に|">"を追加して出力しています(コード4)。呼び出されたプロセスをより細かく、精巧な制御をする必要がある場合は、$EXEC関数があることを知っておくべきでしょう。この関数は標準入力、出力、およびエラーストリームへのアクセスを提供します。
コード4
jjs -scripting dir.js
|> total 72
|>  0 drwxr-xr-x  2 jponge  staff    238 Aug  1 16:12 .
|>  0 drwxr-xr-x  5 jponge  staff    170 Aug  1 12:15 ..
|>  8 -rw-r--r--  1 jponge  staff     90 Jul 31 23:36 dir.js
|>  8 -rw-r--r--  1 jponge  staff    304 Aug  1 15:56 hello.js
|>  8 -rw-r--r--  1 jponge  staff    143 Aug  1 16:12 heredocs.js
|>
$ 

その他

スクリプティングモードではその他にもいろいろな機能があります。
  • $ENV変数はシェルの環境変数を提供します。
  • $ARG変数はプログラムのコマンドライン引数配列です。
  • コメントは#で開始できます。UNIX系システムでスクリプトを実行可能にする上で有用です。exit(code)quit()の両関数で現在のJVMプロセスを終了することができます。 
次のexecutable.jsファイルをみてみましょう。
#!/usr/bin/env jjs -scripting
print(
"Arguments (${$ARG.length})");
for each (arg in $ARG) {
  print("- ${arg}")
} 
このJavaScriptファイルを実行可能にして、呼び出すことができます(引数は--の後に続きます)。(コード5)。
コード5
$ chmod +x executable.js
$ ./executable.js
Arguments (0)
$ ./executable.js -- hello world !
Arguments (3)
- hello
- world
- !
$ 

Embedding Oracle Nashorn

OracleのNashornを埋め込む公開APIは単純にjavax.scriptです。Oracle Nashornが使用可能であれば、そのスクリプティングエンジンはnashorn識別子を通じてアクセスできます。
コード6では、Oracle NashornにJavaアプリケーションからアクセスする方法を示しています。この中で、Nashornを使いsum関数を定義し、呼び出し、その結果を表示する関数を作成しています。
コード6
package sample1;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

public class Hello {

  public static void main(String... args) throws Throwable {
    ScriptEngineManager engineManager = new ScriptEngineManager();
    ScriptEngine engine = 
engineManager.getEngineByName("nashorn");
    engine.eval("function sum(a, b) { return a + b; }");
    System.out.println(engine.eval("sum(1, 2);"));
  }
}
このスクリプトエンジンオブジェクトは、Oracle Nashornインタプリタの唯一のエントリポイントですが、javax.script.Invocableインターフェイスにキャストすることもできます。
Invocable invocable = (
Invocable) engine;
System.out.println(
invocable.invokeFunction(
"sum", 10, 2)); 
Invocableインターフェースは、評価対象のコードをJavaインターフェースのリファレンスに変換するメソッドも提供します。 以下のように、Adderというインターフェースが存在すると仮定しましょう。
public interface Adder {
  int sum(int a, int b);
} 
評価対象のコードは2個の引数を伴うsum関数を定義しているため、実装として以下のように利用することができます。
Adder adder = 
invocable.getInterface(
  Adder.class);
System.out.println(
  adder.sum(2, 3));  
これはJavaScriptからJavaの型を拡張する便利な方法ですが、幸いにも次章でご覧戴くように、これが唯一の方法ではありません。
必ずしもすべてのJavaScriptコードは、String: java.io.Readerから評価されるわけではありません。インスタンスをつかうことも可能です(コード7)。
コード7
engine.eval(new FileReader("src/sample1/greeter.js"));
System.out.println(invocable.invokeFunction("greet", "Julien"));
スコープやスクリプティングエンジンのバインディングを定義する方法に関する情報を含めて、詳細情報はjavax.scriptのAPIを確認すべきです。

mustache.js

それでは、Javaアプリケーションから実際にJavaScriptライブラリを呼ぶことにしましょう。そのために、mustache.jsテンプレート・ライブラリを使ってみましょう。これはHTMLアプリケーションのビュー・フラグメントをレンダリングするために使用する、人気のあるテンプレートライブラリです。簡単に言えば、JSONデータオブジェクト{"name":"Bean"}とテンプレート"Hello {{name}}"を与えると、Mustacheは"Hello Bean"と描画します。とはいえ、条件、コレクションの反復などをサポートしているので、テンプレートエンジンは、それ以上のことができるのですがね。
mustache.jsをダウンロードしたと仮定しましょう。コード8はJavaとの統合例です。
mustache.js - Logic-less {{mustache}} templates with JavaScript
https://github.com/janl/mustache.js
コード8
package sample2;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import java.io.FileReader;

public class Mustache {

  public static void main(String... args) throws Throwable {
    ScriptEngineManager engineManager = new ScriptEngineManager();
    ScriptEngine engine = engineManager.getEngineByName("nashorn");
    engine.eval(new FileReader("src/sample2/mustache.js"));
    Invocable invocable = (Invocable) engine;

    String template = "Email addresses of {{contact.name}}:\n" +
        "{{#contact.emails}}\n" +
        "- {{.}}\n" +
        "{{/contact.emails}}";

    String contactJson = "{" +
        "\"contact\": {" +
        "\"name\": \"Mr A\", \"emails\": [" +
        "\"contact@some.tld\", \"sales@some.tld\"" +
        "]}}";
    Object json = engine.eval("JSON");
    Object data = invocable.invokeMethod(json, "parse", contactJson);

    Object mustache = engine.eval("Mustache");
    System.out.println(invocable.invokeMethod(
mustache, "render", template, data));
  }
} 
Oracle Nashorn用のスクリプティングエンジンへの参照を取得した後、mustache.jsコードを評価します。その後、StringとしてMustacheテンプレートを定義します。データモデルは、JSONオブジェクトである必要があります。今回の場合、まず、それを文字列として定義し、JSON.parseを呼び出してJSONオブジェクトにした上で、Mustache.renderを呼び出すことができます。このプログラムを実行すると、以下のような出力を得ることができます。テンプレートのレンダリングのためにmustache.jsを呼び出しています。
$ java sample2.Mustache 
Email addresses of Mr A:
- contact@some.tld
- sales@some.tld

$ 

Java Seen from Oracle Nashorn

たいていの場合、Java APIをOracle Nashornから呼び出すのが簡単でしょう。結果としてのコードはJavaScript内で書かれたJavaです。
コード9
print(java.lang.System.currentTimeMillis());

基本的な例

System.currentTimeMillis() という静的メソッドを呼び出すことができます(コード9)。Javaオブジェクトをnewでインスタンス化できます。
var file = 
new java.io.File("sample.js");
print(file.getAbsolutePath());
print(file.absolutePath); 
java.io.FileabsolutePathメソッドやパブリックフィールドを定義していませんが、Oracle Nashornはそのためのプロパティを推測するため、file.absolutePathという表現はfile.getAbsolutePath()と同等であることに注意してください。実のところ、Oracle NashornはgetXY()setXY(value)メソッドをプロパティとして扱います。


配列を取り扱う

次のスニペットではjava.util.LinkedListのインスタンスとしてキューを取り込みます。
var stack = 
new java.util.LinkedList();
[1, 2, 3, 4].forEach(function(item) {
  stack.push(item);
});

print(stack);
print(stack.getClass()); 
このコードでは次のような出力を得ます。我々が直接JavaScriptからJavaオブジェクトを操作していることを確認できます。
[4, 3, 2, 1]
class java.util.LinkedList 
また、この場合では最も効率的な方法ではありませんが、コレクションをソートするために、新しいJava8のstream APIを使ってコレクションのソートすることもできます。
var sorted = stack
  .stream()
  .sorted()
  .toArray();
print(sorted); 
今度は[Ljava.lang.Object;@473b46c3のような感じで出力されますが、これはJavaネイティブ配列を示しています。しかし、Java配列はJavaScript配列とは異なります。内部的には、Oracle Nashornはjava.util.Mapを実装するカスタムクラスを使ってJavaScript配列を提供しています。Javaオブジェクトが提供するOracle Nashornのtoメソッドとfromメソッドを使い、変換を実行することができます。
var jsArray = Java.from(sorted);
print(jsArray);

var javaArray = 
Java.to(jsArray);
print(javaArray); 
結果は以下のような感じです。
1,2,3,4
[Ljava.lang.Object;@23a5fd2

クラスのインポート

デフォルトでは、Javaの型への参照はすべて、完全修飾する必要があります(例えば、java.lang.Stringjava.util.LinkedHashSetなど)。Oracle Nashornは、デフォルトではjavaパッケージをインポートしません。それは、StringObjectへの参照がJavaScriptにおける対応する型と競合するためです。そのため、Javaの文字列は、Stringではなくjava.lang.Stringです。
Mozilla Rhinoは、Oracle Nashorn登場前にOracle JDKのリリースで提供していたJavaScriptエンジンの実装でした。サードパーティのJavaScriptファイルをロードする、load(path)関数が特徴でしたが、まだOracle Nashornにもありますので、これを使うと、(Javaでの明示的なインポートのように)クラスをインポートするためのimportClassや、(Javaでのワイルドカード・インポートのように)パッケージをインポートするimportPackageを提供する特別な互換性モジュールをロードすることができます。
load(
"nashorn:mozilla_compat.js");

importClass(java.util.HashSet);
var set = new HashSet();

importPackage(java.util);
var list = new ArrayList(); 
こうした関数は、シンボリックリファレンスを、解釈対象のJavaScriptのコードのグローバルスコープにインポートするということを覚えておきましょう。これらの関数はまだ互換性のためにサポートされていますが、mozilla_compat.jsimportClassの使用は推奨されません。代わりに、JavaImporterという、Mozilla Rhinoの遺産から生まれた別の関数を使うことが推奨されています(コード10)。
コード10
var CollectionsAndFiles = new JavaImporter(
    java.util,
    java.io,
    java.nio);

with (CollectionsAndFiles) {
  var files = new LinkedHashSet();
  files.add(new File("Plop"));
  files.add(new File("Foo"));
  files.add(new File("w00t.js"));
} 
JavaImporterは、Javaパッケージとして可変引数を取り、指定したパッケージのインポートが含まれるスコープを持つ文を使って、返却されたオブジェクトを使うことができます。グローバルJavaScriptスコープは影響を受けません。JavaImporterimportClassimportPackageのずっとよい代替手段です。


オーバーロードされたメソッド

Javaは、メソッドのオーバーロード、つまり、一つのクラス内に同じ名前で異なるシグネチャを持ついくつかのメソッドを定義することができます。 java.io.PrintStreamクラスがいい例で、オブジェクト、文字列、配列、およびプリミティブ型のための多くのprintメソッドやprintlnメソッドのprintlnメソッドを提供しています。
Oracle Nashornは呼び出し毎に実行時に適切なターゲットを選択します。これはつまり、Java APIを使う際にオーバーロードされたメソッドを心配する必要がない、ということです。それでも、必要であれば、ターゲットを正確に選択する方法があります。こうした要求は次のような条件で曖昧なパラメータを使っているときによく発生します。それは、異なるインターフェース型をオーバーロードされたメソッドが許容している(例えばjava.util.concurrentのExecutorServiceのsubmitメソッドを使っている)関数オブジェクトを渡している場合によく起こります。
次のコードでは、printlnの最初の呼び出しは、println(String)のオーバーロードされたメソッドを選択します。2回目の呼び出しではJavaScriptのobjectプロパティを使ってprintln(Object)バリアントにアクセスします。渡される文字列は、Oracle Nashornが解決時に使用している署名を提供します。注意いただきたいのは、例外的に、 Javaパッケージにあるクラスは、修飾されている必要はありません。したがって、有効だけど長くなるprintln(java.lang.Object)の代わりに、println(Object)と書くことができます。
var stdout = 
java.lang.System.out;
stdout.println("Hello");
stdout["println(Object)"]( 
"Hello");

Typeオブジェクト

Java.type 関数を使って、正確なJavaの型への参照を取得することができます。これらにはオブジェクトだけでなくプリミティブ型や配列も含まれます。
var LinkedList = Java.type(
"java.util.LinkedList");
var primitiveInt = Java.type(
"int");
var arrayOfInts = Java.type(
"int[]"); 
返されるオブジェクトは、Javaの型へのマッピングのOracle Nashorn固有表現です。これらはjava.lang.Classのインスタンスとは異なるので注意が必要です。Typeオブジェクトはコンストラクタとして、そしてinstanceofベースの比較において便利です。コード11を見てみましょう。
コード11
var list = new LinkedList;
list.add(1);
list.add(2);
print(list);
print(list instanceof LinkedList);

var a = new arrayOfInts(3);
print(a.length);
print(a instanceof arrayOfInts);
TypeオブジェクトとJavaクラスの参照の間を行き来できます。Typeオブジェクトのclassプロパティは、java.lang.Classにおける同等のものを返します。同様に、対応する型オブジェクトを取得すると、staticプロパティをjava.lang.Classインスタンスで利用できるようになります。
コード12
print(LinkedList.class);
print(list.getClass().static);
print(LinkedList.class === list.getClass());
print(list.getClass().static === LinkedList);
コード12のコードでは、以下のような出力を得ます。
class java.util.LinkedList
[JavaClass java.util.LinkedList]
true
true 

Extending Java Types

Oracle NashornではJavaの型をJavaScriptから拡張するためのシンプルなメカニズムを提供しています。インターフェース実装と具象サブクラスを提供できることは重要です。

インターフェースの実装

Javaインタフェースを考えた場合、実装を提供するための簡単な方法は、インスタンス化し、コンストラクタ関数に実装対象のメソッドがプロパティとして与えられているJavaScriptオブジェクトを渡すことです。
コード13では、nextメソッドとhasNextメソッドの実装を与えて、java.util.Iteratorの具体的な実装を提供しています(removeメソッドはJava8のデフォルトメソッドが提供しています)。これを実行し、期待通りに動作するか確認できます(コード14)。
コード13
var iterator = new java.util.Iterator({
  i: 0,
  hasNext: function() {
    return this.i < 10;
  },
  next: function() {
    return this.i++;
  }
});

print(iterator instanceof Java.type("java.util.Iterator"));
while (iterator.hasNext()) {
  print("-> " + iterator.next());
} 
コード14
true
-> 0
-> 1
-> 2
-> 3
-> 4
-> 5
-> 6
-> 7
-> 8
-> 9 
インターフェイスが単一のメソッドで構成されている場合に、関数オブジェクトを直接渡すことができます。その際、明示的にnew演算子を呼び出す必要はありません。コード15の例では、collection streamsで説明しています。
コード15
var list = java.util.Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
var odd = list.stream().filter(function(i) {
  return i % 2 == 0;
});
odd.forEach(function(i) {
  print(">>> " + i);
}); 
コード15のコードを実行すると、以下のような結果が得られます。
>>> 2
>>> 4
>>> 6
>>> 8 
Oracle Nashornは、Oracle Nashorn関数の形で言語拡張することもできる点は注目すべきでしょう。つまり、小さなラムダ関数のために簡略化した構文を提供します。これは、Java APIから単一の抽象メソッド型を期待されているところでもどこでも使えます。そのため、コード15の以下のコードを
var odd = list.stream().filter(
  function(i) {
  return i % 2 == 0;
}); 
このように書き換えることができます。
var odd = list.stream().filter(
  function(i) i % 2 == 0);
この言語拡張はラムダ式をサポートする新しいJava SE 8 APIを扱う際に便利です。その理由は、Javaのラムダ式を期待される箇所のどこででもJavaScriptの関数を使うことができるからです。また、このより短縮形をJavaScript 1.8エンジンがサポートすることにもご注意下さい。
抽象クラスの場合はインターフェースと同じです。つまり、必要なメソッド実装を伴うJavaScriptオブジェクトをそのコンストラクタ関数に提供します。または、単一の抽象メソッドクラスのインスタンスを必要とする場合には関数を直接渡します。

インスタンスバインドされた実装の使用

具象クラスを拡張するために、Java.extend関数を使う必要があります。第1引数として拡張対象の基本クラスを意味する型オブジェクトをとります。パラメータがインターフェース型の場合、ベースクラスはjava.lang.Objectに仮定します。追加のパラメータとして他のタイプを与えることで、実装されたインターフェースのセットを指定することができます。
コード16の例を考えてみましょう。Java.extend関数は、extenderと呼ばれるTypeオブジェクトを返します。これを呼び出して、具象サブクラスを作成することができます。今回の場合、instancejava.lang.Objectのサブクラスであり、java.lang.Comparablejava.io.Serializable)の2個のインターフェースを実装しています。この実装を、コンストラクタに渡されたJavaScriptオブジェクトを介して作成されたインスタンスに渡します。
コード16
var ObjectType = Java.type("java.lang.Object");
var Comparable = Java.type("java.lang.Comparable");
var Serializable = Java.type("java.io.Serializable");

var MyExtender = Java.extend(
ObjectType, Comparable, Serializable);
var instance = new MyExtender({
  someInt: 0,
  compareTo: function(other) {
    var value = other["someInt"];
    if (value === undefined) {
      return 1;
    }
    if (this.someInt < value) {
      return -1;
    } else if (this.someInt == value) {
      return 0;
    } else {
      return 1;
    }
  }
});

print(instance instanceof Comparable);
print(instance instanceof Serializable);
print(instance.compareTo({ someInt: 10 }));
print(instance.compareTo({ someInt: 0 }));
print(instance.compareTo({ someInt: -10 }));
コード16のコードを実行すると、以下のようにコンソールに出力されます。
true
true
-1
0
1 

クラスバインドされた実装の使用

実装はインスタンス毎に違いますが、同じextenderタイプから作成したインスタンスは同じクラスを共有しています(コード17)。
コード17
var anotherInstance = new MyExtender({
  compareTo: function(other) {
    return -1;
  }
});

// Prints 'true'!
print(instance.getClass() === anotherInstance.getClass());
これは多くの場合問題ありませんが、各インスタンスに実装を渡すのは、必ずしも便利とは限りません。実際、依存性注入のAPIに見られるようなオブジェクトをそのような制御の反転メカニズム機構の形を通じてインスタンス化する必要がある場合も存在します。このような場合には、3rdパーティのAPIは通常、以前の実装クラスへの参照が必要であり、先ほどのextenderメカニズムは不適切です。
幸いなことに、Java.extendを使い、実装をクラス定義にバインドすることができます(各インスタンスに対して実装を指定する必要はありません)。そのためには、最後のパラメータとしてJavaScriptの実装オブジェクトを渡して挙げればよいのです。

コード18の場合、FooCallableBarCallableという2個のextenderタイプを定義しています。foobarのインスタンスを作成する際には、実装を渡す必要はありません。インスタンスに同じクラス定義がないことを確認することもできます。実は、FooCallable.classBarCallable.classjava.lang.Class定義のインスタンスが必要な3rdパーティーJava APIに渡すことができます。
コード18
var Callable = Java.type("java.util.concurrent.Callable");

var FooCallable = Java.extend(Callable, {
  call: function() {
    return "Foo";
  }
});

var BarCallable = Java.extend(Callable, {
  call: function() {
    return "Bar";
  }
});

var foo = new FooCallable();
var bar = new BarCallable();

// 'false'
print(foo.getClass() === bar.getClass());

print(foo.call());
print(bar.call());
この例では説明されていませんが、クラスバインドされた実装で定義されたクラスはそのスーパークラスから継承したコンストラクタを提供します。この例では、オブジェクトが暗黙的にjava.lang.Objectを拡張し、java.util.concurrent.Callableを実装しています。そのため、対応するクラス定義は引数を伴わないパブリックなコンストラクタを有します。

インスタンスバインドされた実装とクラスバインドされた実装の利用

大事なことを言い忘れていましたが、インスタンスバインドされた実装とクラスバインドされた実装を組み合わせることができます。実装オブジェクトをコンストラクタに渡すことで、メソッドの全てもしくは一部クラスバインドされた実装を改善することができます(コード19)。
コード19
var foobar = new FooCallable({
  call: function() {
    return “FooBar”;
  }
});

// 'FooBar'
print(foobar.call());

// 'true'
print(foo.getClass() === foobar.getClass());  

Conclusion

この記事では、コマンドラインツールとして、そしてJavaアプリケーションに埋め込まれたインタプリタとしてOracle Nashornを使用するための様々なシナリオを説明しました。また、JavaScriptからJavaの型を実装して拡張する機能など、JavaとJavaScriptの相互運用性についても取り扱いました。

Oracle Nashornは、JVM上の多言語アプリケーションのためのスクリプト言語を活用するための優れた方法です。JavaScriptは人気のある言語であり、幅広いユースケースでJavaとJavaScriptの間の相互作用はシームレスで簡単です。

著者について

Julien Ponge (@jponge)は、現在INSA de Lyonでコンピュータ理工学の准教授であり、長年オープンソースに携わってきた、いわば職人です。彼はCITI研究室の活動の一環として、プログラミング言語、仮想マシン、およびミドルウェアを主たる研究分野としています。
Département Télécommunications - INSA de Lyon
https://telecom.insa-lyon.fr/

2014年3月21日

[Java] An Embedded Java 8 Lambda Expression Microbenchmark

原文はこちら。
https://blogs.oracle.com/jtc/entry/an_embedded_java_8_lambda

長い道のりでしたが、Java 8がついにやってきました。このリリースに含まれる新機能についてたくさんの場所で記述されたり発表されたりしていますが、おそらく最も重要なのはラムダ式(Lambda Expression)の導入でしょう。ラムダは密接にJavaプラットフォームに統合されており、並列プログラミングの伝統的にトリッキーなところで開発者を支援する可能性があります。
JavaOne 2013: Lambda Expressions
https://blogs.oracle.com/thejavatutorials/entry/javaone_2013_lambda_expressions
もう一つ、Compact Profilesは、以前は小さすぎると考えられていた組み込みプラットフォームに対し、Java Standard Editionの互換性という途方もない利点を利用できるようになります。
An Introduction to Java 8 Compact Profiles
https://blogs.oracle.com/jtc/entry/a_first_look_at_compact
どこに向かっているかわかりますよね?同時に2つの技術を使用し、どのように連携するかを調べるのも楽しいかもしれません。このエントリでは、ちょっとしたプログラムの説明とその性能測定を実施します。言うなればマイクロベンチマークですね。その目的は、新しいラムダ式のパラダイムを使用したプログラミングは、一般的なデスクトップおよびサーバ用途だけでなく、どんどん増え続ける組み込みプラットフォーム用途にも成長させるためだけでなく、有益であることをご紹介するためです。

The Hardware/OS Platform(s)

この記事ではBoundary DevicesのBD-SL-i.MX6というシングルボードコンピュータを使います。1GB RAMが載る、クアッドコアのARM® Cortex™-A9ベースのシステムで、armhf Debian Linuxディストリビューションが動きます。この記事を書いた時点で、表示価格は199 USドルです。
Boundary Devices BD-SL-i.MX6
http://boundarydevices.com/products/sabre-lite-imx6-sbc/
imx6q_sabrelite_top1
もっとおもしろくするために、デバイス上でJava8ラムダ式を実行するだけではなく、新しいJava8 Compact1 Profileの範囲内でラムダ式を実行することにします。このJava実行環境の静的フットプリントは10.5MBです。
組込み機器とは能力もキャパシティもまったく異なるもう一つのシステムを比較対象とし、異種ハードウェアおよび異種OS環境間で実行の挙動を比較するために利用します。そのシステムは、Windows7/64-bitを実行している東芝Tecra R840というノートパソコンです。これは、8GBのRAMを搭載したデュアルコア Intel®Core™ i5-2520Mプロセッサを搭載しており、64ビット版Windows用の標準的なJava8ランタイム環境(JRE)を使用しています。
Tecra R840 Laptops & Notebooks (Toshiba Direct)
http://www.toshiba.com/us/computers/laptops/tecra/R840/

The Application

私たちの基本的なアプリケーションの基礎としてサンプルデータセットを探していたところ、理想的(にして架空の)従業員情報のデータベースを以下のリンクから入手できます。
Sample database with test suite
https://launchpad.net/test-db
利用可能なフォーマットの中で、約30万件のエントリーを含むカンマ区切りのCSVファイルが供給されています。今回のサンプルアプリケーションでは、このファイルを読み、LinkedList<EmployeeRec>に従業員レコードを格納します。 EmployeeRecには次のようなフィールドがあります。
public class EmployeeRec {
    private String id;
    private String birthDate;
    private String lastName;
    private String firstName;
    private String gender;
    private String hireDate;
    ...
}
このデータ構造を初期化し、アプリケーションを使って、男性従業員全員の平均年齢を計算する、という簡単なタスクを実行してみましょう。

Old School

まずは、この計算をラムダ式が利用できなかった時代のやり方で実施してみます。この方法をOldSchoolと呼ぶことにします。計算コードは以下のような感じになります。
double sumAge = 0;
long numMales = 0;
for (EmployeeRec emp : employeeList) {
    if (emp.getGender().equals("M")) {
        sumAge += emp.getAge();
        numMales += 1;
    }
}
double avgAge = sumAge / numMales;

Lamba Expression Version 1

2個目のバリエーションでは、ラムダ式を使って実行してみます。このバージョンをLamba stream()と呼ぶことにしましょう。Java 8での主要ステートメントは以下のような感じになります。
double avgAge = employeeList.stream()
                .filter(s -> s.getGender().equals("M"))
                .mapToDouble(s -> s.getAge())
                .average()
                .getAsDouble();

Lambda Expression Version 2

最後のバリエーションでは、前述のラムダ式にもう少し修正を入れてみます。つまり、 stream() メソッドの代わりに parallelStream() mメソッドを使います。これによりタスクを分割して個別のスレッドで動作する小さな単位に分割することができるようになります。このバージョンをLambda parallelStream()と呼ぶことにしましょう。Java 8のステートメントは以下のようになります。
double avgAge = employeeList.parallelStream()
                .filter(s -> s.getGender().equals("M"))
                .mapToDouble(s -> s.getAge())
                .average()
                .getAsDouble();

Initial Test Results

前述の3個のバリエーションを使って解いたサンプル問題の実行時間をグラフ化し、下にまとめました。左図は、ARM Cortex-A9プロセッサで記録した時間を表し、右図はIntel Core-i5で記録した時間を表しています。より小さな結果であるほどより高速なのですが、両方の結果から、ラムダの直列stream()を活用すると多少のオーバーヘッドがあり、old schoolのラムダ式以前の解法結果より時間がかかっていることがわかります。parallelStream()に関する限り、何とも言えません。Cortex-A9では、parallelStream()オペレーションはOld School方式とはほとんど差がないのに対し、Core-5では、parallelStream()がもたらすオーバーヘッドのために遅くなっています。

ここまでで終えると、並列ストリームがあまり役にたたないと結論付ける人が出てくるかもしれません。しかし、30万人の従業員のリストといった些細な計算を実行するぐらいでは、並列化の利点を示すのには十分ではないと思うんですよね。この次のテストでは、どれほどパフォーマンスが影響を受けるかを確認するために、計算負荷を増加させることにしましょう。

Adding More Work to the Test

今回は、同じ問題を解く(男性の平均年齢を計算する)のですが、それだけでなく、様々な量の中間での計算を追加しています。プログラムに次のidentityメソッドを追加し、必要な計算サイクルの数を変化させながら増やすことができます。
/*
 * Rube Goldberg way of calculating identity of 'val',
 * assuming number is positive
 */
private static double identity(double val) {
    double result = 0;
    for (int i=0; i < loopCount; i++) {
        result += Math.sqrt(Math.abs(Math.pow(val, 2)));    
    }
    return result / loopCount;
}
このメソッドは数値の二乗の平方根をとるため、本質的に高価な恒等関数です。 loopCountの値を変更することにより(これはコマンドラインオプションで指示)、identity()メソッド呼び出しごとのこのループ実行回数を変動させることができます。このメソッドを3個のコードに追加します。例えばラムダのParallelStream()バージョンでは以下のようになります。
double avgAge = employeeList.parallelStream()
                    .filter(s -> s.getGender().equals("M"))
                    .mapToDouble(s -> identity(s.getAge()))
                    .average()
                    .getAsDouble();
identity()メソッドの追加はOld SchoolやLambda Stream()バージョンにも適用しています。Rube Goldbergのような、identity()関数のloopCount内部変数にそれぞれ別の値を与え、その状態でマイクロベンチマークを3回実行した結果をまとめました(下図)。

Cortex-A9では、ループ回数が100に設定されている場合、明らかにparallelStream()のパフォーマンス上の利点を確認できますし、ループ回数が500に増加した場合、その利点はよりいっそう顕著になっています。Core-i5では、parallelStream()の利点を目にするためにはより多くの負荷をかける必要があります。ループカウントを50,000に設定してようやくパフォーマンス上の利点が明らかになることがわかります。Core-i5はたった2コアでとにかく速いため、結果として、parallelStream()の初期オーバーヘッドを上回るためにはもっと多くの負荷が必要というわけです。

Downloads

この記事で試用したサンプルコードはNetBeansプロジェクトとしてお試しいただけます。プロジェクトには30万件以上のエントリを含むCSVファイルが同梱されていますので、想定よりも大きなファイルサイズになってしまいました。このブログ環境(blogs.oracle.com)は2MBを超えるファイルを格納できないので、このプロジェクトソースを圧縮し、3個のファイルに分割しました。以下が3個のファイルのリンクです。
ダウンロードした3個のファイルを結合し、元のLambdaMivrobench.zipファイルを再作成するだけです。Linuxであれば、以下のようなコマンドで結合できます。
$ cat LambdaMicrobench.zip.part? > LambdaMicrobench.zip

Conclusion

多大な労力を費やしてJava8ははるかに普遍的なプラットフォームになりました。10.5MB程度の小さな組み込みJava実行環境であっても最新の進歩を活用できる​​ことがこの簡単なサンプルからわかりますが、これはほんの始まりに過ぎません。並列ストリームラムダ式の性能特性を向上させるためにはまだまだやるべきことがたくさんあります。将来の機能拡張を楽しみにしています。

2014年3月20日

[EM] Oracle OpenWorld 2014 Call for Proposals is now open!

原文はこちら。
https://blogs.oracle.com/oem/entry/oracle_openworld_2014_call_for

また1年がすぎて、この時がやってきました。Oracle OpenWorld 2014のCall for Proposalの受付がスタートしました。OpenWorld 2014 Call for Proposalに関する情報は以下のリンクからどうぞ。
Call for Proposals
http://www.oracle.com/openworld/call-for-papers/index.html
Call for Proposalは2014年3月18日から2014年4月15日(PDT)までです。

昨年OpenWorldの2013で、これまでで最も多くのお客様やパートナー様がOracle Enterprise Managerのアクティビティに参加いただきましたので、今年のOpenWorld 2014ではしっかり準備してきています。Oracle Enterprise Managerの多種な分野にわたり、様々なお客様事例、ベストプラクティス、専門家のアドバイスをわくわくしながら披露していました。昨年のハイライトのいくつかは、このブログの以前のエントリで拾うしていますが、もっとたくさんのハイライトがあったのです。
本気で私達の顧客やパートナーを紹介し、経験豊富な新しい発表者に参加戴きたいと考えています。皆様からのすべてのご提案を慎重に検討することを約束します。
是非この機会を利用し、OpenWorld 2014をあなたにとって、そしてOracle Enterprise Managerにとってよりよいイベントにするために、4月15日までにあなたの提案を送ってください。
あなたの創造性と熱意をお待ちしています。皆様からのご提案を拝読できることを楽しみにしています。

2014年3月18日

[Security, Database, Solaris] NIAP Recommends no further Common Criteria Evaluation of Operating Systems & DBMS

原文はこちら。
https://blogs.oracle.com/darren/entry/niap_recommends_no_further_common

NIAP(国家情報保証パートナーシップ:National Information Assurance Partnership)が汎用目的のオペレーティング・システム(例えばSolarisやLinux、Windows、MacOS、AIXなど)およびDBMS(例えばOracle DatabaseやMySQL、DB2など)のための将来の共通基準(Common Criteria)となる評価プロファイルに関する基本方針表明(public position statements)を発表しました。
NIAP(National Information Assurance Partnership)
Documents and Guidance  » guidance docs
https://www.niap-ccevs.org/Documents_and_Guidance/guidance_docs.cfm
Position Statement regarding the CC evaluation of General Purpose Operating Systems
https://www.niap-ccevs.org/Documents_and_Guidance/ccevs/GPOS%20Position%20Statement.pdf
Position Statement regarding the CC evaluation of DBMS
https://www.niap-ccevs.org/Documents_and_Guidance/ccevs/DBMS%20Position%20Statement.pdf
NIAPは、コストおよび複雑性を理由として、共通基準プロファイルの今後のさらなる開発を勧めず、GPOSやDBMSシステムの評価を勧めない、ということです。

この件でお客様として影響を受ける可能性がある場合、購入や展開の決定にNIAPポリシーが影響を与える可能性がある場合、または、たとえあなたが米国を拠点としてなくてもこのNIAPの声明によって影響を受ける可能性がある場合、直接NIAPにコンタクトして下さい。
NIAPのコンタクト先
https://www.niap-ccevs.org/Contact_Us/

[ご注意]
このエントリは、GPOSやDBMSシステムへの共通基準(CC)評価の適用可能性に関する個人的な声明でも、Oracleの声明でもありません。

Oracle製品の評価状況については、以下のページをご覧下さい。
Oracle Security Evaluations
http://www.oracle.com/technetwork/topics/security/security-evaluations-099357.html

[Solaris] Solaris Studio 12.4 Beta is coming

原文はこちら。
https://blogs.oracle.com/partnertech/entry/solaris_studio_12_4_beta

Oracle Solaris Studioチームは、2014年3月末のリリースに向けて、Oracle Solaris Studio 12.4 Betaのリリースの準備が完了し(製品のGAは2014年下半期を予定)、ISVの皆様やお客様のBetaテストへの参加ノミネートを受付中です。

Oracle Solaris Studio 12.4 Beta版の新機能には以下のものが含まれています。
  • Oracle SPARC-T4/T5/M5/M6、Fujitsu M10、Intel Ivy Bridge搭載のサーバーに対する、コンパイラおよびライブラリの最適化
  • C++ 2011標準をサポートする新しいC++コンパイラおよびdbxデバッガ
  • アプリケーションのパフォーマンス分析をガイドする新たなSmart Start機能やリモートデータ分析、クロスアーキテクチャのサポートを含む、Performance Analyzerの機能改善
  • オーバーヘッドの削減、メモリリークや40個の他の典型的なプログラミング上のエラー検出の精度向上といった、Code Analyzerの機能改善 
  • 領域のキャンセル、スレッド・アフィニティ、タスクの拡張、逐次一貫なアトミックを含む、新しいOpenMP 4.0標準のサポート。
  • 応答時間の短縮や大規模なソースリポジトリを取り扱う際のメモリ使用量の削減といった、統合開発環境(IDE)の機能改善
Oracle Solaris Studio Platinum Betaプログラムの詳細をご覧になりたい方は以下のリンクをどうぞ。
Oracle Solaris Studio 12.4 Platinium Beta Program
http://www.oracle.com/technetwork/server-storage/solarisstudio/beta-customer-participation-2140451.html

2014年3月14日

[FMW, Mobile] Oracle ADF Mobile Patch 6 Released - Speeding Up Android Apps

原文はこちら。
https://blogs.oracle.com/mobile/entry/oracle_adf_mobile_patch_6

モバイルの世界では動きが速いため、ADF Mobileチームも忙しくその動きに対応する必要があります。
2ヶ月ほど前に、新しいLook and FeelをADF Mobileアプリケーションにもたらすパッチを出しましたが、さらにもう一つの新しいパッチ、Patch 6をリリースしました。
New Enhancement Released for iOS7+Android Native Look & Feel and Xcode 5 Support(前回のパッチに関するエントリ)
https://blogs.oracle.com/mobile/entry/new_enhancement_released_for_xcode5
Android OS上で開発、テスト、実行すると、その大きな違いを感じてもらえることでしょう。Android上で動作するADF Mobileアプリケーションの初期起動時間を劇的に改善しました。何が劇的かというと、我々のテストでは、ADF Mobileアプリケーションが以前よりも5倍速く起動するようになっています。
JDeveloperで[ヘルプ]>[更新の確認]をクリックし、ADF Mobileのパッチをダウンロードして、是非その違いを確かめて下さい。

[WLS] WebLogic 12.1.3 Preview (Video)

原文はこちら。
https://blogs.oracle.com/WebLogicServer/entry/weblogic_12_1_3_preview

将来リリース予定のWebLogic Server 12.1.3に関するWebcastを開催できました。Product ManagementチームのSteve Buttonが現在の状況と将来の予定に関するすてきな概要の動画を紹介してくれています。
以下のリンクから、是非「On-Demand」セクションにある、無料でご覧戴ける動画をご覧下さい。

[訳注]
On-Demandセクションの「Developer Preview: Oracle WebLogic Server 12.1.3」です。
Oracle WebLogic DevCast Series
https://event.on24.com/eventRegistration/EventLobbyServlet?target=registration.jsp&eventid=408818&sessionid=1&key=86F39F9548565AA9FB85838C520C4FD0

2014年3月12日

[BPM] Oracle Process Accelerators 11.1.1.7.1 now available on OTN

原文はこちら。
https://blogs.oracle.com/bpm/entry/oracle_process_accelerators_11_1

Oracle Process Accelerators(以下、PA) 11.1.1.7.1がOTNからダウンロードできるようになっています。
Oracle Process Accelerators™
http://www.oracle.com/technetwork/middleware/processaccelerators/overview/index.html
この新しいリリースでは、お客様からの要望をうけてPAを改善することに注力しつつ、Adaptive Case ManagementやOracle Applicationsの拡張といった、BPMの新機能のショーケースとなるようなソリューションを開発しました。

PAのポートフォリオに保険業界が追加されました。このリリースでは、金融サービスや公共セクター向けのすぐ使えるBPMソリューションも増えています。

最新のリリースには以下の2個のPAが追加されています。
  • 保険金請求管理(ICM)
    ICMは最初のAdaptive Case Management (ACM)を使ったPA(CA、Case Accelerator)です。請求はそれぞれ異なるため、ACMが請求業務シナリオにすばらしく適合します。ナレッジワーカーは通常、判断の上最善のアクションをそのタイミングで実施するため、請求処理の流れが変わることがあります。業務シナリオ(自動車保険)に基づいており理解しやすく、それでいて機能がリッチなので、様々な業種の多くの他の業務プロセスにもICMモデルを適合することができます。拡張可能なUIとビジネスルールを使った現実に使えるACMソリューションになっています。
  • ローン組成
    Oracle Process Accelerator for Loan Originationは、個人ローンも法人ローンもサポートします。拡張されたFinancial Frameworkを基盤としているため簡単に拡張可能でき、ローンの種類を追加することができます。
PA 11.1.1.7.1にはすぐに使えるOracle E-Business Suiteとの統合シナリオも含まれています。これは既に提供しているPeoplesoftやSiebelとの統合シナリオに加え、入社手続き(Employee Onboarding)についてE-Business SuiteとのEnd to Endの業務フローを提供します。

他のPAも機能改善されています。特にeForms(電子フォーム)管理については、市民からのeForm提出が加わりました。財務レポートの承認はお客様からの声を基にして、Microsoft ExcelのExtensionを使い財務レポートの承認プロセスが可能になるように機能強化しました。

この新しいリリースに関する近日開催予定のWebcastをお待ち下さい。