浏览 3368 次
|
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
|---|---|
| 作者 | 正文 |
|
时间:2007-05-24 关键字: Hsqldb Ant Eclipse
可重用的 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("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)
{
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/" 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"/>
</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 file="../Common/build.xml" />
......
也可以建立 build.properties 资源文件来配置一些信息等等。。。 附上完整的 build.xml 与 ShutdownTask.jar 以及 Eclipse项目文件,import 到 Eclipse 中,把 build.xml 拖到Ant视图里,直接就可以用了。 BTW:刚才从Word里拷贝过来提交,JavaEye的有BUG,现在重新修改了一下!!! 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
时间:2007-05-28
不错,呵呵,试了一下效果。
但是源码build.xml中凡是url的地方都没有指明数据库名,不知道是不是漏掉了,像是这样类似的定义: <shutdownTask driver="org.hsqldb.jdbcDriver" url="jdbc:hsqldb:hsql://localhost/" userid="sa" password="" sqlCommand="SHUTDOWN IMMEDIATELY" msg="MyShutdownTask"/> 我自己加上之后跑就没有问题了。于是可能需要在dbstart任务里加上数据库别名:
<!-- Start the Hsqldb database server -->
<target name="dbstart" description="Start the Hsqldb database server">
<java classname="org.hsqldb.Server" fork="yes" classpathref="hsqldb.classpath" failonerror="true">
<arg value="-database.0"/>
<arg value="file:${database.dir}/${db.name}"/>
<!-- 这里加上数据库别名-->
<arg value="-dbname.0"/>
<arg value="${db.name}"/>
</java>
</target>
|
|
| 返回顶楼 | |
|
时间:2007-05-28
数据库别名是可加可不加的参数,因此我没有加上去:)
|
|
| 返回顶楼 | |





