可重用的 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>
</target>
但是雖然這個可以讓 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
BUILD FAILED
xxx/build.xml:124: java.sql.SQLException: Connection is broken: java.io.EOFException
打開 verbose 選項看一看更加詳細的信息:
shutdowndb:
[echo] Ignore the message:'java.sql.SQLException: Connection is broken: java.io.EOFException', Don't care about it.
[sql] connecting to jdbc:hsqldb:hsql://localhost/
[sql] Loading org.hsqldb.jdbcDriver using AntClassLoader with classpath xxx/lib/hsqldb.jar
BUILD FAILED
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 ---
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)
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)
也就是說在執行 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("Userfont-size:10pt;color:#000000;"> + 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)
{
try
{
connection.close();
}
catch(SQLException e)
{
thrownew RuntimeException(e);
}
}
}
}
// 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/" user password="" sqlCommand="SHUTDOWN" msg="MyShutdownTask"/> -->
<!-- Sample MyShutdownTask SHUTDOWN COMPACT -->
<!-- <shutdownTask driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:hsql://localhost/" user 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"/>
</target>
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 />
......
也可以建立 build.properties 資源文件來配置一些信息等等。。。
附上完整的 build.xml 與 ShutdownTask.jar 以及 Eclipse項目文件,import 到 Eclipse 中,把 build.xml 拖到Ant視圖裏,直接就可以用了。
講完了。
解散。。。
最後更新:2017-04-02 00:06:21