Jun 02, 2009

[Mustang] Java 配備ツールキットに関するメモ

JavaSE 6u10 で Java 配備ツールキット という機能が追加された。 Java 配備ツールキットを利用することで、クライアントにインストールされている JavaSE 環境の取得や、クライアントへの JavaSE 環境のインストールなどを行うことができる。 この機能は JavaScript ファイル(deployJava.js) で提供されている。 Applet や Java Web Start によるスマートクライアントなどを実装するときに是非活用したい機能だ。 関連情報をメモしておく。

Java 配備ツールキット
http://java.sun.com/javase/ja/6/ea/6u10/deploymentToolkit.html
Java Web App Deployment Advice for JavaSE 6u10
http://java.sun.com/javase/6/docs/technotes/guides/jweb/deployment_advice.html

Posted in Mustang | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Jun 20, 2006

[Mustang] Derby in Mustang にチャレンジ

色々なところで話題になっているようだが、Derby が Mustang に同梱されるらしい。 公式には Java DB という DBMS が搭載されるということだが、Java DB のサイトには

What's Java DB?

Java DB is Sun's supported distribution of the open source Apache Derby 100% Java technology database. It is fully transactional, secure, easy-to-use, standards-based -- SQL, JDBC API, and Java EE -- yet small, only 2MB. The Apache Derby project has a strong and growing community that includes developers from large companies such as Sun Microsystems and IBM as well as individual contributors.
と記述されているので、Java DB == Derby ということだろう。

ユニットテストやプロトタイプ開発時など「とりあえず何でもいいから DBMS が欲しい」というときに Derby を結構使うので同梱してくれるのは多少嬉しい。 ・・・ Maven2 使っていれば別に同梱してくれなくてもすぐ使えるけれど。
Java DB is bundled in Mustang
http://weblogs.java.net/blog/davidvc/archive/2006/06/java_db_is_bund.html
Java DB
http://developers.sun.com/prodtech/javadb

Derby in Mustang のインストール

早速 Java Platform, Standard Edition 6 Binary Snapshot Releases から jdk-6-rc-bin-b88-windows-i586-15_jun_2006.exe をダウンロードしてインストールしてみた。 インストールされた J2SE SDK を見てみると、%JAVA_HOME%\db に Derby がそのまま同梱されていることが分かる。

>tree /f C:\_java\jdk\1.6.0_15_jun_2006\db
C:\_JAVA\JDK\1.6.0_15_JUN_2006\DB
│  3RDPARTY
│  CHANGES
│  COPYRIGHT
│  LICENSE
│  NOTICE
├─demo
│  ├─databases ... snip
│  └─programs ... snip
├─frameworks
│  │  readme.html
│  ├─embedded
│  │  │  readme.html
│  │  └─bin
│  │          dblook.bat
│  │          dblook.ksh
│  │          ij.bat
│  │          ij.ksh
│  │          setEmbeddedCP.bat
│  │          setEmbeddedCP.ksh
│  │          sysinfo.bat
│  │          sysinfo.ksh
│  └─NetworkServer
│      │  readme.html
│      └─bin
│              dblook.bat
│              dblook.ksh
│              ij.bat
│              ij.ksh
│              NetworkServerControl.bat
│              NetworkServerControl.ksh
│              setNetworkClientCP.bat
│              setNetworkClientCP.ksh
│              setNetworkServerCP.bat
│              setNetworkServerCP.ksh
│              startNetworkServer.bat
│              startNetworkServer.ksh
│              stopNetworkServer.bat
│              stopNetworkServer.ksh
│              sysinfo.bat
│              sysinfo.ksh
└─lib
        derby.jar
        derby.war
        derbyclient.jar
        derbyLocale_de_DE.jar
        derbyLocale_es.jar
        derbyLocale_fr.jar
        derbyLocale_it.jar
        derbyLocale_ja_JP.jar
        derbyLocale_ko_KR.jar
        derbyLocale_pt_BR.jar
        derbyLocale_zh_CN.jar
        derbyLocale_zh_TW.jar
        derbynet.jar
        derbyrun.jar
        derbytools.jar

Derby in Mustang を使ってみる

環境設定

Mustang 内の Derby を実行するには、JAVA_HOME、DERBY_HOME という環境変数を指定する必要がある。 これら環境変数を指定した後で、DERBY_HOME の中にある環境設定用バッチファイルを実行する。 今回は Embedded モードを使用した。

> set JAVA_HOME=c:\_java\jdk\1.6.0_15_jun_2006
> set DERBY_HOME=%JAVA_HOME%\db
> set PATH=%JAVA_HOME%\bin;%PATH%
> %DERBY_HOME%\frameworks\embedded\bin\setEmbeddedCp.bat

SET DERBY_HOME=c:\_java\jdk\161730~1.0_1\db

set CLASSPATH=c:\_java\jdk\161730~1.0_1\db\lib
\derby.jar;c:\_java\jdk\161730~1.0_1\db\lib\derbytools.jar;.;C:\Program Files\Ja
va\jre1.5.0_06\lib\ext\QTJava.zip

環境確認

Derby の情報を確認するための sysinfo.bat というバッチファイルが用意されているので実行してみた。

> java -version
java version "1.6.0-rc"
Java(TM) SE Runtime Environment (build 1.6.0-rc-b88)
Java HotSpot(TM) Client VM (build 1.6.0-rc-b88, mixed mode, sharing)

