可重用的 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視圖裡,直接就可以用了。
講完了。
解散。。。