Sep 28, 2005

[Library] コンテンツ移動のお知らせ

http://www.in-vitro.jp/blog/index.cgi/Library/20050928_01.html はこちらに移動しました。
Posted in Library | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

[Derby] Derby の実行速度

Derby の INSERT 速度を試してみた。 時間がなかったのでかなりいい加減。 非常に単純な INSERT 文を 100 万回繰り返してみた。

結果


embedded モード server モード
INSERT 1000000回
コネクション毎に 1000000 件ずつ 1 回繰り返し
45406msec (≒45秒) 320594msec (≒5分)
INSERT 1000000回
コネクション毎に 1000 件ずつ 1000 回繰り返し
51797msec (≒52秒) 321812msec (≒5分)
INSERT 1000000回
コネクション毎に 1 件ずつ 1000000 回繰り返し
798422msec (≒13分) 計測不能(何故か Exception で落ちる)

環境

OS
Windows XP Professional
CPU
Pentium4 2.4GHz
Memory
1GByte

コード(部分抜粋)

    protected void insertRecordMassively1() throws SQLException {

        // 1 回のコネクションで 1000 件の INSERT を 1000 回繰り返す。
        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            Connection connection = this.getConnection();
            try {
                PreparedStatement statement = connection
                        .prepareStatement("INSERT INTO sample VALUES (?,?)");

                for (int j = 0; j < 1000; j++) {
                    int field01 = (int) ((Math.random() * 100000) % 10000);
                    String field02 = "01:" + field01;
                    statement.setInt(1, field01);
                    statement.setString(2, field02);
                    statement.executeUpdate();
                }

                connection.commit();
                connection.close();

            } finally {
                if (connection != null) {
                    connection.close();
                }
            }
        }
        long end = System.currentTimeMillis();

        System.out.println("INSERT * 1000 * 1000 : " + (end - start) + "msec");
    }

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

Sep 26, 2005

[Library] コンテンツ移動のお知らせ

http://www.in-vitro.jp/blog/index.cgi/Library/20050926_01.html はこちらに移動しました。
Posted in Library | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

[Derby] Derby を server モードで起動

先日は Derby を embedded モードで起動したので、今回は server モードを試してみた。 server モードの場合も embedded モードとほとんど同一のコードで起動できた。 意外と簡単。 クライアント側も Driver と URL を変更したら何事も無く接続できた。

Derby の実行環境構築

Derby を Server モードで起動する場合、embedded モードで利用したもの + α の jar が必要になる。

  1. Derby(derby.jar、derbynet.jar、derbyclient.jar) をクラスパスに追加

サンプルコード

package jp.in_vitro.codelets.derby;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import org.apache.derby.drda.NetworkServerControl;

public class Codelet3 {

    public Codelet3() {
        super();
    }

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

    protected void execute() throws Exception {

        // Derby の起動。
        DerbyServer server = new DerbyServer();
        server.start();
        while (!server.isInitialized()) {
            Thread.sleep(1000);
        }

        // ネットワーク(と言っても loopback)経由で Derby に接続。
        DerbyClient client = new DerbyClient();
        client.initializeClient();
        client.execute();

        // Derby の終了。
        server.stop();
    }

    public static class DerbyClient {
        private static final String DRIVER = "org.apache.derby.jdbc.ClientDriver";
        private static final String PROTOCOL = "jdbc:derby://localhost:1527/";

        public DerbyClient() throws ClassNotFoundException {
            super();
            this.initializeClient();
        }

        public void execute() throws SQLException {

            Connection connection = null;
            try {
                connection = this.getConnection();
                Statement statement = connection.createStatement();
                ResultSet rs = statement
                        .executeQuery("SELECT * FROM sys.systables");
                while (rs.next()) {
                    System.out.println("" + rs.getString(1));
                }

                rs.close();
                connection.commit();
                connection.close();

            } finally {
                if (connection != null) {
                    connection.close();
                }
            }
        }

        protected void initializeClient() throws ClassNotFoundException {
            Class.forName(DRIVER);
        }