> %DERBY_HOME%\frameworks\embedded\bin\sysinfo.bat
------------------ Java 情報 ------------------
Java バージョン:       1.6.0-rc
Java ベンダー:         Sun Microsystems Inc.
Java ホーム:           c:\_java\jdk\1.6.0_15_jun_2006\jre
Java クラスパス:       c:\_java\jdk\161730~1.0_1\db\lib\derby.jar;c:\_java\jdk\1
61730~1.0_1\db\lib\derbytools.jar;.;C:\Program Files\Java\jre1.5.0_06\lib\ext\QT
Java.zip
OS 名:                 Windows XP
OS アーキテクチャー:   x86
OS バージョン:         5.1
Java ユーザー名:       me
Java ユーザー・ホーム: C:\Documents and Settings\me
Java ユーザー dir:     C:\Hoge
java.specification.name: Java Platform API Specification
java.specification.version: 1.6
--------- Derby 情報 --------
JRE - JDBC: ?-?
[C:\_java\jdk\1.6.0_15_jun_2006\db\lib\derby.jar] 10.2.0.3 alpha - (412448:41244
9)
[C:\_java\jdk\1.6.0_15_jun_2006\db\lib\derbytools.jar] 10.2.0.3 alpha - (412448:
412449)
------------------------------------------------------
----------------- ロケール情報 ----------------
現行ロケール :  [日本語/日本 [ja_JP]]
ロケールのサポートが見つかりました: [de_DE]
         バージョン: 10.2.0.3 alpha - (412448:412449)
ロケールのサポートが見つかりました: [es]
         バージョン: 10.2.0.3 alpha - (412448:412449)
ロケールのサポートが見つかりました: [fr]
         バージョン: 10.2.0.3 alpha - (412448:412449)
ロケールのサポートが見つかりました: [it]
         バージョン: 10.2.0.3 alpha - (412448:412449)
ロケールのサポートが見つかりました: [ja_JP]
         バージョン: 10.2.0.3 alpha - (412448:412449)
ロケールのサポートが見つかりました: [ko_KR]
         バージョン: 10.2.0.3 alpha - (412448:412449)
ロケールのサポートが見つかりました: [pt_BR]
         バージョン: 10.2.0.3 alpha - (412448:412449)
ロケールのサポートが見つかりました: [zh_CN]
         バージョン: 10.2.0.3 alpha - (412448:412449)
ロケールのサポートが見つかりました: [zh_TW]
         バージョン: 10.2.0.3 alpha - (412448:412449)
------------------------------------------------------

サンプルコード実行

以前作成した Embedded モード Derby 用のサンプルコードを実行してみた。

> java jp.in_vitro.codelets.mustang.javadb.Codelet
field01=100, field02=dummy data
field01=888, field02=hogehoge
Derby システムがシャットダウンされました。 : 50000

Posted in Mustang | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Mar 31, 2006

[Mustang] JapaneseImperialCalendar にチャレンジ

Mustang では遂に和暦がサポートされるらしい!!

JavaWorld 2006/05
を貰ったので何となく眺めていたら、とある記事で紹介されていた。 java.util.Calendar の実装クラスがパッケージプライベートなので API Document を眺めていても全く気付いていなかった。 Calendar の和暦サポートは Mustang でも流れたとばかり思っていた。 JavaWorld は久しぶりに開いたけれど、軽くでも毎月目を通すべきかもしれないな。

JavaWorld の記事中でも紹介されていた JapaneseImperialCalendar の紹介ページは↓

Java SE 6 Mustang じゃじゃ馬ならし 官公庁向けでも大丈夫 - 和暦
http://www.javainthebox.net/laboratory/JavaSE6/imperialcalendar/imperialcalendar.html

サンプルコード

package jp.in_vitro.codelets.util;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class Codelet {

    private Date date = new Date(System.currentTimeMillis());

    public Codelet() {
        super();
    }

    public static void main(final String[] args) {
        Codelet me = new Codelet();
        me.execute00();
        me.execute01();
        me.execute02();
        me.execute03();
    }

    protected void execute00() {
        Locale locale = new Locale("ja", "JP");
        Calendar cal = Calendar.getInstance(locale);

        System.out
                .println("0*************************************************************");

        System.out.println("Default Locale : " + Locale.getDefault());
        System.out.println("Calendar#getInstance : " + locale);
        System.out.println();
        System.out.println("" + cal);
        DateFormat format0 = new SimpleDateFormat("GGGGyy年MMMMdd日");
        System.out.println("GGGGyy年MMMMdd日 : " + format0.format(this.date));
        DateFormat format1 = new SimpleDateFormat("GGGyy年MMMMdd日");
        System.out.println("GGGyy年MMMMdd日 : " + format1.format(this.date));
        DateFormat format2 = new SimpleDateFormat("GGGyy/MM/dd");
        System.out.println("GGGGyy/MM/dd : " + format2.format(this.date));
        DateFormat format3 = new SimpleDateFormat("GGGyy/MM/dd");
        System.out.println("GGGyy/MM/dd : " + format3.format(this.date));
        System.out.println();
    }

    protected void execute01() {
        Locale locale = new Locale("ja", "JP", "JP");
        Calendar cal = Calendar.getInstance(locale);

        System.out
                .println("1*************************************************************");

        System.out.println("Default Locale : " + Locale.getDefault());
        System.out.println("Calendar#getInstance : " + locale);
        System.out.println();
        System.out.println("" + cal);
        DateFormat format0 = new SimpleDateFormat("GGGGyy年MMMMdd日");
        System.out.println("GGGGyy年MMMMdd日 : " + format0.format(this.date));
        DateFormat format1 = new SimpleDateFormat("GGGyy年MMMMdd日");
        System.out.println("GGGyy年MMMMdd日 : " + format1.format(this.date));
        DateFormat format2 = new SimpleDateFormat("GGGyy/MM/dd");
        System.out.println("GGGGyy/MM/dd : " + format2.format(this.date));
        DateFormat format3 = new SimpleDateFormat("GGGyy/MM/dd");
        System.out.println("GGGyy/MM/dd : " + format3.format(this.date));
        System.out.println();
    }

    protected void execute02() {
        Locale.setDefault(new Locale("ja", "JP"));
        Calendar cal = Calendar.getInstance();

        System.out
                .println("2*************************************************************");

        System.out.println("Default Locale : " + Locale.getDefault());
        System.out.println("Calendar#getInstance : null");
        System.out.println();
        System.out.println("" + cal);
        DateFormat format0 = new SimpleDateFormat("GGGGyy年MMMMdd日");
        System.out.println("GGGGyy年MMMMdd日 : " + format0.format(this.date));
        DateFormat format1 = new SimpleDateFormat("GGGyy年MMMMdd日");
        System.out.println("GGGyy年MMMMdd日 : " + format1.format(this.date));
        DateFormat format2 = new SimpleDateFormat("GGGyy/MM/dd");
        System.out.println("GGGGyy/MM/dd : " + format2.format(this.date));
        DateFormat format3 = new SimpleDateFormat("GGGyy/MM/dd");
        System.out.println("GGGyy/MM/dd : " + format3.format(this.date));
        System.out.println();
    }

    protected void execute03() {
        Locale.setDefault(new Locale("ja", "JP", "JP"));
        Calendar cal = Calendar.getInstance();

        System.out
                .println("3*************************************************************");

        System.out.println("Default Locale : " + Locale.getDefault());
        System.out.println("Calendar#getInstance : null");
        System.out.println();
        System.out.println("" + cal);
        DateFormat format0 = new SimpleDateFormat("GGGGyy年MMMMdd日");
        System.out.println("GGGGyy年MMMMdd日 : " + format0.format(this.date));
        DateFormat format1 = new SimpleDateFormat("GGGyy年MMMMdd日");
        System.out.println("GGGyy年MMMMdd日 : " + format1.format(this.date));
        DateFormat format2 = new SimpleDateFormat("GGGGyy/MM/dd");
        System.out.println("GGGGyy/MM/dd : " + format2.format(this.date));
        DateFormat format3 = new SimpleDateFormat("GGGyy/MM/dd");
        System.out.println("GGGyy/MM/dd : " + format3.format(this.date));
        System.out.println();
    }
}

