カテゴリーアーカイブ: 日記

Mar 27 2010

Jasper Reports で PDF ファイル出力

ちょっと必要がありまして、Jasper Reports というオープンソースの帳票出力ライブラリで PDF の出力を行いました。 使い方を忘れてしまいそうなのでメモがてら。 初めて使うライブラリは勝手が分からずなかなか大変です。 :)

Jasper Reports とその帳票設計を行う iReport というアプリです。

jasperforge JasperReports Project Home

JasperReports is the world’s most popular open source reporting engine. It is entierly written in Java and it is able to use data coming from any kind of data source and produce pixel-perfect documents that can be viewed, printed or exported in a variety of document formats including HTML, PDF, Excel, OpenOffice and Word.

jasperforge iReport Project Home

iReport is the free, open source report designer for JasperReports. Create very sophisticated layouts containing charts, images, subreports, crosstabs and much more. Access your data through JDBC, TableModels, JavaBeans, XML, Hibernate, CSV, and custom sources. Then publish your reports as PDF, RTF, XML, XLS, CSV, HTML, XHTML, text, DOCX, or OpenOffice.

Jasper Report は LGPL、iReport は AGPL です。 iReport のほうは NetBeans ベースでつくられているよう。 前者がライブラリで、後者がそのライブラリで読み込む GUI 帳票設計アプリケーションとなります。

とりあえず、ファイルをダウンロード。 以下二つを利用しました。 iReport のほうは、Linux、Mac OS X 版もあります。 Jasper Reports は pure java です。

jasperreports-3.7.1-project.tar.gz

iReport-3.7.1-windows-installer.exe

また、Jasper Reports の PDF 出力は iText PDF ライブラリに依存しています。 iText 自体は上記 project.tar.gz (のlib)に同梱されいますが、日本語の出力の際に必要な iTextAsian.jar が含まれていませんので以下からダウンロードします。(下の方です)

Browse iText, a JAVA-PDF library Files on SourceForge.net

extrajars  – ExtraJars1.0  – iTextAsian.jar

これでファイルの準備は完了。 iReport のほうは適当にセットアップしておきます。

Jasper Reports はいろいろなデータソースから帳票を出力できますが、今回は Java の Bean 経由で出力してみます。 DB に直つなぎとかもできるみたいですね。

最終的に Java からだすので、先にプログラムソースの準備を。

以下のようなモジュール構成にしておきます。 Jasper Reports の依存ライブラリがよく分かりませんでしたが、今回のプログラムで class not found がでなくなった最小構成としています。 また、先の iTextAsian.jar もいっしょに入れておきます。

Jasper01

templates フォルダには Jasper Repost の定義体を入れることにしましょう。

SampleReportBean.java が帳票に出力したいレコードを表現した Bean です。 Bean の内容は以下の通り。 getter、setter は省略。

   1: package net.maple4ever.jasper;
   2:  
   3: public class SampleReportBean {
   4:  
   5:     // メーカ
   6:     private String maker;
   7:     // 機種名
   8:     private String name;
   9:     // OS
  10:     private String os;
  11:     // CPU
  12:     private String cpu;
  13:     // メモリ容量
  14:     private String memory;
  15:     // ハードディスク容量
  16:     private String hdd;
  17:  
  18:     // 以下 getter/setter (省略)
  19: }

さてさて、ここから iReport の世界に入っていきます。 iReport 起動。

とりあえずオプション設定。 iTextAsian.jar と今ほどつくった Java プロジェクトに class path を通します。

 Jasper02

Eclipse で Java プロジェクトつくった場合は、プロジェクトロケーション/bin にします。(class ファイルできるところね) で、上のスクリーンショットでは忘れてしまっていますが、Relodable にチェックを入れます。 iTextAsian.jar にはチェックいらないでしょう。(Java プログラムを修正すると読み直してくれます)

了解おして、ここで iReport を一回再起動。(しないと iTextAsian が反映されませんでした)

でもってファイル –> NEW あたりから帳票新規作成。 ファイルの置き場所を先ほどの templates フォルダにします。 種類、ここでは A4 のブランクにしました。

Jasper03

Open this Template おして、

Jasper04 

みたいな感じです。

できたら、まずは帳票プロパティの Language を Java に変更します。 Groovy が標準のようですね。 これやらないと、後で Java から呼ぶときに groovy の class ないぞってエラーになります。

Jasper04-02

帳票設計画面はこんな感じです。

Jasper05

上から Title、Page Header、Column Header、Detail 1、Column Footer、Page Footer、Summary となっています。 この中で Detail の部分が繰り返しのデータをおくところになります。 ここが重要。

でもって、Title、Summary 部分が1ページと最終ページ。 Page/Column  Header、Footer が表ごとページごととなるようです。

ふまえて、レコードとなるさきほどの Bean を Detail 1 に配置していきます。 まずはデザイナ上部、Preview の横のデータベース矢印みたいなアイコンをクリックします。

Jasper05-02

さきほどつくった Bean のパッケージを入力して Read attributes を押下します。 さすると、Bean のプロパティがでてきます。 うまく読めないときは class path の設定を確認。

Jasper06

選択して Add Selected field(s) ボタンを押下します。 するとこのフィールドがデザイナ上で配置できるようになります。

画面左ツリーの Fields 木にいま追加したフィールド出現するので、ドラッグアンドドロップで Detail 1 に置いていきます。 罫線とか必要ならパレット開いて描画していきます。 static text とかでテーブルヘッダとかタイトルとかもつける。

日本語フォントは PDF Font name を「HeiseiKakuGo-W5」に、PDF Encording を「UniJIS-UCS2-H (Japanese)」にします。 こうしないと PDF になったときに日本語が出力されません。(Adobe Reader のフォント。ちょっと詳しくないですが、iTextAsian.jar の設定値なのかもしれません。 MSP ゴシックとかは設定できない模様)

まぁまぁこんな感じです。

 Jasper09

また繰り返しリストではなく、帳票全体でひとつの埋め込み項目は「パラメータ」として配置することができます。 左ツリーのparameter で追加して名前をつけて置いていきます。

Jasper08

でもって、なんとなくできたらデータを埋め込んでみます。 iReport には任意の Java を呼び出してその帰り値の Collection を埋め込んでくれる便利な機能がありました。(Biz Stream はこれできないよね?)

とりあえずさきほどの Java のプロジェクトに SampleReportFactory.java というソースを追加しました。 createBeanCollection という static なメソッドが標準で使われるようなのでこれも用意しておきます。 こんな感じです。

   1: public class SampleReportFactory {
   2:     
   3:     public static List<SampleReportBean> createBeanCollection() {
   4:         
   5:         List<SampleReportBean> lines =
   6:             new ArrayList<SampleReportBean>();
   7:         
   8:         for(int i=1; i<100;i++) {
   9:             SampleReportBean line = new SampleReportBean();
  10:             line.setName("自作機2号");
  11:             line.setMaker("ひろまさ");
  12:             line.setOs("Ubuntu 9.10");
  13:             line.setCpu("PhenomII X4");
  14:             line.setHdd("320GByte");
  15:             line.setMemory("4GByte");
  16:             line.setColor(String.valueOf(i % 2));
  17:             lines.add(line);
  18:         }
  19:         return lines;
  20:     }
  21: }

iReport に戻って画面上部のデータソースのアイコンを押下します。

Jasper05-01

JavaBeans set datasource を選択。

 Jasper10

でもっていまつくった SampleReportFactory を指定します。

Jasper11

Test おして OK もらったら Save します。

で、デザイナの Preview を押してみると帳票につくったデータソースがバインドされた結果が表示されます。 :)

Jasper13

ソースコードから入力をつくれるので桁数試験とか結構便利です。

さてさて、ちゃんとした帳票だと罫線の制御とかしたくなることがあります。