        protected Connection getConnection() throws SQLException {

            Connection connection = null;
            Properties props = new Properties();
            props.put("user", "me");
            props.put("password", "password");

            connection = DriverManager.getConnection(PROTOCOL
                    + "derbyDB;create=true", props);
            connection.setAutoCommit(false);

            return connection;
        }
    }

    public static class DerbyServer implements Runnable {
        private static final String DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";
        private static final String PROTOCOL = "jdbc:derby:";
        private Thread thread;
        private boolean initialized;

        public DerbyServer() {
            super();
        }

        public void start() {
            if (this.thread == null) {
                this.thread = new Thread(this);
                this.thread.start();
            }
        }

        public void stop() {
            if (this.thread != null) {
                this.thread = null;
            }
        }

        public void run() {
            try {
                this.initializeDBMS();
                while (this.thread != null) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
                }
                this.destroyDBMS();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        public boolean isInitialized() {
            return this.initialized;
        }

        protected void initializeDBMS() throws Exception {

            System.setProperty("derby.drda.startNetworkServer", "true");
            Class.forName(DRIVER).newInstance();

            NetworkServerControl server = new NetworkServerControl();
            server.ping();

            this.initialized = true;
        }

        protected void destroyDBMS() throws SQLException {

            this.initialized = false;

            Connection connection = null;
            try {
                connection = DriverManager.getConnection(PROTOCOL
                        + ";shutdown=true");
                connection.commit();

            } catch (SQLException e) {
                // Derby が正常終了すると SQLException が発行される。
                System.out.println("" + e.getLocalizedMessage() + " : "
                        + e.getErrorCode());
            } finally {
                if (connection != null) {
                    connection.close();
                }
            }
        }
    }
}

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

Sep 25, 2005

[Library] JavaSVN の概要

JavaSVN のクラス図

JavaSVN 0.9.3 の「イイカゲン」なクラス図を作ってみた。

[JavaSVN 0.9.3 のクラス図]

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

Sep 23, 2005

[Library] JavaSVN にチャレンジ

JavaSVN とは

Java から Subversion にアクセスできるライブラリ。 Subversion のクライアントを Pure Java で実装しているツワモノ。 お馴染み Eclipse 用 Subversion Plugin の Subclipse でも内部で利用されている。

JavaSVN
http://tmate.org/svn/
JavaSVN サンプルコード
http://tmate.org/svn/kb/examples/index.php
類似のツールに JSVN があるが、JSVN はネイティブの svn コマンドを呼び出すだけなので使いづらい。

JavaSVN の実行環境構築

  1. JavaSVN (ganymed.jar, javasvn.jar, javasvn-cli.jar, javasvn-javahl.jar) をクラスパスに追加する

サンプルコード

package jp.in_vitro.codelets.javasvn;

import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNNodeKind;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

public class Codelet {

    public Codelet() {
        super();
    }

    public static void main(final String[] args) throws SVNException {

        String url = "http://example.com/repos/";
        String username = "myname";
        String password = "mypassword";

        Codelet me = new Codelet();
        me.initializeJavaSVN();
        SVNRepository repository = me.prepareSVNRepository(url, username,
                password);
        me.printInfo(repository, "projects/");
        me.printInfo(repository, "projects/pom.xml");

        repository.closeSession();
    }

    protected void initializeJavaSVN() {
        DAVRepositoryFactory.setup();
        SVNRepositoryFactoryImpl.setup();
    }

    protected void printInfo(final SVNRepository repository, final String path)
            throws SVNException {

        SVNNodeKind nodeKind = repository.checkPath(path, -1);
        if (nodeKind == SVNNodeKind.NONE) {
            System.out.println("NONE");
        } else if (nodeKind == SVNNodeKind.UNKNOWN) {
            System.out.println("UNKNOWN");
        } else if (nodeKind == SVNNodeKind.DIR) {
            Map properties = new HashMap();
            List children = new ArrayList();
            repository.getDir(path, -1, properties, children);

            System.out.println("*** properties ***");
            for (Object key : properties.keySet()) {
                System.out.println("" + key + " - " + properties.get(key));
            }
            System.out.println("*** children ***");
            for (Object child : children) {
                System.out.println("" + child);
            }

        } else if (nodeKind == SVNNodeKind.FILE) {
            Map properties = new HashMap();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            repository.getFile(path, -1, properties, baos);

            System.out.println("*** properties ***");
            for (Object key : properties.keySet()) {
                System.out.println("" + key + " - " + properties.get(key));
            }
        }

    }