実行結果

0, 2, 3 の結果は理解できる。 1 は何故こうなるのだろう?? バグなのか仕様なのか・・・。 Mustang が正式にリリースされたら試してみるか。

0*************************************************************
Default Locale : ja_JP
Calendar#getInstance : ja_JP

java.util.GregorianCalendar[time=1143914626604,areFieldsSet=true,areAllFieldsSet
=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Tokyo",offset=324000
00,dstSavings=0,useDaylight=false,transitions=10,lastRule=null],firstDayOfWeek=1
,minimalDaysInFirstWeek=1,ERA=1,YEAR=2006,MONTH=3,WEEK_OF_YEAR=14,WEEK_OF_MONTH=
2,DAY_OF_MONTH=2,DAY_OF_YEAR=92,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOU
R=3,HOUR_OF_DAY=3,MINUTE=3,SECOND=46,MILLISECOND=604,ZONE_OFFSET=32400000,DST_OF
FSET=0]
GGGGyy年MMMMdd日 : 西暦06年4月02日
GGGyy年MMMMdd日 : 西暦06年4月02日
GGGGyy/MM/dd : 西暦06/04/02
GGGyy/MM/dd : 西暦06/04/02

1*************************************************************
Default Locale : ja_JP
Calendar#getInstance : ja_JP_JP

java.util.JapaneseImperialCalendar[time=1143914626664,areFieldsSet=true,areAllFi
eldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Tokyo",offset
=32400000,dstSavings=0,useDaylight=false,transitions=10,lastRule=null],firstDayO
fWeek=1,minimalDaysInFirstWeek=1,ERA=4,YEAR=18,MONTH=3,WEEK_OF_YEAR=14,WEEK_OF_M
ONTH=2,DAY_OF_MONTH=2,DAY_OF_YEAR=92,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=1,AM_PM=
0,HOUR=3,HOUR_OF_DAY=3,MINUTE=3,SECOND=46,MILLISECOND=664,ZONE_OFFSET=32400000,D
ST_OFFSET=0]
GGGGyy年MMMMdd日 : 西暦06年4月02日
GGGyy年MMMMdd日 : 西暦06年4月02日
GGGGyy/MM/dd : 西暦06/04/02
GGGyy/MM/dd : 西暦06/04/02

2*************************************************************
Default Locale : ja_JP
Calendar#getInstance : null

java.util.GregorianCalendar[time=1143914626664,areFieldsSet=true,areAllFieldsSet
=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Tokyo",offset=324000
00,dstSavings=0,useDaylight=false,transitions=10,lastRule=null],firstDayOfWeek=1
,minimalDaysInFirstWeek=1,ERA=1,YEAR=2006,MONTH=3,WEEK_OF_YEAR=14,WEEK_OF_MONTH=
2,DAY_OF_MONTH=2,DAY_OF_YEAR=92,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOU
R=3,HOUR_OF_DAY=3,MINUTE=3,SECOND=46,MILLISECOND=664,ZONE_OFFSET=32400000,DST_OF
FSET=0]
GGGGyy年MMMMdd日 : 西暦06年4月02日
GGGyy年MMMMdd日 : 西暦06年4月02日
GGGGyy/MM/dd : 西暦06/04/02
GGGyy/MM/dd : 西暦06/04/02

3*************************************************************
Default Locale : ja_JP_JP
Calendar#getInstance : null

java.util.JapaneseImperialCalendar[time=1143914626664,areFieldsSet=true,areAllFi
eldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Tokyo",offset
=32400000,dstSavings=0,useDaylight=false,transitions=10,lastRule=null],firstDayO
fWeek=1,minimalDaysInFirstWeek=1,ERA=4,YEAR=18,MONTH=3,WEEK_OF_YEAR=14,WEEK_OF_M
ONTH=2,DAY_OF_MONTH=2,DAY_OF_YEAR=92,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=1,AM_PM=
0,HOUR=3,HOUR_OF_DAY=3,MINUTE=3,SECOND=46,MILLISECOND=664,ZONE_OFFSET=32400000,D
ST_OFFSET=0]
GGGGyy年MMMMdd日 : 平成18年4月02日
GGGyy年MMMMdd日 : H18年4月02日
GGGGyy/MM/dd : 平成18/04/02
GGGyy/MM/dd : H18/04/02

Posted in Mustang | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Mar 22, 2006

