閱讀628 返回首頁    go 阿裏雲 go 技術社區[雲棲]


可重用的 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視圖裏,直接就可以用了。
下載地址:Hsqldb_Ant_Eclipse.rar
講完了。
解散。。。
 

最後更新:2017-04-02 00:06:21

  上一篇:go 忽悠 再忽悠,關於《Sanjiva Weerawarana訪談:揭秘REST/WS-*》事相
  下一篇:go [原創]匯編初學者問題合集