Japan Akihito Fujii's Weblog 日々是新 Akihito Fujii's Weblog

月曜日 8 29, 2005

English Translation: (Google) / (Yahoo!)

Duke MouseJavaOne Tokyoの開催 のアナウンスが開始されています。11/8, 9, 10東京国際フォーラムです。Java Developerだけでなく、Java関係者の皆様是非ご参加くださいませ。今年はJava誕生10周年の年です。JavaのDeveloper, 関係者はもちろんのこと、これまでJavaのEventに縁のなかった人も、単なるツールとして割り切って使っていた人も、オタクが多そうでJavaを敬 遠していた人も、Micorsoft好きな人(!?)も、日本ではIBMのJavaイベントばかりに参加していた人も(!?)、今年ばかりはこの JavaOne TokyoでJava 歴史を振り返り10周年を祝い楽しみましょう!今年のJavaOne Tokyoイベントに参加せず、どのJavaイベントに参加するんだ?という感じでsession数もJava Computingに比べかなり多くなってます。
ちなみに、自身でJavaOneのSpeakerになりたいという方。技術を広めるチャンスです。(名前を売るチャンスです(笑))一般公募のフォームか ら応募してください。オープンソース、知の共有の時代です。昔のように独自ノウハウを蓄積し切り売りしていては、ITの流れに取り残されることは周知の事 実です。得たノウハウ、知識を素早く公開し世に問い、拡張改善をスピードアップし、成功した技術をピックアップしてサービスを含めMonetizeする。 "Participation Age"のビジネスモデルは、小さな勇気がそのスタートです。是非、積極的に参加してください。日本のJavaOneなら英語の問題もないですから First stepとしてはGoodですよね。(ちなみに、Speakerになると専用控え室での特別待遇はもちろんのこと、(確か)セッション無料です。加えて、 いろんな有名人と会話できます。技術者にとって、よい技術者との会話に勝る明日への糧はありませんよね。)
余談ですが、イベントの裏方からDuke Mouse試作品の写真(右参照)を入手してしまいました。これはレアです、すばらしい!喜んでもって帰るとまたカミサンにバカにされそうです(笑)

金曜日 8 19, 2005

English Translation: (Google) / (Yahoo!)

どんなお客さんと何の話をしたということは、基本的にBlogにむやみに書いてはいけないと思うので、固有名詞が書けませんが・・・今日はお客さんとのMeeting中に、ちょっとしたことから今後のITアプリの方向性の漠然とした会話で話が急にかみ合ってしまい、Meeting中に「今度飲みに行きましょう!」と当人同士で盛り上がってしまいました。(恥ずかしい・・・Mktg失格?)
最後に小職のBlogも見ていただけているとのこと・・・しかし、いずれにせよこのような出会いは嬉しいものです。

水曜日 8 17, 2005

English Translation: (Google) / (Yahoo!)

NetBeansの歌がupされてる。(ホント、好き、こういう動き。)netbeans.jpのみなさま。これもついでにL10nしてくださいませ。
English Translation: (Google) / (Yahoo!)

あら・・・奥さん、サイボウズ・ラボに転職されたんですね。ご活躍を期待しております。

金曜日 8 12, 2005

English Translation: (Google) / (Yahoo!)

JavaのWeb Applicationとして、RSS/Atom Feedを作成するプログラムを作成してみましょう。J2EE web applicationの開発に精通した方には、今回の内容はあまり有益ではないかも知れませんが、「RSS/Atom FeedってどうWebから生成すればいいのだろう」と漠然と考えている方にはお勧めです。Javaのツールを使って簡単に実現することができます。今回 はJava.netのRome Projectが提供しているFeed Syndication APIとそのsample codeをそのまま利用します。
RomeのFeed Syndication APIを利用することで、様々なFeed Formatに非常に簡単に対応することが可能です。もちろん、JavaのAPIですから既存のJ2EE web applicationにも直ぐに適用することができます。JDK だけで開発するのも可能ですが、今回は今後のことも考えて、最新のJava統合開発環境のNetBeans 4.1 日本語版と、J2EE 1.4の実行環境であるApplication Server 8.1 PEを利用します。
こんな簡単なことをするのに、なぜ統合開発環境とApp serverをと思われるかもしれませんが、ビルドや配備作業、デバッグ、プロファイリング、HTTPモニタ機能など、現実の開発に必要なツールが多数含 まれているためです。(今後好評ならこれを発展させて行きたいので・・・)