[Mustang] Java 6 Revealed

もう Mustang に関する書籍が出版される。 発売予定日 は 2006/05/29。 このタイミングで出版とは、さすが米国。 日本も負けていられない。 誰か国産 Mustang 本書いてくれないかな。


Java 6 Revealed

Posted in Mustang | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Mar 21, 2006

[Mustang] Console にチャレンジ

Mustang では Console というクラスが新設された。 Console はその名の通りコンソールへのアクセスを提供してくれるクラス。 ちなみに、コンソール用なので Eclipse 上では使えない模様(System.console() が null を返す)。

Class Console
http://download.java.net/jdk6/docs/api/java/io/Console.html

サンプルコード

package jp.in_vitro.codelets.lang;

import java.io.Console;
import java.io.PrintWriter;

public class Codelet {

    public Codelet() {
        super();
    }

    public static void main(String[] args) {
        Codelet me = new Codelet();
        me.execute();
    }

    protected void execute() {
        Console console = System.console();
        PrintWriter writer = console.writer();

        writer.print("name:");
        writer.flush();
        String name = console.readLine();
        writer.println("your name is " + name);
        writer.flush();

        writer.print("password:");
        writer.flush();
        char[] password = console.readPassword();
        writer.println("your password is " + new String(password));
        writer.flush();
    }
}

実行結果

> java -version
java version "1.6.0-beta"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0-beta-b59g)
Java HotSpot(TM) Client VM (build 1.6.0-beta-b59g, mixed mode, sharing)

> java -classpath classes jp.in_vitro.codelets.lang.Codelet
name:in-vitro.jp
your name is in-vitro.jp
password:     ←[ここでパスワードを入力しているがエコーバックされない]
your password is hogehoge

>

Posted in Mustang | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Mar 20, 2006

[Mustang] Mustang における File の 追加機能

Mustang では java.io.File も結構機能追加されていることに気付いた。 ディスクスペースの取得や、パーミッション関連の操作が追加されている。

Class File
http://download.java.net/jdk6/docs/api/java/io/File.html

Mustang で File に追加されたメソッド

public boolean setWritable(boolean writable,boolean ownerOnly)
Sets the owner's or everybody's write permission for this abstract pathname.
public boolean setWritable(boolean writable)
A convenience method to set the owner's write permission for this abstract pathname.
public boolean setReadable(boolean readable,boolean ownerOnly)
Sets the owner's or everybody's read permission for this abstract pathname.
public boolean setReadable(boolean readable)
A convenience method to set the owner's read permission for this abstract pathname.
public boolean setExecutable(boolean executable,boolean ownerOnly)
Sets the owner's or everybody's execute permission for this abstract pathname.
public boolean setExecutable(boolean executable)
A convenience method to set the owner's execute permission for this abstract pathname.
public boolean canExecute()
Tests whether the application can execute the file denoted by this abstract pathname.
public long getTotalSpace()
Returns the size of the partition named by this abstract pathname.
public long getFreeSpace()
Returns the number of unallocated bytes in the partition named by this abstract path name.
public long getUsableSpace()
Returns the number of bytes available to this virtual machine on the partition named by this abstract pathname.

サンプルコード(ディスクスペースの取得)

package jp.in_vitro.codelets.io;

import java.io.File;

public class Codelet {

    public Codelet(){
        super();
    }
    
    public static void main(String[] args) {
        Codelet me = new Codelet();
        me.execute();
    }
    
    protected void execute(){
        File file = new File("c:\\");
        System.out.println("" + file.getAbsolutePath());
        System.out.println("FREE SPACE   : " + file.getFreeSpace());
        System.out.println("TOTAL SPACE  : " + file.getTotalSpace());
        System.out.println("USABLE SPACE : " + file.getUsableSpace());
    }
}

実行結果

c:\
FREE SPACE   : 2151354368
TOTAL SPACE  : 15002906624
USABLE SPACE : 2151354368

Posted in Mustang | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Mar 19, 2006

[Mustang] Normalizer にチャレンジ

Normalizer とは

java.text.Normalize は Mustang から導入された文字列処理用のクラス。 Unicode 文字列の正規化を行ってくれる。 今まで独自のコードでやっていた処理を Normalizer に置き換えられそうなのでチェックしてみた。

Class Normalizer
http://download.java.net/jdk6/doc/api/java/text/Normalizer.html
Enum Normalizer.Form
http://download.java.net/jdk6/doc/api/java/text/Normalizer.Form.html
Normalization Charts
http://www.unicode.org/charts/normalization/

Normalizer では、以下の 4 つの Normalization Form が定義されている。

  • NFC - Canonical decomposition, followed by canonical composition.
  • NFD - Canonical decomposition.
  • NFKC - Compatibility decomposition, followed by canonical composition.
  • NFKD - Compatibility decomposition.
同じ文字でもそれぞれの Form で文字コード上の表現が変化する。

変換結果

日本語を使用するアプリケーションで頻繁に変換処理が行われる文字をチェックしてみた。 NFKC 変換が現在の独自ロジックでの変換の置き換えに使用できそう。 但し、色々試してみたところ多少不足があるので単純な置き換えは無理。

