当我在WildFly上正常定义Derby DataSource时,db.lck文件保持未删除状态,表示每次关闭WildFly时数据库都没有正确关闭。因为嵌入式Derby需要一个特殊的关闭过程,该过程使用以“; shutdown = true”字符串结尾的JDBC URL获取新连接。
所以,我需要像shutdown-hook那样执行shutdown程序。我发现旧的JBoss有办法实现它:
https://developer.jboss.org/wiki/SetUpADerbyDatasource http://grepcode.com/file/repository.jboss.org/nexus/content/repositories/releases/org.jboss.jbossas/jboss-as-varia/6.0.0.Final/org/jboss/jdbc/DerbyDatabase.java
但我不知道如何在最近的WildFly上应用它,因为它看起来像“mbean”和“依赖”元素不再允许其数据源定义,我在最近的WildFly上找不到它的等价物。 / p>
我认为数据源定义的“connection-listener-class”变量是相当可观的,它可能是实现它的一种方法。我还没有尝试过,但它看起来有点复杂,我不确定它是否按预期工作。
那么,有没有办法定义一个shutdown-hook,用最近的WildFly执行Derby的shutdown程序?
修改
我发布了一条安装Apache Derby到WildFly的说明,其中包括我的解决方案。 http://www.nailedtothex.org/roller/kyle/entry/installing-apache-derby-to-wildfly
答案 0 :(得分:2)
我找到了一个更好的MBean解决方案。它只是在每次WildFly关闭时执行关机程序。
只需克隆this repository并构建一个jar,将其放到$WILDFLY_HOME/standalone/deployments
。项目中有各种文件,所以在这里粘贴所有文件很烦人。
对org.jboss.ironjacamar.jdbcadapters,connection-listener-class和connection-listener-property的依赖是不必要的,所以现在$WILDFLY_HOME/modules/org/apache/derby/main/module.xml
可以简化如下:
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="org.apache.derby">
<resources>
<resource-root path="derby.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
</dependencies>
</module>
答案 1 :(得分:0)
connection-listener-class按照我的预期工作。我注册了一个监听器类,然后在每次关闭WildFly时,Derby都会正确启动关闭。
但是我应该记住一件事 - test-connection-in-pool
不会触发连接监听器类。如果我只是启动WildFly,然后执行test-connection-in-pool
到Derby的数据源,然后关闭WildFly,那么将永远不会调用侦听器并且db.lck将保持未删除状态。所以,它可能不是一个理想的解决方案。像更直接的shutdown-hook之类的东西会更好。
我所做的是:
$WILDFLY_HOME/modules/org/apache/derby/main
/subsystem=datasources/jdbc-driver=derby:add(driver-name=derby, driver-module-name=org.apache.derby, driver-class-name=org.apache.derby.jdbc.EmbeddedDriver)
data-source add --name=DerbyDS --driver-name=derby --connection-url=jdbc:derby:/Users/kyle/tmp/derbytest --jndi-name=java:jboss/jdbc/DerbyDS --user-name=sa --password=sa
/subsystem=datasources/data-source=DerbyDS:write-attribute(name=connection-listener-class, value=org.nailedtothex.derby.DerbyShutdownConnectionListener)
/subsystem=datasources/data-source=DerbyDS:write-attribute(name=connection-listener-property,value={"url"=>"jdbc:derby:/Users/kyle/tmp/derbytest"}
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="org.apache.derby">
<resources>
<resource-root path="derby.jar"/>
<resource-root path="derby-shutdown-hook-1.0-SNAPSHOT.jar"/>
</resources>
<dependencies>
<module name="javax.api"/>
<module name="javax.transaction.api"/>
<module name="org.jboss.ironjacamar.jdbcadapters"/>
</dependencies>
</module>
Please refer GitHub for whole project contains pom.xml
import org.jboss.jca.adapters.jdbc.spi.listener.ConnectionListener;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
public class DerbyShutdownConnectionListener implements ConnectionListener {
private static final Logger log = Logger.getLogger(DerbyShutdownConnectionListener.class.getName());
private static final String DEFAULT_URL = "jdbc:derby:";
private static final String SHUTDOWN_SUFFIX = ";shutdown=true";
private String url;
private String urlForShutdown;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
@Override
synchronized public void initialize(final ClassLoader classLoader) throws SQLException {
urlForShutdown = createUrlForShutdown();
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
log.log(Level.INFO, "Shutdown derby. URL to use: {0}", urlForShutdown);
shutdown(urlForShutdown);
}
});
log.log(Level.INFO, "Derby shutdown hook added. URL to use: {0}", urlForShutdown);
}
private String createUrlForShutdown() {
return (url == null ? DEFAULT_URL : url) + SHUTDOWN_SUFFIX;
}
private void shutdown(String url) {
Connection cn = null;
try {
cn = DriverManager.getConnection(url);
} catch (SQLException e) {
if ("08006".equals(e.getSQLState()) || "XJ015".equals(e.getSQLState())) {
log.log(Level.INFO, "Derby shutdown succeeded. SQLState={0}", e.getSQLState());
return;
}
log.log(Level.SEVERE, "Derby shutdown failed", e);
} finally {
if (cn != null) {
try {
cn.close();
} catch (Exception e) {
}
}
}
}
@Override
public void activated(Connection connection) throws SQLException {
}
@Override
public void passivated(Connection connection) throws SQLException {
}
}