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
Jun 20, 2006
[Mustang] Derby in Mustang にチャレンジ
色々なところで話題になっているようだが、Derby が Mustang に同梱されるらしい。 公式には Java DB という DBMS が搭載されるということだが、Java DB のサイトには
What's Java DB?と記述されているので、Java DB == Derby ということだろう。
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.
ユニットテストやプロトタイプ開発時など「とりあえず何でもいいから 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
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
Mar 22, 2006
[Mustang] Java 6 Revealed
もう Mustang に関する書籍が出版される。
発売予定日 は 2006/05/29。
このタイミングで出版とは、さすが米国。
日本も負けていられない。
誰か国産 Mustang 本書いてくれないかな。
![]()
Java 6 Revealed
Mar 21, 2006
[Mustang] Console にチャレンジ
Mustang では Console というクラスが新設された。 Console はその名の通りコンソールへのアクセスを提供してくれるクラス。 ちなみに、コンソール用なので Eclipse 上では使えない模様(System.console() が null を返す)。
サンプルコード
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 >
Mar 20, 2006
[Mustang] Mustang における File の 追加機能
Mustang では java.io.File も結構機能追加されていることに気付いた。 ディスクスペースの取得や、パーミッション関連の操作が追加されている。
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
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.
変換結果
日本語を使用するアプリケーションで頻繁に変換処理が行われる文字をチェックしてみた。 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);
}
}
Mar 18, 2006
[Mustang] Java から Web ブラウザと MUA を起動
Mustang を眺めていたら、何と Web ブラウザと MUA を起動する API を発見!!
早速チャレンジ。
単純に API を呼んでみたところ何の障害もなく Web ブラウザの起動に成功した。
普段使いのメールアドレスが全て Gmail になっているため、MUA は起動確認できず。
そもそも MUA がインストールされていない orz
Mustang では Web ブラウザや MUA 以外にもファイルに関連づけられたアプリケーションの起動ができる。
試しに Explorer とテキストエディタを起動してみたが、どちらもうまくいった。
サンプルコード
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);
}
}
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);
}
}
}
![[表示されたトレイアイコン]](/blog/entries/Mustang/20060220_01/systemtray_01.jpg)
表示されたトレイアイコン
![[ポップアップメニュー]](/blog/entries/Mustang/20060220_01/systemtray_02.jpg)
ポップアップメニュー
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
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 の実行環境構築
- Mustang をインストールすれば万事 OK
サンプルコード
↓は以下の処理を行うサンプルコード。
- ハードコーディングされているソースコードをコンパイル
- コンパイルで生成されたバイトコードをオンメモリのまま ClassLoader でローディング
- ClassLoader から Class を取得して main メソッドを実行
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)
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
- 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