ORIGINAL ->      NFC        NFD          NFKC          NFKD
-------------------------------------------------------------
¢ (00A2) ->   ¢ (00A2)  ¢ (00A2)  ¢ (00A2)  ¢ (00A2)
¢ (FFE0) ->   ¢ (FFE0)  ¢ (FFE0)  ¢ (00A2)  ¢ (00A2)
£ (00A3) ->   £ (00A3)  £ (00A3)  £ (00A3)  £ (00A3)
£ (FFE1) ->   £ (FFE1)  £ (FFE1)  £ (00A3)  £ (00A3)
¬ (00AC) ->   ¬ (00AC)  ¬ (00AC)  ¬ (00AC)  ¬ (00AC)
¬ (FFE2) ->   ¬ (FFE2)  ¬ (FFE2)  ¬ (00AC)  ¬ (00AC)
- (002D) ->   - (002D)  - (002D)  - (002D)  - (002D)
- (FF0D) ->   - (FF0D)  - (FF0D)  - (002D)  - (002D)
| (007C) ->   | (007C)  | (007C)  | (007C)  | (007C)
| (FF5C) ->   | (FF5C)  | (FF5C)  | (007C)  | (007C)
~ (007E) ->   ~ (007E)  ~ (007E)  ~ (007E)  ~ (007E)
~ (FF5E) ->   ~ (FF5E)  ~ (FF5E)  ~ (007E)  ~ (007E)
が (304C) ->   が (304C)  か? (304B3099)  が (304C)  か? (304B3099)
ぎ (304E) ->   ぎ (304E)  き? (304D3099)  ぎ (304E)  き? (304D3099)
ぱ (3071) ->   ぱ (3071)  は? (306F309A)  ぱ (3071)  は? (306F309A)
ぴ (3074) ->   ぴ (3074)  ひ? (3072309A)  ぴ (3074)  ひ? (3072309A)
㍉ (3349) ->   ㍉ (3349)  ㍉ (3349)  ミリ (30DF30EA)  ミリ (30DF30EA)
㌔ (3314) ->   ㌔ (3314)  ㌔ (3314)  キロ (30AD30ED)  キロ (30AD30ED)
㎜ (339C) ->   ㎜ (339C)  ㎜ (339C)  mm (006D006D)  mm (006D006D)
㎡ (33A1) ->   ㎡ (33A1)  ㎡ (33A1)  m2 (006D0032)  m2 (006D0032)
㍻ (337B) ->   ㍻ (337B)  ㍻ (337B)  平成 (5E736210)  平成 (5E736210)
㍼ (337C) ->   ㍼ (337C)  ㍼ (337C)  昭和 (662D548C)  昭和 (662D548C)
№ (2116) ->   № (2116)  № (2116)  No (004E006F)  No (004E006F)
㏍ (33CD) ->   ㏍ (33CD)  ㏍ (33CD)  KK (004B004B)  KK (004B004B)
℡ (2121) ->   ℡ (2121)  ℡ (2121)  TEL (00540045004C)  TEL (00540045004C)
㊤ (32A4) ->   ㊤ (32A4)  ㊤ (32A4)  上 (4E0A)  上 (4E0A)
㊥ (32A5) ->   ㊥ (32A5)  ㊥ (32A5)  中 (4E2D)  中 (4E2D)
㈱ (3231) ->   ㈱ (3231)  ㈱ (3231)  (株) (0028682A0029)  (株) (0028682A0029)
㈲ (3232) ->   ㈲ (3232)  ㈲ (3232)  (有) (002867090029)  (有) (002867090029)

サンプルコード

package jp.in_vitro.codelets.text;

import java.text.Normalizer;

public class Codelet {

    public Codelet() {
        super();
    }

    public static void main(String[] args) {
        Codelet me = new Codelet();
        me.execute();
    }

    protected void execute() {

        String targets = "\u00A2\uFFE0\u00A3\uFFE1\u00AC\uFFE2\u002D\uFF0D\u007C\uFF5C\u007E\uFF5Eがぎぱぴ㍉㌔㎜㎡㍻㍼№㏍℡㊤㊥㈱㈲";
        System.out
                .println("ORIGINAL ->      NFC        NFD          NFKC          NFKD");
        System.out
                .println("-------------------------------------------------------------");
        for (char ch : targets.toCharArray()) {
            this.normalize("" + ch);
        }
    }

    protected void normalize(final String target) {
        String normalized = null;
        String normalizedHex = null;

        System.out.print("" + target + " (" + this.toHex(target) + ") -> ");

        normalized = Normalizer.normalize(target, Normalizer.Form.NFC);
        normalizedHex = this.toHex(normalized);
        System.out.print("  " + normalized + " (" + normalizedHex + ")");

        normalized = Normalizer.normalize(target, Normalizer.Form.NFD);
        normalizedHex = this.toHex(normalized);
        System.out.print("  " + normalized + " (" + normalizedHex + ")");

        normalized = Normalizer.normalize(target, Normalizer.Form.NFKC);
        normalizedHex = this.toHex(normalized);
        System.out.print("  " + normalized + " (" + normalizedHex + ")");

        normalized = Normalizer.normalize(target, Normalizer.Form.NFKD);
        normalizedHex = this.toHex(normalized);
        System.out.print("  " + normalized + " (" + normalizedHex + ")");

        System.out.println();
    }

    protected String toHex(final String str) {

        StringBuffer buf = new StringBuffer();
        for (char ch : str.toCharArray()) {
            buf.append(Integer.toString((int) ((ch >> 12) & 0x0F), 16)
                    .toUpperCase());
            buf.append(Integer.toString((int) ((ch >> 8) & 0x0F), 16)
                    .toUpperCase());
            buf.append(Integer.toString((int) ((ch >> 4) & 0x0F), 16)
                    .toUpperCase());
            buf.append(Integer.toString((int) (ch & 0x0F), 16).toUpperCase());
        }
        return new String(buf);
    }
}

Posted in Mustang | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Mar 18, 2006

[Mustang] Java から Web ブラウザと MUA を起動

Mustang を眺めていたら、何と Web ブラウザと MUA を起動する API を発見!! 早速チャレンジ。
単純に API を呼んでみたところ何の障害もなく Web ブラウザの起動に成功した。
普段使いのメールアドレスが全て Gmail になっているため、MUA は起動確認できず。 そもそも MUA がインストールされていない orz
Mustang では Web ブラウザや MUA 以外にもファイルに関連づけられたアプリケーションの起動ができる。 試しに Explorer とテキストエディタを起動してみたが、どちらもうまくいった。

Class Desktop
http://download.java.net/jdk6/docs/api/java/awt/Desktop.html

サンプルコード

package jp.in_vitro.codelets.awt;

import java.awt.Desktop;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;

public class Codelet2 {

    public Codelet2() {
        super();
    }