準備
  • Rome プロジェクトの サ イトからバイナリをダウンロード、解凍し、rome-0.6.jarを取り出します。Romeは、JDOMを利用しているため、JDOMのサイトからJDOM 1.0のバイナリをダウンロード、解凍し、jdom.jarを取り出します。
  • 今回は無料で利用できるJava開発ツールと、J2EE Application Serverを利用するため、NetBeansとSun Java System Application Server 8.1 Platform Editionをインストールします。NetBeans, SJS Appliction Server 8.1 PEは、NetBeans.orgからダウンロードが可能です。NetBeans.orgのダウンロードページからNetBeans IDE 4.1 with J2EE Application Server 8.1 PE bundleを選んでください。バイナリをダウン ロード後、インストールしてください。インストールしたApplication Server 8.1 PEは、NetBeansを起動し、左側パネルの「実行時」タグをクリックし実行時ペインを開き、サーバを右クリックし、「サーバを追加」を選択してくだ さい。ウィザードが起動し、指示に従い情報を入力することで追加することが出来ます。
サーバの追加 App server 8.1の追加

 アプリケーションの開発
  •  NetBeansを起動し、新規プロジェクトを作成してください。ここではFeedApplication1としてWebアプリ ケーションのプロジェクトを作成します。
(各スナップショットは、画像のみを表示することで拡大できます。)
プロジェクトの作成 プロジェクトの作成

  • プロジェクトタグのFeedApplication1を右クリックし、新規からJavaパッケージを選択し、このアプリケーションの package名を指 定します。ここでは、jp.co.sun.feedとしています。
ライブラリの追加 

  • プロジェクトタグのライブラリを右クリックし、「JAR/フォルダを追加」を選び、rome-0.6.jarとjdom.jarをそれぞれ追 加してください。

ライブラリの追加

  • プロジェクトタグのFeedApplication1を右クリックし、新規からサーブレットを選択し、新しく SampleFeedServletを作成します。サーブレットのパッケージ名は、先ほど作成したjp.co.sun.feedが選択可能になっていま す。<コンテキスト>/<URLマッピング名>でSampleFeedServletが呼び出されるよう、URLマッピングを /feedとします。

SampleFeedServlet servlet mapping

  • 作成したSampleFeedServletのコードを追加します。このコードはRome プロジェクトのサンプルコードを修正して利用しています。(コードの詳細はまた別の機会にでも紹介することにします。)Feedが英語のままだとつまらな いので、記述は日本語に変更しています。
/*
 * SampleFeedServlet.java
 * Most of codes are copyed from rome-sample-06 FeedServlet.java
 * Please refer to rome-sample-06 which is available on http://wiki.java.net/bin/view/Javawsxml/Rome
 * Created on 2005/08/11, 16:51, Akihito Fujii
 */
/*
 * Copyright 2004 Sun Microsystems, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package jp.co.sun.feed;

import java.io.*;
import java.net.*;

import javax.servlet.*;
import javax.servlet.http.*;
import com.sun.syndication.feed.synd.*;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedOutput;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author akihito
 * @version
 */
public class SampleFeedServlet extends HttpServlet {

    private static final String DEFAULT_FEED_TYPE = "default.feed.type";
    private static final String FEED_TYPE = "type";
    private static final String MIME_TYPE = "application/xml; charset=UTF-8";
    private static final String COULD_NOT_GENERATE_FEED_ERROR = "Could not generate feed";

    private static final String DATE_FORMAT = "yyyy-MM-dd";

    private String _defaultFeedType;
   
    public void init() {
        _defaultFeedType = getServletConfig().getInitParameter(DEFAULT_FEED_TYPE);
        _defaultFeedType = (_defaultFeedType!=null) ? _defaultFeedType : "atom_0.3";
    }
   
