无法以编程方式正确关闭Derby

时间:2012-06-28 14:43:03

标签: java maven maven-plugin derby

我编写了一个OSS插件,用于在Maven构建过程中启动/停止Derby。 该插件在普通的旧单模块中运行良好。但是,如果我有一个包含多个模块的聚合器,并且其中一个以上的模块都有与数据库相关的测试,那么我似乎遇到了一些奇怪的问题。

我正在调用插件的startstop目标(分别在process-resourcestest阶段),如下所示:

        <plugin>
            <groupId>org.carlspring.maven</groupId>
            <artifactId>derby-maven-plugin</artifactId>
            <version>1.4</version>

            <configuration>
                <failIfAlreadyRunning>false</failIfAlreadyRunning>
            </configuration>

            <executions>
                <execution>
                    <id>start-derby</id>
                    <phase>process-resources</phase>
                    <goals>
                        <goal>start</goal>
                    </goals>
                </execution>
                <execution>
                    <id>stop-derby</id>
                    <phase>test</phase>
                    <goals>
                        <goal>stop</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>

问题在于,在第二次尝试启动Derby(内存中)服务器时,Derby似乎仍在运行,或者已从第一个模块加载了数据库内容。我可以告诉这一点,因为聚合器中的第一个模块创建并填充表中的一些数据。我的期望是,一旦我关闭了Derby并从另一个模块重新开始它,它将是一个没有任何现有内容的新数据库。

以下是我在插件中处理关闭Derby的代码:

try
{
    try
    {
        server.ping();
    }
    catch (Exception e)
    {
        if (failIfNotRunning)
        {
            throw new MojoExecutionException("Failed to stop the Derby server, no server running!", e);
        }

        getLog().error("Derby server was already stopped.");
        return;
    }

    server.shutdown();

    while (true)
    {
        Thread.sleep(1000);
        try
        {
            server.ping();
        }
        catch (Exception e)
        {
            getLog().info("Derby has stopped!");
            return;
        }
    }
}
catch (Exception e)
{
    throw new MojoExecutionException(e.getMessage(), e);
}

可以在GitHub here中检出或查看这个相当简单的插件的完整来源。

1 个答案:

答案 0 :(得分:0)

我最终做了以下事情:

try
{
    try
    {
        server.ping();
    }
    catch (Exception e)
    {
        if (failIfNotRunning)
        {
            throw new MojoExecutionException("Failed to stop the Derby server, no server running!", e);
        }

        getLog().error("Derby server was already stopped.");
        return;
    }

    try
    {
        DriverManager.getConnection(getConnectionURL());
        DriverManager.getConnection("jdbc:derby:;shutdown=true");
    }
    catch (SQLException e)
    {
        // Apparently this prints out a bunch of stuff we're not currently interested in,
        // we just want it to shutdown properly.
        // Perhaps further handling might be required at a future point in time.
    }

    server.shutdown();

    while (true)
    {
        Thread.sleep(1000);
        try
        {
            server.ping();
        }
        catch (Exception e)
        {
            getLog().info("Derby has stopped!");
            break;
        }
    }

    System.getProperties().remove("derby.system.home");
}
catch (Exception e)
{
    throw new MojoExecutionException(e.getMessage(), e);
}

这不是我预期的必须完成的方式。