    public static void main(String[] args) throws MalformedURLException,
            IOException, URISyntaxException {
        Codelet2 me = new Codelet2();
        me.runWebBrowser();
        me.runMailer();
        me.runExplorer();
        me.runTextEditor();
    }

    protected void runWebBrowser() throws MalformedURLException, IOException,
            URISyntaxException {
        Desktop.getDesktop().browse(
                new URL("http://www.in-vitro.jp/blog").toURI());
    }

    protected void runMailer() throws IOException {
        Desktop.getDesktop().mail();
    }

    protected void runExplorer() throws IOException {
        Desktop.getDesktop().open(new File("c:\\"));
    }

    protected void runTextEditor() throws IOException {
        File dummyTextFile = new File("c:\\hogehoge.txt");
        OutputStream os = null;
        try {
            os = new FileOutputStream(dummyTextFile);
            os.write("this is temporary file.".getBytes());
        } finally {
            if (os != null) {
                os.close();
            }
        }

        Desktop.getDesktop().open(dummyTextFile);
    }
}

Posted in Mustang | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Feb 20, 2006

[Mustang] SystemTray にチャレンジ

SystemTray とは

Mustang では Windows のタスクバーステータスエリアにアイコンを表示する機能が追加されたらしい。 わんこ日記さんの[Java]What's cool in AWT on Java SE 6 (Mustang)で紹介されていた。 これは面白そうなので早速チャレンジ。

API Document - Class SystemTray
http://java.sun.com/javase/6/docs/api/java/awt/SystemTray.html

サンプルコード

JDK 6.0beta で試してみたところ、非常に簡単に実現できた。

package jp.in_vitro.codelets.awt;

import java.awt.AWTException;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.logging.Logger;

import javax.swing.ImageIcon;

public class Codelet {

    public static void main(final String... args) throws AWTException,
            InterruptedException {
        Codelet me = new Codelet();
        me.execute();
    }

    public Codelet() {
        super();
    }

    public void execute() throws AWTException, InterruptedException {
        if (SystemTray.isSupported()) {
            // create PopupMenu
            PopupMenu popupMenu = new PopupMenu();
            MenuItem exitMenuItem = new MenuItem();
            exitMenuItem.setLabel("Exit");
            exitMenuItem.addActionListener(new ExitMenuItemActionListener());
            popupMenu.add(exitMenuItem);

            // create TrayIcon
            ImageIcon image = new ImageIcon(this.getClass().getResource(
                    "/trayicon.jpg"));
            TrayIcon icon = new TrayIcon(image.getImage());
            icon.setPopupMenu(popupMenu);

            // enable TrayIcon
            SystemTray tray = SystemTray.getSystemTray();
            tray.add(icon);
        } else {
            Logger.global.info("SystemTray is not supported.");
        }
    }

    protected static class ExitMenuItemActionListener implements ActionListener {
        public void actionPerformed(final ActionEvent evt) {
            System.exit(0);
        }
    }
}

[表示されたトレイアイコン]
表示されたトレイアイコン

[ポップアップメニュー]
ポップアップメニュー

Posted in Mustang | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Feb 16, 2006

[Mustang] Mustang Beta リリース

Mustang の Beta がついにリリースされた。 Beta リリースに伴い(?) サイトが整備されてきているみたいなので、改めてメモ。

Java Platform, Standard Edition (Java SE) 6 Beta
http://java.sun.com/javase/6/
Download Java Platform, Standard Edition 6 Beta
http://java.sun.com/javase/6/download.jsp
JDK 6 Documentation
http://java.sun.com/javase/6/docs/index.html
Java Platform Standard Edition 6 API Specification
http://java.sun.com/javase/6/docs/api/index.html
Bug Database
http://bugs.sun.com/bugdatabase/index.jsp
Bug Database (Mustang 関連)
http://bugs.sun.com/bugdatabase/search.do?process=1&category=java&bugStatus=open&subcategory=&type=bug&keyword=6.0+or+1.6
change (Contains a list of bug fixes for each build)
https://mustang.dev.java.net/servlets/ProjectDocumentList?folderID=2855

Posted in Mustang | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 17, 2005

[Mustang] Java Compiler API にチャレンジ

Java Compiler API とは

クラスライブラリからソースコードをコンパイルしてバイトコード化できる API。 仕様は JCP で JSR199 として策定中。

本当は Tiger で JDK に導入されるはずだったのだが、いつの間にやら Mustang に延期されていた。 現在の Mustang の snapshot には動作するコードが入っているので、Mustang でのお披露目は大丈夫そう。 Code Generator のランタイム実行、Rule Engine の高速化などなど色々な用途がありそうなので正式リリースが待ち遠しい。

JSR199 Java Compiler API
http://jcp.org/en/jsr/detail?id=199

Java Compiler API の実行環境構築

  1. Mustang をインストールすれば万事 OK

サンプルコード

↓は以下の処理を行うサンプルコード。

  1. ハードコーディングされているソースコードをコンパイル
  2. コンパイルで生成されたバイトコードをオンメモリのまま ClassLoader でローディング
  3. ClassLoader から Class を取得して main メソッドを実行
たったこれだけなのに、結構なコーディングが必要だった。 まだ Mustang が開発中だから仕方がないか。 今後に期待!!

Codelet.java

package jp.in_vitro.codelets.mustang.compilerapi;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.tools.DiagnosticMessage;
import javax.tools.JavaCompilerTool;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
import javax.tools.JavaCompilerTool.CompilationTask;

public class Codelet {
    public Codelet() {
        super();
    }

    public static void main(final String[] args) {
        Codelet me = new Codelet();
        me.execute();
    }

    protected void execute() {
        this.execute01();
        this.execute02();
        this.execute03();
    }