    protected SVNRepository prepareSVNRepository(final String url,
            final String username, final String password) throws SVNException {

        SVNRepository repository = SVNRepositoryFactory.create(SVNURL
                .parseURIEncoded(url));

        ISVNAuthenticationManager authenticationManager = SVNWCUtil
                .createDefaultAuthenticationManager(username, password);
        repository.setAuthenticationManager(authenticationManager);

        return repository;
    }
}

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

Sep 22, 2005

[Book] Robust Java

書籍情報


Robust Java

レビュー

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

Sep 20, 2005

[Derby] Derby メモ

Derby で調べた内容を少しだけメモ。 Derby 公式サイトにあるドキュメントを拾い集めただけ。

Derby environments

Derby には "embedded" モードと "server" モードで動作できる。 "embedded" モードはアプリケーション内部で起動されて、そのアプリケーション内でのみ使用可能なモード。"server" モードは単体でアプリケーションとして動作するモードで、複数のクライアントアプリケーションから使用可能。 コネクションの張り方やマルチスレッドなどで挙動が異なるらしい。

Environments in which Derby can run
http://db.apache.org/derby/docs/10.1/getstart/getstart-single.html#cgsquck70629
Connection Mode
http://db.apache.org/derby/docs/10.1/devguide/devguide-single.html#N16F6D

Derby Driver

Derby で使用できる JDBC ドライバは以下の 2 つ。

  • org.apache.derby.jdbc.EmbeddedDriver ・・・ "embedded" モード用ドライバ
  • org.apache.derby.jdbc.ClientDriver ・・・ "server" モード用ドライバ
Available drivers
http://db.apache.org/derby/docs/10.1/getstart/getstart-single.html#rgsquck35368

Database connection URL

URL の書式は以下の通り。

jdbc:derby://<server>[:<port>]/databaseName[;URLAttributes=<value> [;...]]
Database connection URL
http://db.apache.org/derby/docs/10.1/getstart/getstart-single.html#rgsquck30197

Derby プロパティ

Derby を実行する際に指定できるプロパティ一覧。

java -Dderby.system.home=c:\\derby ...
の様に JVM 起動時に指定するか、
Properties props = System.getProperties();
props.setProperty("derby.system.home", "c:\\derby");
の様にアプリケーション中から指定する。derby.properties という設定ファイルに記述することもできる。
Derby properties
http://db.apache.org/derby/docs/10.1/tuning/tuning-single#ctunproper22250

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

[Library] コンテンツ移動のお知らせ

http://www.in-vitro.jp/blog/index.cgi/Library/20050920_01.html はこちらに移動しました。
Posted in Library | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

Sep 19, 2005

[Library] コンテンツ移動のお知らせ

http://www.in-vitro.jp/blog/index.cgi/Library/20050919_01.html はこちらに移動しました。
Posted in Library | このエントリーをはてなブックマークに追加 | この記事をクリップ! livedoor クリップ |

[Derby] Derby にチャレンジ

Derby とは

Derby は 元 CloudScape と呼ばれた RDBMS。 IBM が Apache に寄贈したもの。 Pure Java で DBMS 自体のサイズが 2M と小さいのがステキ。

Derby
http://db.apache.org/derby/

Derby の実行環境構築