    /** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

        DateFormat dateParser = new SimpleDateFormat(DATE_FORMAT);

        SyndFeed feed = new SyndFeedImpl();

        feed.setTitle("Sample Feed (created with Rome)");
        feed.setLink("http://rome.dev.java.net");
        feed.setDescription("このフィードはRome(Java syndication utilities)を利用して生成されています。");

        List entries = new ArrayList();
        SyndEntry entry;
        SyndContent description;

        entry = new SyndEntryImpl();
        entry.setTitle("Rome v0.1");
        entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome01");
        try {
            entry.setPublishedDate(dateParser.parse("2004-06-08"));
        }
        catch (ParseException ex) {
            // IT CANNOT HAPPEN WITH THIS SAMPLE
        }
        description = new SyndContentImpl();
        description.setType("text/plain");
        description.setValue("Romeの初期リリースです。");
        entry.setDescription(description);
        entries.add(entry);

        entry = new SyndEntryImpl();
        entry.setTitle("Rome v0.2");
        entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome02");
        try {
            entry.setPublishedDate(dateParser.parse("2004-06-16"));
        }
        catch (ParseException ex) {
            // IT CANNOT HAPPEN WITH THIS SAMPLE
        }
        description = new SyndContentImpl();
        description.setType("text/plain");
        description.setValue("バグ修正、APIのマイナーチェンジ、数件の新機能の追加。"+
                             "<p>詳細は <a href=\"http://wiki.java.net/bin/view/Javawsxml/RomeChangesLog#RomeV02\">Changes Log for 0.2</a>を参照してください</p>");
        entry.setDescription(description);
        entries.add(entry);

        entry = new SyndEntryImpl();
        entry.setTitle("Rome v0.3");
        entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome03");
        try {
            entry.setPublishedDate(dateParser.parse("2004-07-27"));
        }
        catch (ParseException ex) {
            // IT CANNOT HAPPEN WITH THIS SAMPLE
        }
        description = new SyndContentImpl();
        description.setType("text/html");
        description.setValue("<p>バグ修正、APIの変更、数件の新機能追加、ユニットテストの実施</p> "+
                             "<p>詳細は<a href=\"http://wiki.java.net/bin/view/Javawsxml/RomeChangesLog#RomeV03\">Changes Log for 0.3</a>を参照してください。</p>");
        entry.setDescription(description);
        entries.add(entry);

        entry = new SyndEntryImpl();
        entry.setTitle("Rome v0.4");
        entry.setLink("http://wiki.java.net/bin/view/Javawsxml/Rome04");
        try {
            entry.setPublishedDate(dateParser.parse("2004-09-24"));
        }
        catch (ParseException ex) {
            // IT CANNOT HAPPEN WITH THIS SAMPLE
        }
        description = new SyndContentImpl();
        description.setType("text/html");
        description.setValue("<p>バグ修正、APIの変更、数件の新機能追加、ユニットテストの実施終了< /p>"+
                             "<p>詳細は<a href=\"http://wiki.java.net/bin/view/Javawsxml/RomeChangesLog#RomeV04\">Changes Log for 0.4</a>を参照してください。</p>");
        entry.setDescription(description);
        entries.add(entry);

        feed.setEntries(entries);

       
        try {
           
            String feedType = request.getParameter(FEED_TYPE);
            System.out.println("FeedType:"+ feedType);
            feedType = (feedType!=null) ? feedType : _defaultFeedType;
            feed.setFeedType(feedType);

            response.setContentType(MIME_TYPE);
            SyndFeedOutput output = new SyndFeedOutput();
            output.output(feed,response.getWriter());
        }
        catch (FeedException ex) {
            String msg = COULD_NOT_GENERATE_FEED_ERROR;
            log(msg,ex);
            response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,msg);
        }
       
    }
   
    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     */
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
   
    /** Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
   
    /** Returns a short description of the servlet.
     */
    public String getServletInfo() {
        return "Short description";
    }
    // </editor-fold>
}


  • 作成されているindex.jspを編集します。
    (省略)
  <body>

    <h1>Feed JSP Page</h1>
    <BR><A HREF="./feed">FeedServlet パラメータなし</A><BR>
    <BR><A HREF="./feed?type=atom_0.3">FeedServlet Atom</A><BR>
    <BR><A HREF="./feed?type=rss_1.0">FeedServlet RSS 1.0</A><BR>
    <BR><A HREF="./feed?type=rss_2.0">FeedServlet RSS 2.0</A><BR>
   
    <%--(以下省略)

  • Webアプリケーションの配備記述子に、デフォルトのFeedタイプをを指定するための初期パラメータを追加します。
初期パラメータ

アプリケーションの実行
  • 実行ボタンを押し、アプリケーションをコンパイル、パッケージング、配備し、実行します。ブラウザが起動され、index.jspが表示され ます。それぞれのリンクをクリックすることにより、1つのサーブレットから異なるフォーマットのFeedが生成されます。以下はAtom, RSS 1.0, RSS 2.0の実行例です。
