天天看點

可重用的 Hsqldb 啟動、停止之 Ant 任務腳手架

可重用的 hsqldb 啟動、停止之 ant 任務腳手架

立正。。。

稍息

講一下

坐下。。。

在eclipse裡用ant來啟動hsqldb

      <!-- start the hsqldb database server -->

      <targetname="dbstart"description="start the hsqldb database server">

            <javaclassname="org.hsqldb.server"fork="yes"classpathref="hsqldb.classpath"failonerror="true">

                  <argvalue="-database.0"/>

                  <argvalue="file:${database.dir}/db"/>

            </java>

      </target>

此時如果要停止 hsqldb ,即點選紅色按鈕來 terminate 掉它,實作上,hsqldb的java線程還是在背景運作的,它并沒有真正結束。

判斷的方法有四種:

1、再次運作 ant startdb 任務,會發現 db.lck 還被使用,而 <delete dir="${database.dir}"/> 删除不了,被前一個執行個體 lock 住了。

buildfile: xxx/build.xml

startdb:

   [delete] deleting directory xxx/database

build failed

xxx/build.xml:88: unable to delete file xxx/database/db.lck

2、利用jdk 5.0以上的版本中的 jps 來檢視,即:

%java_home%/bin/jps -lvm

你可以看到其中有如下的資訊顯示

<pid> org.hsqldb.server -database.0 file:database/db

即表明它還是在運作當中。

3、netstat -a | find "9001"

 tcp    xxx:9001   xxx:0 listening

發現 hsqldb 預設的服務端口 9001 還在監聽中。

4、再次運作你的資料庫連接配接程式,程式運作正常,還是可以連接配接上去,并可以完全正常進行你的資料操作。

由上面的方法可見它還是在正常運作中,eclipse裡的紅色按鈕并沒有真正 terminate 掉它。

那如何真正停止掉它呢?同樣也有幾種方法。

1、利用 ant 本身提供的 sql 任務,如下發送 shutdown [compact|immediately] 指令過去就可以了,如下:

      <!-- shutdown the hsqldb database server via ant sql task -->

      <targetname="dbshutdown"description="shutdown the hsqldb database server via ant sql task">

            <echomessage="ignore the message:'java.sql.sqlexception: connection is broken: java.io.eofexception', don't care about it."/>

            <sqldriver="org.hsqldb.jdbcdriver"url="jdbc:hsqldb:hsql://localhost/"userid="sa"password=""classpathref="hsqldb.classpath"onerror="stop"print="true"><![cdata[

            shutdown;

            ]]></sql>

但是雖然這個可以讓 hsqldb server 停止掉了,但是會報錯誤,build出現錯誤我是不能接受的,不知道你是否接受?

shutdowndb:

     [echo] ignore the message:'java.sql.sqlexception: connection is broken: java.io.eofexception', don't care about it.

      [sql] executing commands

      [sql] 0 rows affected

xxx/build.xml:124: java.sql.sqlexception: connection is broken: java.io.eofexception

打開 verbose 選項看一看更加詳細的資訊:

      [sql] connecting to jdbc:hsqldb:hsql://localhost/

      [sql] loading org.hsqldb.jdbcdriver using antclassloader with classpath xxx/lib/hsqldb.jar

java.sql.sqlexception: socket creation error

        at org.apache.tools.ant.taskdefs.jdbctask.getconnection(jdbctask.java:314)

        at org.apache.tools.ant.taskdefs.sqlexec.execute(sqlexec.java:346)

        at org.apache.tools.ant.unknownelement.execute(unknownelement.java:275)

        at org.apache.tools.ant.task.perform(task.java:364)

        at org.apache.tools.ant.target.execute(target.java:341)

        at org.apache.tools.ant.target.performtasks(target.java:369)

        at org.apache.tools.ant.project.executesortedtargets(project.java:1216)

        at org.apache.tools.ant.project.executetarget(project.java:1185)

        at org.apache.tools.ant.helper.defaultexecutor.executetargets(defaultexecutor.java:40)

        at org.apache.tools.ant.project.executetargets(project.java:1068)

        at org.apache.tools.ant.main.runbuild(main.java:668)

        at org.apache.tools.ant.main.startant(main.java:187)

        at org.apache.tools.ant.launch.launcher.run(launcher.java:246)

        at org.apache.tools.ant.launch.launcher.main(launcher.java:67)

caused by: java.sql.sqlexception: socket creation error

        at org.hsqldb.jdbc.util.sqlexception(unknown source)

        at org.hsqldb.jdbc.jdbcconnection.<init>(unknown source)

        at org.hsqldb.jdbcdriver.getconnection(unknown source)

        at org.hsqldb.jdbcdriver.connect(unknown source)

        at org.apache.tools.ant.taskdefs.jdbctask.getconnection(jdbctask.java:304)

        ... 13 more

--- nested exception ---

        at org.hsqldb.jdbcdriver.getconnection(unknown source)

        at org.apache.tools.ant.project.executesortedtargets(project.java:1216)

也就是說在執行 shutdown 指令後,

org.apache.tools.ant.taskdefs.jdbctask.getconnection(jdbctask.java:314) 還去 getconnection,那肯定就出錯了。

2、自己寫個簡單的 ant 腳本來關閉它

shutdowntask.java

import java.sql.connection;

import java.sql.drivermanager;

import java.sql.sqlexception;

import java.sql.statement;

import org.apache.tools.ant.buildexception;

import org.apache.tools.ant.task;