  1. Derby(derby.jar) をクラスパスに追加

サンプルコード

package jp.in_vitro.codelets.derby;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class Codelet {

    private static final String DRIVER = "org.apache.derby.jdbc.EmbeddedDriver";

    private static final String PROTOCOL = "jdbc:derby:";

    public Codelet() {
        super();
    }

    public static void main(final String[] args) throws InstantiationException,
            IllegalAccessException, ClassNotFoundException, SQLException {

        Codelet me = new Codelet();
        me.execute();
    }

    protected void execute() throws InstantiationException,
            IllegalAccessException, ClassNotFoundException, SQLException {

        // Derby を embedded モードで起動する。
        this.initializeDBMS();
        try {
            try {
                // テーブルの生成。
                this.createTable();
            } catch (SQLException e) {
                // 既に Table が生成済みの可能性があるので・・・
            }
            // insert
            this.insertRecord();
            // update
            this.updateRecord();
            // select
            this.selectRecord();
            // delete
            this.deleteRecord();
            // テーブルの削除。
            this.dropTable();
        } finally {
            // Derby のシャットダウン
            this.destroyDBMS();
        }
    }

    protected void initializeDBMS() throws InstantiationException,
            IllegalAccessException, ClassNotFoundException, SQLException {
        Class.forName(DRIVER).newInstance();

        Connection connection = null;
        try {
            connection = DriverManager.getConnection(PROTOCOL
                    + "derbyDB;create=true");
            connection.commit();

        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }

    protected void destroyDBMS() throws SQLException {
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(PROTOCOL
                    + ";shutdown=true");
            connection.commit();

        } catch (SQLException e) {
            // Derby が正常終了すると SQLException が発行される。
            System.out.println("" + e.getLocalizedMessage() + " : "
                    + e.getErrorCode());
        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }

    protected Connection getConnection() throws SQLException {

        Connection connection = null;
        Properties props = new Properties();
        props.put("user", "me");
        props.put("password", "password");

        connection = DriverManager.getConnection(PROTOCOL + "derbyDB", props);
        connection.setAutoCommit(false);

        return connection;
    }

    protected void createTable() throws SQLException {

        Connection connection = this.getConnection();
        try {
            Statement statement = connection.createStatement();
            statement
                    .executeUpdate("CREATE TABLE sample(field01 INT, field02 VARCHAR(10))");

            connection.commit();
            connection.close();

        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }

    protected void insertRecord() throws SQLException {

        Connection connection = this.getConnection();
        try {
            Statement statement = connection.createStatement();
            statement.executeUpdate("INSERT INTO sample VALUES (999,'dummy data')");
            statement.executeUpdate("INSERT INTO sample VALUES (888,'hogehoge')");

            connection.commit();
            connection.close();

        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }

    protected void updateRecord() throws SQLException {

        Connection connection = this.getConnection();
        try {
            Statement statement = connection.createStatement();
            statement
                    .executeUpdate("UPDATE sample SET field01=100 WHERE field02='dummy data'");

            connection.commit();
            connection.close();

        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }

    protected void deleteRecord() throws SQLException {

        Connection connection = this.getConnection();
        try {
            Statement statement = connection.createStatement();
            statement.executeUpdate("DELETE FROM sample");

            connection.commit();
            connection.close();

        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }

    protected void selectRecord() throws SQLException {

        Connection connection = this.getConnection();
        try {
            Statement statement = connection.createStatement();
            ResultSet rs = statement
                    .executeQuery("SELECT * FROM sample ORDER BY field01");

            while (rs.next()) {
                System.out.println("field01=" + rs.getString(1) + ", field02="
                        + rs.getString(2));
            }

            rs.close();
            connection.commit();
            connection.close();

        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }

    protected void dropTable() throws SQLException {

        Connection connection = this.getConnection();
        try {
            Statement statement = connection.createStatement();
            statement.executeUpdate("DROP TABLE sample");

            connection.commit();
            connection.close();

        } finally {
            if (connection != null) {
                connection.close();
            }
        }
    }

}

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

Sep 17, 2005

[Library] Pure Java DBMS

Pure Java の RDBMS を探してみた。 探してみると結構な数がある。 hsqldb は以前試してみたことがあるが、イマイチ使い勝手が良くなかった。 というわけで、他の RDBMS を試してみよう。

hsqldb - Original License
http://hsqldb.org/
Derby - Apache License, Version 2.0
http://db.apache.org/derby/
Mckoi - GPL
http://mckoi.com/database/
QED - Original License
http://www.quadcap.com/home.html
tinySQL - LGPL
http://sourceforge.net/projects/tinysql/
One$DB - LGPL
http://daffodildb.com/one-dollar-db.html

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

Sep 15, 2005

[Library] Jsch にチャレンジ

JCIFS とは

SSH2 用の Java ライブラリ。 SFTP、SCPなどにも対応している優れもの。

Jsch
http://www.jcraft.com/jsch/index.html
Jsch のサンプルコード
http://www.jcraft.com/jsch/examples/

JCIFS の実行環境構築

  1. Jsch(jsch-0.1.23.jar) をクラスパスに追加。

サンプルコード

package jp.in_vitro.codelets.jsch;

import java.lang.reflect.Field;
import java.util.Vector;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.HostKey;
import com.jcraft.jsch.HostKeyRepository;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;

public class Codelet {

    public Codelet() {
        super();
    }

    public static void main(final String[] args) throws Exception {

        Codelet me = new Codelet();
        me.connectSsh("192.168.1.1", "myname", "mypassword");
    }

    public void connectSsh(final String hostname, final String username,
            final String password) throws SecurityException,
            NoSuchFieldException, IllegalArgumentException,
            IllegalAccessException, JSchException {

        JSch jsch = new JSch();

        Session session = null;
        while (true) {
            try {
                session = jsch.getSession(username, hostname, 22);
                session.setPassword(password);
                session.connect(3000);
                break;
            } catch (JSchException e) {
                if (e.getLocalizedMessage().indexOf("UnknownHostKey") >= 0) {
                    // 無理矢理 known_host に登録。ホントはマズい。
                    HostKey hostkey = session.getHostKey();
                    HostKeyRepository hostkeyRepo = jsch.getHostKeyRepository();
                    Field field = hostkeyRepo.getClass().getDeclaredField(
                            "pool");
                    field.setAccessible(true);
                    System.out.println("" + field.getType());
                    Vector hostkeyRepoPool = (Vector) field.get(hostkeyRepo);
                    hostkeyRepoPool.add(hostkey);
                    session.disconnect();
                    continue;
                }
                break;
            }
        }

        Channel channel = session.openChannel("shell");
        channel.setInputStream(System.in);
        channel.setOutputStream(System.out);
        channel.connect();
    }

}

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

Sep 14, 2005

[Book] Programming Java Virtual Machine

書籍情報


Programming Java Virtual Machine

レビュー

Java の bytecode が何故動作するのか、という Java の世界における根本的な解説を提供してくれる一冊。 最近は Ease of Development(EoD) の旗印の下、コーディングを簡単に、簡単にという動きが強い。 ただ、現実には依然として bytecode レベルの知識がないと理解できないことも多い。 VM の知識というと毛嫌いする人も居るが、Java で真面目に生計を立てたいのなら是非一読を薦めたい。

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

Sep 10, 2005

[JSR] JSR 181 Web Services Metadata for the Java Platform ダイジェスト

Web Services Metadata for the Java Platform の仕様をざっと眺めたときのメモ。

JSR 181 Web Services Metadata for the Java Platform

オリジナルの入手はこちら → JSR 181

Concepts

Server Programming Model

Web Services Metadata

Annotation: javax.jws.WebService
Annotation: javax.jws.WebMethod
Annotation: javax.jws.Oneway
Annotation: javax.jws.WebParam
Annotation: javax.jws.WebResult
Annotation: javax.jws.HandlerChain
Annotation: javax.jws.soap.SOAPBinding
Annotation: javax.jws.soap.SOAPMessageHandlers

Java Mapping To XML/WSDL

SOAP Binding

Mapping JSR-181 to the J2EE 1.4 Runtime Environment

Using JSR-181 annotations to affect the shape of the WSDL

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

Sep 02, 2005

[Book] UML Distilled

書籍情報


UML Distilled

日本語翻訳版


UML モデリングのエッセンス

レビュー

UML の入門書としては非常に名の通った書籍なのでご存知の方も多いだろう。 この本の良いところは、UML の解説は入門に徹しつつもきちんと現実的な解説を織り込んでいるところ。 下手に何冊も UML の書籍を読み漁るよりも、この一冊を丁寧に読む方が良いと思う。

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