ちょっとマニュアル調べて簡単そうだったのが各描画オブジェクトがもつ、Print When Express というプロパティ。 フィールドとかの値を判定して表示の可否をきめることができます。

たとえば、行をしましまにしたかったら Bean にそれっぽいフラグ項目をつくって、

Jasper14

こんな感じで Print When Expression を設定してあげると true のときだけ表示になります。(Jasper への戻値は、boolean じゃなくて Boolean のようなので注意してください)

というわけで灰色ざぶとんを行の下に敷いて、しましま。 とか。

Jasper15

他にも良い方法があるとは思うですが、これさえあればあとは組み合わせ、、知恵と勇気でなんでもいけるかと。。(笑)

では最後に Java から作った帳票をだしてみます。 iReport 終了。 iReport で保存・コンパイルされたものが templates フォルダに入っているはずです。

Jasper16 

.jasper がコンパイルされた結果です。 プログラムからはこちらを使います。(動的コンパイルもできるみたいですがここでは割愛)

面倒なので先ほどの SampleReportFactory クラスに main を追加する感じで。 List はさきほどつくったもの。 また、HashMap にパラメータを設定して Jasper に渡すと PDF ができる感じです。

   1: public class SampleReportFactory {
   2:  
   3:     // さきほどの createBeanCollection メソッド省略
   4:  
   5:     public static void main(String args[]) throws JRException {
   6:         
   7:         // 出力するBean のつまった List を DataSource に設定
   8:         JRBeanCollectionDataSource ds =
   9:             new JRBeanCollectionDataSource(
  10:                 SampleReportFactory.createBeanCollection());
  11:         // パラメータの Map 作成
  12:         Map<String,String> param = new HashMap<String,String>();
  13:         param.put("now", "2010/03/11");
  14:         // これらのデータを元に PDF 作成
  15:         JasperPrint pdf = JasperFillManager.fillReport(
  16:                 "./templates/sample-report.jasper", param, ds);
  17:         // PDF をファイルとして出力
  18:         JasperExportManager.exportReportToPdfFile(pdf,
  19:                 "./templates/sample-report.pdf");
  20:         
  21:         // pdf.addPage((JRPrintPage)pdf.getPages().get(0));
  22:         
  23:     }
  24:  
  25: }

実行~。

Jasper17

おめでとうございます(笑)

最後のサンプルソースの一番下にコメントでかいてありますが、複数のテンプレートをつなげて一つの PDF にすることもできそうです。

   1: // pdf.addPage((JRPrintPage)pdf.getPages().get(0));

addPage の引数に index ありもあったので、交互差し込みとかもできるかもですね。

ここまできたら、本家のマニュアルの xml タグを調べていけばあとはなんとか。。(笑)

JasperReports 3.7.1 – Schema Reference

This document describes the structure of the JRXML report template files for the JasperReports library.

Expression 系でいろいろできそうです。

以上、参考になりましたら。

Mar 23 2010

Microsoft Arc Mouse に変更です

使っていた Microsoft のでっかいマウスのラバー部分がでろでろになってきましたので、マウスを変更しました。

手が大きいのもあって、大きい重いマウスが好みだったりするのですが Microsoft Arc Mouse がなんだかかわいかったので、そちらにしてみました。 真っ向から傾向が違いますが、たまには。 :)

Microsoft Arc Mouse ブラック ZJA-00017

全く新しい洗練された外観に、優れた携帯性と快適な操作性をあわせ持った、スタイリッシュなレーザー方式マウス

こんなのです。 Ubuntu 9.10 で動作させていますが、特に問題はなさそう。 電池は単四2本で軽い軽い。

IMG_0078

持ち運び用に折りたためます。

IMG_0080

持ち運びポシェットがついててよいですなぁ。 折りたたむと電源が切れるので、PC 起動中もお掃除もできるという特典がもれなくついてまいります(笑)

使い勝手は、最初指の置き場所に困りましたがちょっとしたら慣れました。 ホイールがちょっとかちゃかちゃうるさいかな。 引っかかりがあるホイールなので中ボタンは押しやすいです。  :)

なお、サイドボタン(戻る)はぼくの手はうまく押せません。 ブラウザアドインとか Opera とかの右左押しで運用対処を(笑)

カラーバリエーションあり。 普通使いも携帯もできるマウスを探している方は要チェックや!

Mar 20 2010

Excel ファイルの操作を Groovy から行う

あちこちの現場で、エクセルファイルから create table をつくったり Bean をつくったりするマクロをみかけます。 ぼくもつくったことありますが、こういうのってワンショットで一回つくったら大抵もう使わないプログラム。

エクセル VBA でつくりますが、ぼくら VBA ってあんまり使わないのですぐ忘れてしまい、あれ文字列の連結 & だっけ?とか、 ; つけてすまったー! とか、たくさんのファイルを処理するとぱかぱかエクセルあがったりしてうーん、とかいろいろ、、、というわけで Java からエクセルを読み込む XLSBeans を試してみました。

実は VBA も RANGE オブジェクトつくって Iterator っぽくまわせたり結構やるなって思う部分もあるのですが、やっぱり書き方的に慣れてない部分も多々あります。 で、Java って思うのですが、ワンショットにしては適当にかけない部分もあり、、ってことで今回は Groovy から XLSBeans を呼び出してみました。 :)

XLSBeans – Project Amateras

ExcelとJavaBeansをJava 5のアノテーションでマッピングするためのライブラリです。

MYCOMジャーナルに簡単な紹介記事が掲載されています。まずはこちらをご覧いただくとXLSBeansがどのようなものかをご理解いただけるのではないかと思います。

XLSBeans – ExcelをJavaBeanに自動マッピング!

とりあえず、XLSBeans と Groovy を使えるようにしてこんな感じに・・・。

xlsbeans01

Excel をつくります。 OOo で xls 形式にしましたが問題ありませんでした。

たとえば、画面定義。 本物は 100 とか 200行オーダで、もっといろいろ書いているもんですが、とりあえず。 これの struts FormBean をつくるようなイメージで。(あくまでイメージね)

xlsbeans02

で、ソースをかきます。 Groovy なので単一モジュールで、main もなく、がりがりいけます。 試験的に漢字変数とかも使ってみました。 なんかこわい(笑)

import net.java.amateras.xlsbeans.*;
import net.java.amateras.xlsbeans.annotation.*;
 
// エクセルファイルを定義に従って読み込む
sheet = (new XLSBeans()).load(
    new FileInputStream("xls/項目定義.xls")
    , ExcelSheet.class);
 
// 定義からデータ呼んでファイル出力
new File("xls/test.txt").withPrintWriter { w ->
    for(画面項目 in sheet.画面項目行) {
        upper = 画面項目.物理名[0].toUpperCase();
        upper +=
            画面項目.物理名[1..画面項目.物理名.length() - 1]; 
        str = """
            // ${画面項目.論理名}
            private String ${画面項目.物理名};
            
            private String get${upper}() {
                return ${画面項目.物理名};
            }
            private void set${upper}(String str) {
                ${画面項目.物理名} = str;
            }""";
        w.println(str);
    }
}
 
// 以下エクセルの定義
 
@Sheet(name="Sheet1")
class ExcelSheet {
    @HorizontalRecords(tableLabel="画面項目定義"
        , recordClass=画面項目.class)
    public List<画面項目> 画面項目行;
}
 
class 画面項目 {
    @Column(columnName="論理名")
    public String 論理名;
    @Column(columnName="物理名")
    public String 物理名;
    @Column(columnName="タイプ")
    public String タイプ;
    @Column(columnName="長さ")
    public String  長さ;
    @Column(columnName="出力編集")
    public String 出力編集;
}

これを実行するとエクセルを処理して内容を吸い出して整形したテキストファイルができあがります。 サンプルでも JavaDoc くらいつけろですか。 :D

// タイトル
private String title;
 