/**

 *shutdowntask:anttaskforshutdownthehsqldbserver.

 *

 *@authoryulimin

 */

publicclass shutdowntask extends task

{

      // defaut value

      private string msg = "shutdowntask";

      private string driver = "org.hsqldb.jdbcdriver";

      private string url = "jdbc:hsqldb:hsql://localhost/";

      private string userid = "sa";

      private string password = "";

      private string sqlcommand = "shutdown";

      public shutdowntask()

      {

            super();

      }

      /**

       *fortest

       *

       *@paramargv

       *@throwsexception

       */

      publicstaticvoid main(final string[] argv)

            final shutdowntask shutdowntask = new shutdowntask();

            shutdowntask.shutdown();

       *themethodexecutingthetask

      publicvoid execute() throws buildexception

            system.out.println(msg + " begin......");

            system.out.println("driver=" + getdriver());

            system.out.println("url=" + geturl());

            system.out.println("userid=" + getuserid());

            system.out.println("password=" + getpassword());

            system.out.println("sqlcommand=" + getsqlcommand());

            shutdown();

            system.out.println(msg + " end......");

            system.out.println();

       *shutdownthedatabase

      publicvoid shutdown()

            connection connection = null;

            statement statement = null;

            try

            {

                  class.forname(getdriver());

                  connection = drivermanager.getconnection(geturl(),getuserid(),getpassword());

                  statement = connection.createstatement();

                  statement.execute(getsqlcommand());

                  statement.close();

                  connection.close();

            }

            catch(exception e)

                  e.printstacktrace();

                  thrownew runtimeexception(e);

            finally

                  if(statement != null)

                  {

                        try

                        {

                              statement.close();

                        }

                        catch(sqlexception e)

                              thrownew runtimeexception(e);

                  }

                  if(connection != null)

                              connection.close();

      // more accessor method : setter & getter

      publicvoid setmsg(final string msg)

            this.msg = msg;

      publicvoid setdriver(final string driver)

            this.driver = driver;

      publicvoid setpassword(final string password)

            this.password = password;

      publicvoid seturl(final string url)

            this.url = url;

      publicvoid setuserid(final string userid)

            this.userid = userid;

      publicvoid setsqlcommand(final string sqlcommand)

            this.sqlcommand = sqlcommand;

      public string getdriver()

            returndriver;

      public string getpassword()

            returnpassword;

      public string geturl()

            returnurl;

      public string getuserid()

            returnuserid;

      public string getsqlcommand()

            returnsqlcommand;

      public string getmsg()

            returnmsg;

}

編譯 javac -classpath %ant_home%/lib/ant.jar shutdowntask.java

打包 jar cvf shutdowntask.jar *.*

把 shutdowntask.jar 直接放到項目的lib目錄下,下面的示例 classpath 我直接引入到 hsqldb.classpath中,可以根據需要放到項目的不同地方再進行調整引入使用等等。。。:)

build.xml裡的調用示例,愛怎麼用就怎麼用,提供好幾個示例。

      <!-- classpath declaration -->

      <pathid="hsqldb.classpath">

            <filesetdir="${lib.dir}">

                  <includename="**/hsqldb.jar"/>

                  <includename="**/shutdowntask.jar"/>

            </fileset>

      </path>

      <!-- shutdown the hsqldb database server via shutdowntask -->

      <targetname="dbshutdowntask"description="shutdown the hsqldb database server via shutdowntask">

            <!-- define shutdowntask -->

            <taskdefname="shutdowntask"classname="shutdowntask"classpathref="hsqldb.classpath"/>

            <!-- call shutdowntask -->

            <!-- default shutdowntask, only like this -->

            <!-- <shutdowntask/> -->

            <!-- sample myshutdowntask -->

            <!-- <shutdowntask driver="org.hsqldb.jdbcdriver" url="jdbc:hsqldb:hsql://localhost/" userid="sa" password="" sqlcommand="shutdown" msg="myshutdowntask"/> -->

            <!-- sample myshutdowntask shutdown compact -->

            <!-- <shutdowntask driver="org.hsqldb.jdbcdriver" url="jdbc:hsqldb:hsql://localhost/" userid="sa" password="" sqlcommand="shutdown compact" msg="myshutdowntask"/> -->

            <!-- sample myshutdowntask shutdown immediately -->

            <shutdowntaskdriver="org.hsqldb.jdbcdriver"url="jdbc:hsqldb:hsql://localhost/"userid="sa"password=""sqlcommand="shutdown immediately"msg="myshutdowntask"/>

3、就在直接在指令行下運作 ant startdb ,然後 ctrl + c 直接幹掉它就可以。

            如啟動時的提示:from command line, use [ctrl]+[c] to abort abruptly

補充

os:windows 2k pro sp4 english

ant -version

apache ant version 1.6.5 compiled on june 2 2005

jdk 1.4.2 1.5.0 1.6.0 1.7.0都可以。。。

最後,如何使用它呢?

在其它項目中隻要相應地 import 這個 build.xml 這個檔案即可達到重用,如:新項目與這個項目并行,即

<?xml version="1.0" encoding="utf-8"?>

<projectname="jpa_otherproject"default="compile"basedir=".">

      <import file="../common/build.xml" />

    ......

也可以建立 build.properties 資源檔案來配置一些資訊等等。。。

附上完整的 build.xml 與 shutdowntask.jar 以及 eclipse項目檔案,import 到 eclipse 中,把 build.xml 拖到ant視圖裡,直接就可以用了。

講完了。

解散。。。