    protected void execute01() {
        // HelloWorld
        JavaCompilerTool compiler = this.prepareJavaCompilerTool();
        JavaFileManagerImpl fileManager = this
                .prepareJavaFileManagerImpl(compiler);

        String sourceCode = "public class HelloWorld {" + 
          "public static void main(String[] args){" + 
          "System.out.println(\"Hello, World!\");}}";
        String className = "HelloWorld";
        JavaSourceFileObject sourceObject = new JavaSourceFileObject(className,
                sourceCode);
        this.compile(compiler, fileManager, sourceObject);
        this.executeMain(fileManager, "HelloWorld", new String[0]);

    }

    protected void execute02() {
        // 複数クラスのコンパイル
        JavaCompilerTool compiler = this.prepareJavaCompilerTool();
        JavaFileManagerImpl fileManager = this
                .prepareJavaFileManagerImpl(compiler);

        // Main
        String mainSourceCode = "public class Main {" + 
          "public static void main(String[] args){" + 
          "Sub sub = new Sub(); sub.execute();}}";
        String mainClassName = "Main";
        JavaSourceFileObject mainSourceObject = new JavaSourceFileObject(
                mainClassName, mainSourceCode);

        // Sub
        String subSourceCode = "public class Sub {" + 
          "public void execute(){" + 
          "System.out.println(\"Sub was executed!!\");}}";
        String subClassName = "Sub";
        JavaSourceFileObject subSourceObject = new JavaSourceFileObject(
                subClassName, subSourceCode);

        this.compile(compiler, fileManager, mainSourceObject, subSourceObject);
        this.executeMain(fileManager, "Main", new String[0]);
    }

    protected void execute03() {
        // コンパイルエラー
        JavaCompilerTool compiler = this.prepareJavaCompilerTool();
        JavaFileManagerImpl fileManager = this
                .prepareJavaFileManagerImpl(compiler);

        String sourceCode = "public class Uncompilable {" + 
          "public static void main(String[] args){" + 
          "executeAbEsseMethod();}}";
        String className = "Uncompilable";
        JavaSourceFileObject sourceObject = new JavaSourceFileObject(className,
                sourceCode);
        this.compile(compiler, fileManager, sourceObject);
        this.executeMain(fileManager, "Uncompilable", new String[0]);
    }

    protected void compile(final JavaCompilerTool compiler,
            final JavaFileManagerImpl fileManager,
            final JavaSourceFileObject... sourceObjects) {

        CompilationTask task = compiler.run(null,
                (JavaFileObject[]) sourceObjects);
        if (task.getResult()) {
            System.out.println();
            System.out
                    .println("************************************************");
            System.out.println("*  Compilation souce(s) completed!!");
            System.out
                    .println("************************************************");
            for (JavaSourceFileObject sourceObject : sourceObjects) {
                System.out.println("" + sourceObject.getName());
            }
        } else {
            System.out.println();
            System.out
                    .println("************************************************");
            System.out.println("*  Compilation souce(s) failed!!");
            System.out
                    .println("************************************************");
            for (DiagnosticMessage message : task.getDiagnostics()) {
                System.out.println("" + message);
            }
            throw new IllegalStateException();
        }
    }