実行画面 Atom Feed RSS 1.0 RSS 2.0

最後に

このサンプルアプリケーションでは、初回ということで、Feedの情報をServletのコード内で作成していますが、情報をDBから取得したり、動的に生成したり、または、ユーザによってJ2EEの機能を活用した認証や、Feedのパーソナライズしたりすることにより、様々なことが可能になります。(LDAPと連携してここのIdentity情報をベースにしたPersonalized Feedなども実現できますね。)またJ2EE Application Server上で構築することは、このアプリの可用性向上や、負荷分散機能の実現が容易なことをも意味します。
この記事が好評なようであれば・・・、次の機会にこれらに挑戦してみたいと思います。(NetBeansのMobility Packを利用して、MIDPのRSS Readerと連携するってもも個人的には興味がありますが・・・)

Rome Projectのメンバーに感謝。

水曜日 8 10, 2005

English Translation: (Google) / (Yahoo!)

konfabulatorkonfabulator(Yahoo!が 買収)をinstall。右のように自宅のMacと同じようなテスクトップが出現してちょっと嬉しい・・・ということが書きたかったわけではありません。
SunにいるとServer Sideの重厚な会社だけあって、とかくこういったトレンドネタに疎くなるのでちょっとBlogに派手な自分のKonfabulatorのDesktop を乗っけてみました。
Googleの各種サービスや、Yahoo!のサービスなどのIneternet Service(Web Service)が、こういったWidgetでDesktopと融合していくなか、今後のDesktop環境どうなり、サービスの形態がどうなり、どのよ うなServer side technology, やplatformが必要となるのかもっと真剣に考えなければいけません。
Web 2.0時代(なんか本当にある仕様のような響きなので、あまりこの言葉はすきではありませんが)のServer側に求められるService Grid型(Utility computing 型のComputing farm)のPlatformは、こういったService, Desktopとの融合を想定したplatformであるべきなのでしょう。こういったComsumer向けserivceをhostingする Service Gridという発想で、次世代のサーバ側プラットフォームを考えると、ConsumerサービスのPlatformにとっては、SIやISVの重要度は低 下し、大小を問わないこまかなサービス層のGrid serviceへの取り込み、もしくはまとまった大規模Service providerの取り込みが、Service Platform vendorの主戦場になるであろうことが想像がつきます。Service開発者から考えると、こういったService platformを想定した場合、細かな単位でのDeveloper Gridが必要です。サーバを立ち上げて、Web servicesを提供するなんてのはnon senseです。DeveloperがService GridのStaging環境でServiceを開発し、世に問う形が新しいISV/ASPの形になるのでしょう。
ちょっと前のめりで走りすぎではありますが、Serviceを巻き込んだITの大きな波が来ているなぁと感じる今日この頃です。
「希薄化するレイヤー境界とプラットホーム間競争」と題して渡辺氏がcnetのblogで取り上げているような内容も非常に興味深く、一読の価値ありで す。

火曜日 8 09, 2005

English Translation: (Google) / (Yahoo!)

平鍋さんのBlog「An Agile Way」にJUDE/NetBeansの連携記事に関してコメントが掲載されています。平鍋さんの説明力にはいつも「すごいなぁ」と思ってしまいますが、「簡単重要」いい言葉です。

月曜日 8 08, 2005

English Translation: (Google) / (Yahoo!)

第1回Feed Business Syndicationカンファレンスを実施しました。私がモデレータを務めたパネルディスカッションの詳細は、後日FBSのsiteにて紹介します。

水曜日 8 03, 2005

English Translation: (Google) / (Yahoo!)

本日Feed Business Syndicationの第1回セミナーをグロービス東京オフィスで開催します。私は、"Feed syndicationの活用法”についてのパネルディスカッションのモデレータとして参加します。セミナーの参加者は100名を予定しており、告知2,3日で既に満席になっていますが、興味のある方は藤井までご連絡くださいませ。プレゼンなどの内容はFBSのWeb siteで公開される予定です。

月曜日 8 01, 2005

English Translation: (Google) / (Yahoo!)

「JUDE、NetBeansでアプリケーション構築」と題し、UMLモデリングツールの雄「JUDE」とNetBeansとの連携に関する技術チュートリアルが公開されました。連携は簡単です。是非Tryしてみてください。
日々是新 Akihito Fujii's Weblog