private String getTitle() {
    return title;
}
private void setTitle(String str) {
    title = str;
}

・・・。 ・・・。 まちがって getter / setter を private にしてしまいました。 まぁサンプルということでご愛敬。。(笑)

さて、最初エクセルを取得する Bean を Groovy のプロパティをつかって public をつけずに定義していたら、うまく値が入りませんでした。 Groovy でも public String hoge; とかするのが正解のようです。

VBA で処理すると座標系でやってしまいがちで、これが結構数えたり面倒だったりするもんですが、XLSBeans を使うとオートで Bean にマッピングしてくれるので大変便利です。 エクセルのあちこちの位置に置いてみたりしてみましたが、うまく検索して場所を探してくれるようです。

Groovy から呼ぶと、public static void main() いらなかったり、ヒアドキュメント + GString のうめこみ変数とか、ファイルのオープンクローズとか不要とか、文字列操作とかいろいろ楽かもですね。 ぼくは慣れてないので、まだまだ簡単にかく方法あると思います。

てなわけで、Eclipse にプロジェクトひとつ準備しておくと何かのおりに使えるかもしれません。 :)

Feb 13 2010

サーバサイド Groovy と Groovlets

ちょっと前ですが、スクリプト言語 Groovy の新しいバージョンにあわせて eclipse-groovy プラグインのバージョンがあがったということで、ちょっと触ってみました。 Groovy 自体、ワンショットスクリプトを数回かいただけでほどんどさわったことがないのですが、まぁお遊びということで。

このスクリプト言語、いざとなったら普通の Java の書き方できるので手が止まらなくて便利なのです。 クラスライブラリもいつもの使えますし(笑)

【コラム】イマドキのIDE事情 (74) 高機能なGroovy開発環境「Groovy-Eclipse 2.0」リリース! | エンタープライズ | マイコミジャーナル

1月15日、Groovy開発用のEclipseプラグイン「Groovy-Eclipse 2.0」がリリースされた。GroovyはJava VM上で動作するスクリプト言語でJavaに似た構文を持つためJavaプログラマにとって扱いやすいという特徴がある。Groovy-EclipseはこのGroovyでの開発を強力に支援してくれるEclipseプラグインだ。バージョン1.0から大幅に機能が強化されており、Eclipse標準の Java開発環境であるJDTと比較しても遜色ない開発支援機能を備えている。

ぱらぱらみていると、Groovy をサーバサイドでつかう Groovlets という仕組みがあるようだったので、こちらとあわせてサーブレット環境で使ってみることに。

以下、せっかくやったのでメモです。

とりあえず、Eclipse WTP で新規「動的 Web プロジェクト」をつくります。

groovlets02

普通ですね。 :)

で、このままだと Groovy-Eclipse が構成されていないので(.groovy がコンパイルされない)、つくったプロジェクトを右クリックして Groovy を構成します。

groovlets01

Convert to Groovy Project。 これで nature に groovy が入ります。 でもって、これやると groovy の jar も追加してくれるのですが、JavaEE の場所 (WEB-INF/lib)に入らないので消して、手動で lib の下にいれてあげます。

Groovlets を使うには –all を使うといいようです。 配布元にある groovy-binary-1.7.0.zip の embeddable フォルダに入っています。

あとは、 src の下で .groovy ファイルを作成すればコンパイル・再デプロイを groovy-eclipse と WTP がやってくれます。 ここまでで、 .groovy のグルーヴィな記述でサーバサイドプログラムを行うことができます。

さて、こっからが Groovlets。

サーバに「ファイルとして配置された」 .groovy をそのまま動かすのが Groovlets です。 ランタイムで勝手にコンパイルしてくれます。 あと、GSP という JSP みたいなテンプレートライブラリがあります。

要はサーバに配置された .groovy ファイルを書き換えると Groovlets がホットデプロイ(とはいわないか。JIT?) してくれる仕組み。 ぼくはまた、このホットデプロイを利用しながら、Groovy のシンタックスシュガーを使いまくって小規模な Web アプリを高速にかくものと想像していたのですが、どうもそうとは違う模様。

間違っていたらご指摘いただきたいのですが、 Groovy でモジュールを分割する仕組みは import のみ。 でもって、Groovlets は import 先のモジュールはダイナミックにコンパイルしてくれないのです。 なので、プログラムは url-pattern にあたったひとつの .groovy ファイルだけで構成する必要があります。

もちろん、デプロイ時に .class になっているものは import 可能なので Eclipse で .groovy かいてコンパイルしてデプロイすりゃいいんですが、そしたら Groovlets 使わなくてもいいような(笑)

結論的には、GSP とか JSP とかと同じように html テンプレートで使うのかな~。 もしくは上にフレームワークをかくための土台、、あとモジュール1本で済むような、「なんとか度」判定みたいなアプリとか。 :D

groovy のオリジナルソースを読んだところ、ダイナミックコンパイルは直アクセスだけでなく RequestDispatcher の指定も対応しているようだったので、きっとそういうことなのでしょう。

てなわけで、試しに以下のように構成してみました。

groovlets03

web.xml (抜粋)

<display-name>Groovlets</display-name>
<!-- Groovlets -->
<servlet>
    <servlet-name>Groovy</servlet-name>
    <servlet-class>groovy.servlet.GroovyServlet
    </servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Groovy</servlet-name>
    <url-pattern>*.groovy</url-pattern>
</servlet-mapping>
<!--  GSimpleServlet -->
<servlet>
    <servlet-name>GSimpleServlet</servlet-name>
    <servlet-class>net.maple4ever.groovlets.GSimpleServlet
    </servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>GSimpleServlet</servlet-name>
    <url-pattern>/index.do</url-pattern>
</servlet-mapping>

Groovlets と自前のサーブレットを2つ登録します。

テンプレート(ダイナミックコンパイル側)の .groovy ファイルは WEB-INF/groovy もしくは WEB-INF/ に配置します。(/ 優先で、そこになければ groovy/ を見に行くようになっていました) ここではわかりやすいように WEB-INF/groovy/index.groovy を配置。

index.groovy

html.html {
    head {
        title 'index.groovy'
    }
    body {
        h1 'Hello, Groovy World.'
    }
}

このへんが groovy の面白いところで、クロージャをつかった html の builder とかがあります。 これを使っておけば変な HTML ができることはないでしょう。(たぶん)

で、サーブレット側。 一応こちらも groovy っぽく書いてみる。。

GSimpleServlet.groovy

package net.maple4ever.groovlets;
 
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
class GSimpleServlet extends HttpServlet {
    
    void doGet(
        HttpServletRequest request
        , HttpServletResponse response) throws IOException {
        def rd = request.getRequestDispatcher("index.groovy")
        rd.include(request,response);
    }
    
}

最初、 void doGet(reauest, response) とかかいてみて、動かなくてはたと2分。 型を指定してなかったので、 HttpServlet の doGet をオーバーライドできなかったというオチでした。 オーバーロードになっちゃったのね。 てっか、そこ省略は怖いか。 :)

で、この中で index.groovy をこんな感じで include してあげると、読まれた時点で index.groovy が動的コンパイルされます。

ということで、、、う~ん view に groovy 使えるよ、という理解でいいのだろうか。いまいっぽ腹に落ちないひろまさくんでした。

Jan 26 2010

携帯電話 Bluetooth + DUN でモバイルインターネットを試す

10年前くらいは携帯電話/PHP の回線契約数を 5 回線くらい持っていたりして、モバイル系大好きだったのですが、いつのころからかご無沙汰気味。

昔はこの手のがずいぶんお値段高くて維持費的なものからやめてしまったと思いましたが、最近 ドコモの 128K パケホーダイとかでてきて、お小遣いくらいでまた遊べるようになったので、ちょっと復活して試しに Bluetooth + DUN を使ってノートPC をインターネットにつなぐ準備をしてみました。

こういうの、なにかちょっとした出張とかあったときのためとか、緊急時のインターネット回線用にとかでも用意しておくと便利かもしれません。 :)

bluetooth01

用意したのはノートPC ThinkPad くんと、ドコモの FOMA 携帯電話 SH906i さん。

また、ドコモの FOMA を契約していると、mopera U というドコモがやっている携帯電話接続可能なインターネットプロバイダを使うことができます。 これが現在キャンペーン中で、4末までですが 0円、もしくは 262.5円/月で接続することができます。

キャンペーン|サービス一覧|ドコモの定額データプラン対応のインターネット接続プロバイダ「mopera U (モペラユー)」

2009年12月1日(火)~2010年4月30日(金)

てなわけで、こちらの U スタンダードプランを使ってみることに。 ライトでもいいのでうすが、ドコモの公衆無線LAN Mzone も 0円キャンペーン中なので、こちらも試してみたくてスタンダードにしています。(ライトだとつけられない)

ちなみに mopera U の契約は、携帯電話を使って iMode のお客様メニューからやるのが一番簡単そうでした。 ただ申し込みサイトの説明がちょっと違っていて、

お申込み・契約変更|ドコモの定額データプラン対応のインターネット接続プロバイダ「mopera U (モペラユー)」

「iMenu」⇒「お客様サポート」⇒「お申込・お手続き」⇒「各種お申込・お手続き」⇒「便利なサービスの申込」

とありましたが、なくって、、「便利なサービス」じゃなくて、「MM サービス」というメニューの中にありました。 探したわ。 っていうか MM って久しぶりに聞いた(笑) ここでスタンダード + 公衆無線LAN を申し込みました。

ではでは、まず ThinkPad + SH906i の Bluetooth で Windows から DUN してみます。

どんな PC でも同じですが、先ずは PC 側の Bluetooth を有効に。。 …する方法を忘れて10分を消費しました。。 デバイスマネージャから見えなかったので一瞬、ぼくの ThinkPad に Bluetooth がついていたのが夢だったかと。。(笑)

ThinkPad の場合は Fn + F5 でオンにできます。 :)

bluetooth02

で、デバイスマネージャを確認。 でてきます。

bluetooth04

あとは、携帯電話の Bluetooth メニューから機器検索とかして、PC とペアリングします。 そうすると、PC 側にデバイスが現れます。

bluetooth05

この PC の場合は、携帯電話が COM4 に割り当てられました。 この状態で COM4 にアクセスがあると Bluetooth の無線を経由して接続されます。

で、ここからが mopera U に接続する設定です。 実はドコモからコネクションマネージャというのアプリがでていてオート設定できるのですが、ここは黙って手動設定。(笑)

まず、携帯電話に mopera U の APN を登録します。 ここでは実験なので、インターネットには接続できない、(現在)パケット無料の管理画面表示用のアクセスポイントを追加。

Poderosa でも teraterm でも使って、携帯電話のつながっている COM4 にアクセスします。 Bluetooth 経由で携帯電話のモデムにつながるハズです。 昔みたく PC と携帯をケーブルつながなくていいので便利ですね。 携帯電話はポッケにいれたままでOKです。 :D

でもって、携帯電話モデムの AT コマンド(説明書にでています)を使って、0120.mopera.net という APN を追加します。 番号は 10 にしてみました。

bluetooth03

シリアルなのでコマンドはゆっくり入力しましょう。 文字が遅れてくるよ。

AT+CGDCONT?
+CGDCONT:1,"PPP","mopera.ne.jp",,0,0
+CGDCONT:3,"IP","mopera.net",,0,0
OK
AT+CGDCONT=10,"IP","0120.mopera.net"
OK
AT+CGDCONT?
+CGDCONT:1,"PPP","mopera.ne.jp",,0,0
+CGDCONT:3,"IP","mopera.net",,0,0
+CGDCONT:10,"IP","0120.mopera.net",,0,0
OK

SH906i では APN 追加は、AT+CGDCONT= コマンドです。(真ん中コマンド) 他の携帯電話の方はマニュアルを確認のこと。(たぶんいっしょですが)

できたら、PC からここで登録した APN にダイアルアップします。 番号識別は電話番号の欄で行います。 携帯電話デバイスから右クリックして、ダイアルアップネットーワークの追加。

bluetooth06

電話番号に *99***[APN番号]# を設定します。 ここでは先に設定した 10 を。

で、ダイアル。 :)

bluetooth07

ユーザ名とパスワードは、mopera U に加入したときのウエルカムメッセージの URL からネットワーク暗証番号をいれた後の画面で確認できます。(若干わかりにくい)

接続できたら、 http://start.mopera.net/ にアクセスしてみましょう。 つながっているはずです。 この APN ではここのサイト以外はつながりません。(設定確認などをするところです)

ちゃんとインターネットにつながる 128K パケホなどの APN 設定情報はこちらにあります。

設定方法|ドコモの定額データプラン対応のインターネット接続プロバイダ「mopera U (モペラユー)」

ネットワーク設定(アクセスポイント等)やメール設定(POP、IMAP等)など、手動で設定を行う際に必要な各種設定情報をご紹介いたします。

手動設定用詳細情報(PDF形式:735KB)

mopera Uを従量でネットサーフィンやメールを利用する場合のアクセスポイント情報です。

アクセスポイント一覧(PDF形式:1,008KB)

パケホ 128K だと、APN は mpr.ex-pkt.net かな。(必ずサイト/PDF で確認してください) 128K だと使えないですが、フィルタリングフリーアクセスポイントとかあって面白いですね。

実は、ぼくのパケホ契約はまだ昔のやつなので 128K 接続つかえず、インターネット接続は試せていないのですが、後日やってみます。(一応、準備だけしたらしい(笑))

では、最後に mopera u スタンダードで使える、Mzone という公衆無線LAN。 このオプションをつけておくと、携帯電話じゃなくって、普通のそのへんにとんでいる Mzone の 無線 LAN も使えるようになります。

札幌だと、地下街はほぼ全域で使える模様。 あとはホテルとか空港とか、カフェとかですかね。 ぼくは、お昼あの辺の地下街でご飯を食べていることが多いのでためしてがってん。

接続は iPod touch より。 :)

mopera01 

うむうむ。 札幌地下街歩きながら見ていましたが、だいたいつながるようです。 現在 0 円なのでこれはお得。。 ポートは http のみかな、、メールは試しませんでしたが、特殊なポートはふさがれている模様でした。 WEP 接続なので、まぁまぁやることはほどほどに。

iPod touch から http でブラウジングはちゃんとできるので、お昼のオタノシミが増えました(笑)

とりあえず、ダイアルアップ、公衆LAN ともにキャンペーンは 4末までなので、それまでにいろいろ試してみたいと思います。 :)

Jan 12 2010

Eclipse 3.5 wiki エディタのフォント不具合

Eclipse 3.5 からだとおもうのですが、ファイル拡張子を .mediawiki とか tracwiki とかにして開くと wiki 記法が使えるエディタが開くようになりました。 ちょっとドキュメントを書く機会があったので気分転換に使ってみたり。

新しいものというのは、楽しいものである、、ぼくは、うきうきで wiki の記述を始めた・・・。(←ふり

悲劇は、 tracwiki のコード表記の部分で起きた。

travwiki01

倍角か! 昔のワープロか!(←弱いおち

ぼのを「・・・」

というわけで、Eclipse の Bugzilla を探してみるとどうやら SWT の不具合の模様。

Bug 278959 – setting font height should update font width

Created an attachment (id=138181) [details]

次の Eclipse 3.6 には入るようですが、3.5 で使えないのも寂しいのパッチを SWT 3.5.1 に適応してみました。 といっても1行パッチ。

SWT のソースをコンパイルして、上記不具合 class を plugins の下の

org.eclipse.swt.win32.win32.x86_3.5.1.v3555a.jar

に差し替えただけです。

とう!

travwiki02

なおった、なおった。 :-)

.wiki のファイルは HTML や DocBook などに出力でき、リアルタイムでは HTML で表示できます。 設定画面である程度 CSS も変更できるようです。

travwiki03

まぁ正直、エディタの方はまだまだのできっぽいですが、とりあえず記法をオートコンプリートできるのは、wiki になれていないぼくには便利でした。 こまったら、CTRL + SPACE。

travwiki04

DocBook に書き出せるので、docbook2pdf とか docbook2txt とかでも整形して出力できそうですね。

というわけで、ひさびさのこののりのブログはやっぱり良い・・・。 :-)

Jan 2 2010

Twitter のボットと Platform as a Service

明けましておめでとうございます。 2010 年、ぼくも hiromasa.another もいつもどおりのまったり感かと思いますが、今年もよろしくお願いいたします。 :)

さて去年あたりから、Windows Azure などいわゆるクラウド的なサービスがいろいろでてきて、なんだかちょっとわくわく。 今年の興味はこの辺から・・・。

クラウドというと、ラップするレイアがサービスによっていろいろ違ってなんだかよく分からないですが、ぼくはその中の PaaS というサービスが遊ぶに面白そうかなと思っています。

クラウドと呼ばれているものにはいくつか種類があると思いますが、たとえば Amazon EC2 はサーバの物理存在を隠します。 サーバが 2台ほしければ、2 って画面にいれて起動させれば 2台できる。 増やしたければすぐ増やせる。 サーバの手配とかデータセンターの置き場所とか電源とか考えなくていいわけですね。

たとえば Google Apps。 これはサーバとさらにアプリケーションの運用を隠します。 言うならばメールサーバ落ちた!などと会社の情報システム部門がてんやわんやしなくてよくなるというサービス(笑)

で、PaaS というのはその中間。 物理サーバとアプリケーション動作に無関係な運用部分を請け負ってくれます。 で、のせるアプリケーションは各自つくってすぐデプロイできるように環境が整っている感じです。

今で言うところの、レンタルサーバに PHP のアプリケーションを各自入れて動かすの発展系のイメージ。

たとえば現状のレンタルサーバでは WordPress の MySQL のバックアップとか自分でやらなくてはならなくて結構大変ですが、PaaS の場合はスケジュールで勝手にバックアップをとってくれたり簡単にリストアできたり、各種リソースの使用量が管理画面から見えたり、よりアプリケーションよりのサービスが付随します。

PaaS のひとつである、Windows Azure では、既に WordPress も稼働しているとのことです。

「PDC09」リポート:Microsoftはハイブリッドな戦略で古い殻を脱ぎ捨てる (2/3) – ITmedia +D PC USER

欧米を中心に世界中で広く利用されているブログシステム「WordPress」の開発者であるマット・マレンウェッグ氏が登場し、Windows Azure上でWordPressを動作させるデモを紹介した。

さて、この PaaS ですがもう一つの特徴が、様々なアプリケーションを動かすための環境が整っていること。 簡単に言えば、C# とか Java とかそのへんの言語と、そのアプリケーションサーバ環境周りも使うことができます。

PHP では少し無理があったことも簡単にできるようになる・・・。 実はここがぼくの最大の関心事。 大昔 CGI が無料で使える海外サーバがでてきたようなどきどきが(笑)

PaaS のサービスは Google App Engine とか Stax Networks とかありますが、ここでは後者を使ってみました。 Stax のほうがサンドボックスの制限が緩いので遊びやすいのです。

とりあえずつくってみたのは、twitter ボット。

 stax02

PHP でももちろんボットはつくれますが、一般的な PHP の環境はプログラムから動き出すことができないという制約があります。 人のアクセスとか別系の cron とか外的要因からプログラムをキックする必要がありますが、ここでは Java のスレッドスケジューラを使って自分から定期起動するようにしています。

いろんなライブラリが簡単に使えるのもいいところで、このボットは twitter クライアントに twitter4j、また スケジューラ に Quartz というライブラリを使っています。

Twitter4J – A Java library for the Twitter API

Twitter4J は TwitterAPI の Java ラッパです。 Twitter4J を使うと XML や HTTP に詳しくなくても容易に Twitter とインタラクトするアプリケーションを書くことが出来ます。

Quartz Scheduler – Home

Quartz is a full-featured, open source job scheduling service that can be integrated with, or used along side virtually any Java EE or Java SE application – from the smallest stand-alone application to the largest e-commerce system.

ちなみに、Google App Engine はスレッド禁止っぽいので、Quatz は残念ながら動作しないと思われます。 http の通信もなにか特別なことをしなくてはいけなそうでした。(たぶん)

で、とりあえずライブラリや web.xml を配置します。 Stax Networks は Tomcat を使っているようで、また一般的な WAR も配置できるので基本的になにも考えずにいつも通りにつくれます。

stax04

web.xml を以下のように。

<?xml version="1.0" encoding="UTF-8"?>
<web-app>
  <display-name>Desyura</display-name>
  <servlet>
    <servlet-name>QuartzInitializer</servlet-name>
    <servlet-class>
    org.quartz.ee.servlet.QuartzInitializerServlet</servlet-class>
    <init-param>
      <param-name>shutdown-on-unload</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>start-scheduler-on-load</param-name>
      <param-value>false</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet>
    <display-name>RobotInitializer</display-name>
    <servlet-name>RobotInitializer</servlet-name>
    <servlet-class>
    net.maple4ever.desyura.RobotInitializer</servlet-class>
    <load-on-startup>2</load-on-startup>
  </servlet>
</web-app>

QuartzInitializerServlet と、スケジューラの起動の Servlet を順番に登録。

あとはソースを書くだけです。 動作できるかどうかのサンプルでかいただけなので、いんちきをたくさん含んでいることをあらかじめご了承ください。

RobotInitializer.java。 スケジュールのインスタンスをもらって、Job を行うクラスを登録する感じです。 CronTriger を使うと cron みたいな形式で時間を指定できます。

package net.maple4ever.desyura;
 
import java.text.ParseException;
import java.util.Calendar;
import java.util.Locale;
 
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
 
import org.quartz.CronTrigger;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.impl.StdSchedulerFactory;
 
public class RobotInitializer extends HttpServlet {
    
    public static final String START_TIME = "START_TIME";
    private static final long serialVersionUID = 1L;
 
    public RobotInitializer() {
        super();
    }
 
    @Override
    public void init() throws ServletException {
        // QuartzInitializerServlet で作成したスケジューラを取得
        Scheduler sched = null;
        try {
            sched = (new StdSchedulerFactory()).getScheduler();
        } catch (SchedulerException e) {
            throw new ServletException(e);
        }
        // Cron 形式のトリガー作成(とりあえず 5分)
        Trigger trigger = new CronTrigger("trigger1", "group1");
        try {
            ((CronTrigger) trigger).setCronExpression("0 0/5 * * * ?");
        } catch (ParseException e) {
            throw new ServletException(e);
        }
        // JobDetail にコールバッククラス登録
        JobDetail jobDetail = new JobDetail(
                "Twitter Bot"
                , "Twitter Bot"
                , TwitterBotService.class
                , true
                , true
                , true);
        // 起動時間を JobDataMap に格納(twitter のロケールも日本にすること)
        jobDetail.getJobDataMap().put(START_TIME,
                Calendar.getInstance(Locale.JAPAN));
        // スケジュール開始
        try {
            sched.scheduleJob(jobDetail, trigger);
            sched.start();
        } catch (SchedulerException e) {
            throw new ServletException(e);
        }
    }
    
}

 

TwitterBotService.java。 時間がきたら twitter をみてつぶやく Job クラスです。 スケジュールごとに new されるので手を抜いて static で値を保持しています。(本当は context にシリアライズできる形で値をいれるのが良いと思われます)

package net.maple4ever.desyura;
 
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.List;
import java.util.Date;
 
import org.quartz.JobExecutionContext;
import org.quartz.StatefulJob;
 
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
 
public class TwitterBotService implements StatefulJob {
    
    // StatefulJob は同時実行されないが手抜き synchronized しておく
    static private List<Long> read = (List<Long>) Collections
            .synchronizedList(new ArrayList<Long>());
    static private final int PAGE_COUNT = 20;
    
    public void execute(JobExecutionContext context) {
        // スケジュールイベント
        System.out.println("Fire! " + context.getScheduledFireTime());
        // 初回起動時間取得
        Date fistTime = ((Calendar) context.getMergedJobDataMap().get(
                RobotInitializer.START_TIME)).getTime();
        // twitter 接続
        Twitter tw = new Twitter("ユーザ名", "パスワード");
        
        String tweet;
        try {
            // twitter から Mentions をもらう
            List<Status> status = tw.getMentions();
            for(Status stat : status) {
                // 起動時より前の返信は答えない
                if(fistTime.after(stat.getCreatedAt())) continue;
                // すでに返信していたら答えない
                if(read.contains(stat.getId())) continue;
                // 自分のスクリーンネームを相手に置換してつぶやく
                tweet = stat.getText().replaceAll(
                        stat.getInReplyToScreenName(),
                        stat.getUser().getScreenName());
                tw.updateStatus(tweet, stat.getId());
                System.out.println(tweet);
                // 読んだリストに入れておく
                read.add(stat.getId());
            }
            // getMentions() は 20件取得なのでそれを超えたら忘れる
            if(read.size() > PAGE_COUNT) {
                read.remove(0);
            }
        } catch (TwitterException e) {
            // 投稿失敗しても次に期待する
            System.out.println(e.getStackTrace());
        }
    }
    
}

(あ!!、if の位置間違っていることをブログかきながら発見。。(笑))

ひとつしかスケジュールもアカウントも制御できないエコーなボットですが、100 ステップくらいでできちゃうのはお手軽すぎです。

これは実験なのであれですが、スケジュールも twitter も意識させずに文字列操作部分だけ外だしにできるようにプログラムをかえていけばいいかなという感じですね。 Jython とか JRuby とか Groovy とかの Java の上で動くスクリプト言語にその部分をプラグインのように渡すのも面白いかもしれません。

できた WAR は Stax Networks にそのままデプロイできます。 ant タスクがあるのでコマンド一発。 FTP クライアントとかいりませぬ。

hiromasa.another :o ) » Blog Archive » Stax Networks への JavaEE アプリのデプロイ

あとは、ドキュメントにかいてあるとおり build.xml にユーザ名とかパスワード、war の stax-application.xml パスをかきます。

stax-application.xml はとりあえず適当に Stax Networks の管理画面で BASIC Servlet and JSP なアプリを作成しておいて、それをダウンロードしてきてそのまんま使うのが楽かもしれません。

さて、twitter は昔 Jabber をサポートしていたので、たとえば Stax Networks とソケットつなぎっぱなしにして、リアルタイムに反応するボットとかもつくれたと思うのですが、もうできなくて残念。

でも、最近は websocket とかそれっぽい技術もできてきていますので、こういったアプリケーションサーバがあると、いままで http な Web ではできなかったようなことも実現できそうです。

いろいろこのへんの技術で遊んでみたいな、と思った1年の始まりでした。 :)

Dec 26 2009

マルチプラットフォームの GUI アプリケーション

たまぁになんですが、自作のちょっとしたアプリで GUI を使いたいときがあります。 ほいでもって、ぼくは家で大抵は Linux を使っているのですが、せっかくつくったアプリなのでたまに使う Windows でも使いたい、、。 ということで、マルチプラットフォームで動く GUI アプリ。

Mono + GTK、Mono + Windows.Forms、 Java + Swing、 Java + GTK(あるのかな?)、などなど思いつきますが、今回は Java + SWT をやってみました。 :-)

GTK は各種プラットフォームで動作する GUI ツールキットですが、自前で描画をしているので特に Linux 以外で動かすとやっぱりほんのすこーし、違う。 まぁ特別問題があるわけではないのですが、Pidgin や GIMP を Windows などで動作させたことがある方ならなんとなく分かるのではないでしょうか。

Swing は逆に Windows で動かす分にはそれなりなのですが、Linux で動かすとフォント系が厳しい。。 Swing は TrueType も自前で描画するので特にアンチエイリアスがある環境ではなにか違う感じを醸し出します(笑) (フォントレンダラがあんまりよくないのかな)

てなわけで、やっぱネイティブだよねってことで Java + SWT です。

Standard Widget Toolkit – Wikipedia

SWT は Java で書かれている。GUI部品を表示するため、SWT はそのオペレーティングシステムが提供するGUIライブラリを JNI(Java Native Interface)経由で使用する(これはシステム固有のAPIを使う一般的手法である)。SWT を使うプログラムは移植性があるが、ツールキット自体の実装は Java でかかれているにも関わらず、各プラットフォーム固有である。

ネイティブライブラリですが、Windows、Linux、Mac OS X などなどいろんなプラットフォームに移植されていますので、実行ファイルこそ変われど同じアプリケーション(ソース)が動作します。 Eclipse などの巨大なアプリケーションが SWT で動作していますので、ライブラリ自体もかなり枯れていると思われます。

で、SWT にかぶる形で GUI のフレームワークとして JFace というのがあって今回はこれも使ってみました。

とりあえず、SWT と JFace のライブラリを持ってきます。 JFace は Eclipse の plugins に入っているものをほげってきました。(外部 Jar 追加で参照してもいいのですが、なんとなくコピーして自分のおなかに)

jface02

こんな感じにライブラリをいれておきます。 これは Linux の場合。

詳しくはこちらが参照になります。

SWTとJFaceに必要な外部JARファイルを特定する – Identify the Required External JAR Files for SWT and JFace – 何かしらの言語による記述を解析する日記

JFaceプロジェクトには、SWTのクラスとJFaceのクラス、その他JFaceが依存するEclipseのクラスが必要です。SWTプロジェクトのウェブサイトから、SWTのクラスを含むファイルをダウンロードできます。JFaceのファイルとJFaceが依存するファイルは、プロジェクトに手動で追加する必要があります。

ほいでもってソースをかきます。

あちこちのサイト様を参照しました。 JFace は ApplicationWindow から extends して開始です。 (未来の自分用へのメモ)

JFaceSample.java

package net.maple4ever.sample.jface;
 
import java.io.File;
 
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
 
public class JFaceSample extends ApplicationWindow {
    
    public JFaceSample() {
        super(null);
    }
    
    @Override
    protected Control createContents(Composite parent) {
        // ウインドウタイトル設定
        parent.getShell().setText("JFaceSample");        
        // ウインドウサイズ設定
        parent.getShell().setSize(480, 320);
        
        // 親の下にさらに Composite をつくる
        Composite child = new Composite(parent, SWT.NONE);
        // レイアウトマネージャ設定
        child.setLayout(new GridLayout());
        // テーブル作成
        TableViewer table = new TableViewer(child);
        table.getTable().setLayoutData(new GridData(GridData.FILL_BOTH));
        // テーブルにプロバイダ設定
        table.setContentProvider(new FileTableContentProvider());
        table.setInput(new File(System.getProperty("user.home")));
        
        return parent;
    }
    
    @Override
    protected MenuManager createMenuManager() {
        // 親メニュー作成
        MenuManager bar = new MenuManager();
        MenuManager fileMenu = new MenuManager("ファイル(&F)");
        // Action クラスを継承したインスタンスを渡す
        fileMenu.add(new ActionExit(this));
        // 追加メニューを返却
        bar.add(fileMenu);
        
        return bar;
    }
    
    public static void main(String[] args) {
        // ApplicationWindow インスタンス生成
        JFaceSample window = new JFaceSample();
        // メニューバー追加(createMenuManagerメソッド が呼ばれる)
        window.addMenuBar();
        // ウインドウクローズまでイベントループブロック指定
        window.setBlockOnOpen(true);
        // イベントループ開始(終わるまでここでブロック)
        window.open();
        // イベントループ終わったらリソース解放
        Display.getCurrent().dispose();
    }
    
}

ActionExit.java

package net.maple4ever.sample.jface;
 
import org.eclipse.jface.action.Action;
import org.eclipse.jface.window.ApplicationWindow;
 
class ActionExit extends Action {
    
    private ApplicationWindow window = null;
    
    public ActionExit(ApplicationWindow win) {
        // ApplicationWindow もらっておく
        window = win;
        setText("終了(&X)@Ctrl+W");
    }
    
    @Override
    public void run() {
        // Action の処理を run にかく
        // ApplicationWindow 呼んじゃえ
        window.close();
    }
    
}

FileTableContentProvider.java

package net.maple4ever.sample.jface;
 
import java.io.File;
 
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.Viewer;
 
class FileTableContentProvider implements IStructuredContentProvider {
    @Override
    public Object[] getElements(Object element) {
        File currentDir = (File) element;
        File[] files = currentDir.listFiles();
        return files == null ? new Object[0] : files;
    }
    
    @Override
    public void inputChanged(Viewer arg0, Object arg1, Object arg2) {
    }
    
    @Override
    public void dispose() {
    }
}

で、まずは Linux。 実行~ :)

jface03

うむうむ。 Linux SWT の GTK 版なのであたりまえですが、GTK で描画されています。 Linux の場合、GTK のテーマでみんないろいろ画面をかえているので、何にもしなくても追随してくれるのはやっぱりいいですね。 :)

同様に Windows でも Windows 用の SWT ライブラリをあつめて、同じアプリケーションのソースを実行!

jface01

エアローってことで、 Windows 7 で動かしたの図ですが同じソースでネイティブ描画してくれております。 よい、よい。 :D

JFace は、普通の GUI フレームワークとちょこっと趣向が違うところがあったりして面白いですね。 スレッドの中からの GUI 描画方法とかまだ全然分かっていない部分もあって本気で使いこなすには時間がかかりそうですが、小物ならなんとかいけそうです。

ちなみにできたアプリの配布ですが、小さいアプリであれば Eclipse のエクスポートウイザードの実行形式 jar で ant 書き出してもらうのが楽そうです。

jface04

で、できた jar 玉を JRE が入っていれば通常ダブルクリックで実行できます。

jface05

gjc で JRE なしのまじネイティブ (.exe 版とか)もできるのかなぁ。 Eclipse の gjc 版はあるのでできると思いますが、ちょっとそこまでは調べていません。

swt 、JFace とも Eclipse Public License 系のライセンスなのでこういった配布形態も問題ないとおもいますが、やる方がいたら各自よくご確認ください。 ぼくは配布するまではなさそうなので、、(笑)

てなわけで、画面系はやっぱりネイティブがいいよね、という方は試してみるといいかもしれません。 :)

Nov 14 2009

Moblin 2.1 の研究

以前から気になっていました、解像度の低いコンピュータ向けの UI をもつ Moblin を試してみました。 とりあえず ライブ USB で ThinkPad / IdeaPad で起動してみることに。

最近ネットブックとかに Windows とは別に、起動選択でブラウザとメールくらいが高速起動でつかえる機能がついているものがありますが、あれのすごいやつだと思ってもらえれば正解です。 :)

HOME | moblin.org/jp

Moblin は、The Linux Foundationが主催するモバイル端末向けのLinuxディストリビューションで、ネットブックやMobile Internet Device(MID)、In-Vehicle Infotainment(IVI)向けのソフトウェア技術、アイデア、プロジェクト、コード、アプリケーションを共有するオープン・ソース・コミュニティです。

いまのとろこ、ネットブック/ネットトップ向けのリリースが成果物の中心となっていますが、これらをカスタマイズして MID など小型コンピュータにいれていくのだと思います。

ベースは Linux で、その上に OpenGL を使った描画ライブラリの Clutter や、解像度が低い PC 用への UI ツールキットなどの Moblin のキモがのっていくイメージに見えました。 このうわものを各ディストリビューションに移植した Ubuntu Moblin や Fedora Moblin などもあるようです。(本家の Moblin は Fedora ベースの for Intel ってな感じでしょうか)

てなわけで、

ごう、もぶりん!

moblin01

噂通りの超高速起動で、 USB メモリからですが、おそらく BIOS から 12,3 秒くらいで起動してしまっている気がします。 とりあえずアニメしたりしてめんこいです。 :)

moblin02

しばらく使っているとトップ画面はこんな風に。 おもしろいのがデータを使った履歴がサムネイルで真ん中の縦列に表示されることです。 見た Web ページや画像、動画などなど。 アプリ指向ではなくデータ指向でつくられていることが伺えます。

右の縦列は外部的な時系列なデータの動きがでるようになっているようです。 Last.fm と twitter がとりあえず標準で対応していました。 左の縦列は登録していた未来、予定や TODO などが出るようです。

基本的に Linux/GTK ベースなので一般的な UNIX アプリは動きそうですが、本領を発揮するのが Clutter と Moblin UI をつかってできているアプリだとおもいます。 基本はフル画面。 iPhone のアプリを想像してもらうといいかもですね。

まずはブラウザ。 Firefox ベースですが、小さい画面でうごくように UI が再設計されています。 2.1 からアドインも使えるようになっているようです。

moblin03 

でもってメーラです。 ベースは不明。。(笑)

moblin04 

タブがつかえる模様。

アプリのランチャーです。 GNOME DO みたくアプリ名入力でしぼっていけます。

moblin06

当然マルチタスク対応ですのでアプリのスイッチャーがあります。

moblin07

仮想デスクトップみたいになっていて、フル画面じゃないアプリも(普通の GTK っぽいアプリ)を配置できます。 スクリーンショットでは画面1(左)で動画を再生していますが、スイッチング中の縮小表示でもちゃんと動いているのはさすがといったところです。 :)

まだ Moblin ネイティブ(?)的なアプリが少ないようで、ブラウザ、メーラ、メディア再生がそれっぽくなっていて、残念ながら TODO やスケジューラはいまいちな感じでした。 もちろん Evolution とかも動くのだと思いますが、今後各アプリとも UI を Moblin にあわせたものがそろって本領発揮といったところだと思います。

アプリの開発環境も(なんとなくの予想ですが) Python バインディングもでてきそうな雰囲気なので、できたら手軽におしゃれなアニメ UI がつくれるようになりそうですね。

ちなみにこのネットブック版、完成度ははっきりいってしまうとまだまだです。 特に日本語環境は、本気で使おうと思うと対応はしていますがやばめっぽい。 あとメディアが DNLA サーバみてくれなかったんです~。 対応しているハズなんですが。。 あと、IdeaPad では無線LAN が使えませんでした、ThinkPad X61 は OK。

まぁまぁネットブック向けにリリースされているものはコンセプトモデルも兼ねていると思いますので、これを各社カスタマイズしてコンピュータにいれて出荷するのが本流かと思います。 さっくり起動してきれいに動く感覚はこれで十分わかりそうです。

とりあえず紹介動画とかみてたのしげな夢を見てみることにします。

かわいすなぁ。 :)

Nov 8 2009

Stax Networks への JavaEE アプリのデプロイ

慣れの問題もあるかもですが、ぼくはちょっとした自分でしか使わないような Web アプリをつくるのに PHP とかより Java を使った方が早い場合があります。 言語的な問題というより環境、、便利なライブラリがたくさんあって、いれるのも lib に jar 入れるだけだし~、みたいな(笑)

問題はインターネット上にデプロイする先があまりないことですが、クラウドがでてきてくれたので最近はいくつか無料で使わせてくれるところがでてきています。

昔 Morph AppSpace を使って遊んでいましたが、Stax Networks というのも良さそうなので実験してみました〜 Google App Engine なんてのもありますね。:-P

stax01

Stax Networks – Home

The fastest way for Java EE developers to build, manage and scale applications in the Cloud.

というわけで、早速適当なものをつくってデプロイ。

以前から iアプリ用の Java の twitter クライアントがほしいなぁとおもっていて、この場合サーバサイドのプロキシがないと実装できないので、それをつくるのを見据えて、とりあえず REST すると public タイムラインとってくるのをやってみようと思いました。

Java EE に JAX-RS という REST の仕様がありますが、その実装である JBoss の RESTEasy と、twitter にアクセスするために twitter4j を使ってみます。

JBoss、JAX-RS実装「RESTEasy 1.0」正式版リリース – SourceForge.JP Magazine

JAX-RS(JSR 311)は、JavaでRESTアーキテクチャを利用してWebアプリケーションを作成するためのJCP仕様。RESTEasyはJBossのJAX- RS実装で、開発者に容易に開発できるフレームワークを提供する。Tomcatなど、JDK 5以上をベースとしたサーブレットコンテナで動作するが、「JBoss Application Server」と蜜に統合することで、ユーザーエクスペリエンスを改善できるという。

Twitter4J – A Java library for the Twitter API

Twitter4J は TwitterAPI の Java ラッパです。 Twitter4J を使うと XML や HTTP に詳しくなくても容易に Twitter とインタラクトするアプリケーションを書くことが出来ます。

Eclipse で動的 Web プロジェクトを新規作成して、WebContent/WEB-INF/lib に各ライブラリ jar を放り込みます。

WebCOntent/WEB-INF/web.xml で RESTEasy をサーブレット登録して URL にマッピングします。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
    <display-name>DJOdekoServer</display-name>
    <context-param>
        <param-name>resteasy.scan</param-name>
        <param-value>true</param-value>
    </context-param>
    <context-param>
       <param-name>resteasy.servlet.mapping.prefix</param-name>
       <param-value>/api</param-value>
    </context-param>
    <servlet>
        <servlet-name>Resteasy</servlet-name>
        <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Resteasy</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

これでアプリをかく準備完了です。 ソースを適当にかきます。 :-)

RESTEasy は resteasy.scan を true にしておくと、@Path のアノテーションをもつクラス(?)を勝手にスキャンしてくれてクラスロードしてくれるようです。

ということで、@Path で URI を指定しておけばエントリポイントが勝手にできます。 便利ですね。

package net.maple4ever.djodeko.server.rest;
 
import java.util.HashSet;
import java.util.List;
import java.util.Set;
 
import javax.ws.rs.Path;
import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
 
import org.jboss.resteasy.annotations.providers.jaxb.Wrapped;
 
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
 
@Path("/public")
public class TimeLine {
 
    @GET
    @Produces("application/xml")
    @Wrapped(element="public")
    public Set<PublicTimeLine> getPublic() {
        Twitter twitter = new Twitter();
        List<Status> statuses = null;
        try {
            statuses = twitter.getPublicTimeline();
        } catch (TwitterException e) {
            e.printStackTrace();
        }
        
        HashSet<PublicTimeLine> publicTimeLine = new HashSet<PublicTimeLine>();
        for (Status status : statuses) {
            publicTimeLine.add(new PublicTimeLine(
                    status.getUser().getName(),
                    status.getText()));            
        }
        return publicTimeLine;
    }
 
}
 
@XmlRootElement(name = "tweet")
class PublicTimeLine {
    
    @XmlElement
    String account;
    @XmlElement
    String tweet;
    
    public PublicTimeLine() { }
    
    public PublicTimeLine(String account, String tweet) {
        this.account = account;
        this.tweet = tweet;
    }
 
    public String getAccount() {
        return account;
    }
 
    public String getTweet() {
        return tweet;
    }
    
}

その try cache はおかしーじゃねーかというつっこみはなしで。。(笑)

twitter4j を使ってパブリックタイムラインをもらって XML で出力する例です。  @Path("/public") を指定しているので、コンテキストルート/public にメソッドがマップされます。 メソッドにさらにアノテーションでパスを指定したり引数をもらうこともできます。

まぁまぁここまではできるひとなら 15分仕事です。 PHP より楽じゃねっすかね。 ローカルではうまくうごくことでしょう。 :)

で、これを Stax Networks にデプロイするわけですが、、はて、WAR玉 ってデプロイできるかな。 なにか専用の SDK あるみたいですが。。(笑)

Deploying WAR Files – Stax

If you have an a Java web application packaged as a WAR file, you can use the Stax Deploy ANT task from the Stax SDK to deploy your WAR file to the Stax Cloud using an ANT script.

というわけで、ちゃんとドキュメントがありました。 SDK に ant タスクがあるようです。 とりあえず、SDK をどっかにいれてあと ant もいれておきましょう。 (Ubuntu には ant のバイナリパッケージにあるんですが、念のため本家版をつかっています。 Eclipse 内蔵の ant でもいいかもです。)

Ubuntu の場合は、 ~/.profile に以下を書いておくといいかもです。

#Stax Setting
export STAX_HOME=/home/hiromasa/Application/stax/stax-sdk-0.3.6
export ANT_HOME=/home/hiromasa/Application/stax/apache-ant-1.7.1/
export PATH=$PATH:$STAX_HOME:$ANT_HOME/bin

あとは、ドキュメントにかいてあるとおり build.xml にユーザ名とかパスワード、war の stax-application.xml パスをかきます。

stax-application.xml はとりあえず適当に Stax Networks の管理画面で BASIC Servlet and JSP なアプリを作成しておいて、それをダウンロードしてきてそのまんま使うのが楽かもしれません。

stax03

WAR ファイルはとりあえず面倒なので Eclipse のプロジェクトエクスポートでつくっています。 これで ant すればネットワーク越しにデプロイしてくれます。  Morph AppSpace と違ってすぐデプロイしてくれるようです。 URL にアクセスしてみましょう。 :)

http://djodeko.hiromasa.staxapps.net/api/public

ちゃんと動いていますね。 :)

さて、Stax Networks は素敵なことにドメインマッピングに対応しています。 とりあえず、自分のドメインの CNAME を設定しておきます。

cname djodeko djodeko.hiromasa.staxapps.net.

最後にドットいれるのを忘れないよう。。

で、名前がひけるようになるまで我慢の子です。 Stax Networks 的に DNS が引ける状態でないとうまく登録してくれません。 もし管理画面で save しても値が空になるようならこの状態です。 ややまってからしましょう。 うまく保存できたら、、

http://djodeko.maple4ever.net/api/public

素敵ですね。 :)

実験的につくったものなので、まぁ URI かえるといろいろエラーでますが、どうやら Tomcat 使っているみたいです。

ファイルの書き込みがなければほとんどのフレームワーク/ライブラリは素直にうごくような雰囲気です。

DB (MySQL が使える)のほうはまだためしていませんが、JNDI 設定してしまえばあとは同じでしょう。 S2JDBC とか Hibernate とか動くんだと思います。

ふと思い立って、CMS とかも Java 製のものあるのかなとおもって検索してみると、エンタープライズ向けにいくつかあるようですね。 アプリケーションコンテナいるとコネクションプールとかシングルトンつかえるから性能的にはやっぱり有利な部分もあると思います。 PaaS が増えてくるとすればこれらも要チェックかもですね。

とりあえず、Stax は何もしなくてもいろいろ動きそう。 いろんなアプリをデプロイして実験してみるのも面白いかもしれません。