    protected void executeMain(final JavaFileManagerImpl fileManager,
            final String className, final String[] args) {
        System.out.println();
        System.out.println("************************************************");
        System.out.println("*  Execute " + className);
        System.out.println("************************************************");

        ClassLoader loader = this.prepareClassLoader(fileManager);
        try {
            Class testClass = loader.loadClass(className);
            Method mainMethod = testClass.getMethod("main",
                    new Class[] { String[].class });
            mainMethod.invoke(null, new Object[] { args });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    protected JavaCompilerTool prepareJavaCompilerTool() {
        JavaCompilerTool compiler = ToolProvider.defaultJavaCompiler();
        compiler.setExtendedOption("-Xlint:all");
        return compiler;
    }

    protected JavaFileManagerImpl prepareJavaFileManagerImpl(
            final JavaCompilerTool compiler) {
        JavaFileManagerImpl fileManager = new JavaFileManagerImpl(compiler
                .getStandardFileManager());
        compiler.setFileManager(fileManager);
        return fileManager;
    }

    protected ClassLoader prepareClassLoader(
            final JavaFileManagerImpl fileManager) {
        ClassLoaderImpl loader = new ClassLoaderImpl();
        for (String className : fileManager.getClassNames()) {
            loader.addClass(className, fileManager.getClass(className)
                    .getCode());
        }
        return loader;
    }
}

AbstractJavaFileObject.java

package jp.in_vitro.codelets.mustang.compilerapi;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.nio.CharBuffer;

import javax.tools.JavaFileObject;

public abstract class AbstractJavaFileObject implements JavaFileObject {
    private Kind kind;
    private String name;

    public AbstractJavaFileObject(final String name, final Kind kind) {
        super();
        this.name = name;
        this.kind = kind;
    }

    public Kind getKind() {
        return this.kind;
    }

    public boolean delete() {
        return false;
    }

    public String getNameWithoutExtension() {
        return this.name;
    }

    public String getName() {
        return this.name;
    }

    public String getPath() {
        return this.name;
    }

    public long lastModified() {
        return 0L;
    }

    public long lengthInBytes() {
        return -1L;
    }

    public boolean matches(final String simpleName, final Kind kind) {
        return this.kind.equals(kind) && name.equals(simpleName);
    }

    public CharBuffer getCharContent(boolean ignoreEncodingErrors) {
        throw new UnsupportedOperationException();
    }

    public InputStream openInputStream() {
        throw new UnsupportedOperationException();
    }

    public OutputStream openOutputStream() {
        throw new UnsupportedOperationException();
    }

    public Reader openReader() {
        throw new UnsupportedOperationException();
    }

    public Writer openWriter() {
        throw new UnsupportedOperationException();
    }
}

JavaSourceFileObject.java

package jp.in_vitro.codelets.mustang.compilerapi;

import java.io.Reader;
import java.io.StringReader;
import java.nio.CharBuffer;

public class JavaSourceFileObject extends AbstractJavaFileObject {
    private String code;

    public JavaSourceFileObject(final String name, final String code) {
        super(name, Kind.SOURCE);
        this.code = code;
    }

    @Override
    public CharBuffer getCharContent(boolean ignoreEncodingErrors) {
        return CharBuffer.wrap(code);
    }

    @Override
    public Reader openReader() {
        return new StringReader(code);
    }

    @Override
    public String getName() {
        return getNameWithoutExtension() + ".java";
    }
}

JavaClassFileObject.java

package jp.in_vitro.codelets.mustang.compilerapi;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class JavaClassFileObject extends AbstractJavaFileObject {
    private byte[] code;

    public JavaClassFileObject(final String name) {
        super(name, Kind.CLASS);
    }

    @Override
    public OutputStream openOutputStream() {
        return new ClassOutputStream();
    }

    public class ClassOutputStream extends ByteArrayOutputStream {
        public void close() throws IOException {
            super.close();
            JavaClassFileObject.this.code = super.toByteArray();
        }
    }

    public byte[] getCode() {
        return code;
    }
}

JavaFileManagerImpl.java

package jp.in_vitro.codelets.mustang.compilerapi;

import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.JavaFileObject.Kind;

public class JavaFileManagerImpl implements JavaFileManager {
    private Map classes = new HashMap();
    protected final JavaFileManager parentFileManager;

    public JavaFileManagerImpl(final JavaFileManager parentFileManager) {
        super();
        this.parentFileManager = parentFileManager;
    }

    public JavaClassFileObject getClass(final String name) {
        return this.classes.get(name);
    }

    public Set getClassNames() {
        return Collections.unmodifiableSet(this.classes.keySet());
    }

    public JavaFileObject getFileForOutput(final String name, final Kind kind,
            final JavaFileObject originatingSource) {
        if (originatingSource instanceof JavaSourceFileObject) {
            JavaClassFileObject classObject = new JavaClassFileObject(name);
            this.classes.put(name, classObject);
            return classObject;
        } else {
            throw new UnsupportedOperationException();
        }
    }

    public void close() throws IOException {
        this.parentFileManager.close();
    }

    public void flush() throws IOException {
        this.parentFileManager.flush();
    }

    public void setLocation(final String location, final String path) {
        this.parentFileManager.setLocation(location, path);
    }

    public Iterable list(final String packageName,
            final Set kinds) throws IOException {
        return this.parentFileManager.list(packageName, kinds);
    }

    public JavaFileObject getFileForInput(final String name) {
        throw new UnsupportedOperationException();
    }

    public JavaFileObject getFileForOutput(final String filename,
            final String location, final String pkg) throws IOException {
        throw new UnsupportedOperationException();
    }
}

ClassLoaderImpl.java

package jp.in_vitro.codelets.mustang.compilerapi;

import java.util.HashMap;
import java.util.Map;

public class ClassLoaderImpl extends ClassLoader {
    private Map classes = new HashMap();

    public ClassLoaderImpl() {
        super();
    }

    public ClassLoaderImpl(final ClassLoader parent) {
        super(parent);
    }

    public void addClass(final String name, final byte[] bytecode) {
        this.classes.put(name, bytecode);
    }

    public void addClasses(final Map classes) {
        this.classes.putAll(classes);
    }

    @Override
    public Class< ? > loadClass(final String name)
            throws ClassNotFoundException {
        try {
            return super.loadClass(name);
        } catch (ClassNotFoundException e) {
            byte[] classData = classes.get(name);
            return defineClass(name, classData, 0, classData.length);
        }
    }
}

サンプルの実行結果

↑の Codelet#main を実行した結果は↓

************************************************
*  Compilation souce(s) completed!!
************************************************
HelloWorld.java

************************************************
*  Execute HelloWorld
************************************************
Hello, World!

************************************************
*  Compilation souce(s) completed!!
************************************************
Main.java
Sub.java

************************************************
*  Execute Main
************************************************
Sub was executed!!

************************************************
*  Compilation souce(s) failed!!
************************************************
Uncompilable:1: シンボルを見つけられません。
シンボル: メソッド executeAbEsseMethod()
場所    : Uncompilable の クラス
Exception in thread "main" java.lang.IllegalStateException
	at jp.in_vitro.codelets.mustang.compilerapi.Codelet.compile(Codelet.java:113)
	at jp.in_vitro.codelets.mustang.compilerapi.Codelet.execute03(Codelet.java:81)
	at jp.in_vitro.codelets.mustang.compilerapi.Codelet.execute(Codelet.java:27)
	at jp.in_vitro.codelets.mustang.compilerapi.Codelet.main(Codelet.java:20)

Posted in Mustang | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Oct 16, 2005

[Mustang] Mustang メモ

そろそろ Mustang も視野にいれておかないと、ということで一通りメモ。

Mustang
http://mustang.dev.java.net/
JDK 6 Documentation
http://download.java.net/jdk6/docs/
Java SE 6, Platform Name and Version Numbers
http://download.java.net/jdk6/docs/relnotes/version-6.html
JSR270 JavaTM SE 6 ("Mustang")
http://www.jcp.org/en/jsr/detail?id=270
Mustang が関連する JSR はこちら↓。
JSR105 XML Digital Signature
http://jcp.org/en/jsr/detail?id=105
JSR199 Java Compiler API
http://jcp.org/en/jsr/detail?id=199
JSR202 JavaTM Class File Specification Update
http://jcp.org/en/jsr/detail?id=202
JSR221 JDBC 4.0
http://jcp.org/en/jsr/detail?id=221
JSR222 JAXB 2.0
http://jcp.org/en/jsr/detail?id=222
JSR223 Scripting for the JavaTM Platform
http://jcp.org/en/jsr/detail?id=223
JSR224 JAX-RPC 2.0
http://jcp.org/en/jsr/detail?id=224
JSR260 Javadoc Tag Update
http://jcp.org/en/jsr/detail?id=260
JSR268 Java Smart Card I/O API
http://jcp.org/en/jsr/detail?id=268
JSR269 Pluggable Annotation Processing API
http://jcp.org/en/jsr/detail?id=269

Posted in Mustang | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |