Pax考试同步问题

时间:2014-05-06 14:37:01

标签: java apache-karaf pax-exam

我正在使用Pax Exam对我的OSGi应用程序执行集成测试。该应用程序由许多不同的包组成,我使用ConfigurationFactory将其部署到测试容器中,如下所示:

public class TestConfigurationFactory implements ConfigurationFactory {

@Override
public Option[] createConfiguration() {
    return options(
            karafDistributionConfiguration()
                    .frameworkUrl(
                            maven().groupId("org.apache.karaf")
                                    .artifactId("apache-karaf")
                                    .version("3.0.1").type("tar.gz"))
                    .unpackDirectory(new File("target/exam"))
                    .useDeployFolder(false),
            keepRuntimeFolder(),
            // Karaf (own) features.
            KarafDistributionOption.features(
                    maven().groupId("org.apache.karaf.features")
                            .artifactId("standard").classifier("features")
                            .version("3.0.1").type("xml"), "scr"),
            // CXF features.
            KarafDistributionOption.features(maven()
                    .groupId("org.apache.cxf.karaf")
                    .artifactId("apache-cxf").version("2.7.9")
                    .classifier("features").type("xml")),
            // Application features.
            KarafDistributionOption.features(
                    maven().groupId("com.me.project")
                            .artifactId("my-karaf-features")
                            .version("1.0.0-SNAPSHOT")
                            .classifier("features").type("xml"), "my-feature"));
}
}

这很好用,然后我可以编写测试方法来测试我的应用程序,但我有以下问题,我理解的本质上是同步问题。我作为my-feature的一部分部署的一个bundle有一个EventHandler,它监听正在启动的bundle并将有关每个已启动bundle的一些信息写入DB。我假设这是与我的测试方法的执行异步发生的事情。在我的测试方法执行后,因此我可以在我的测试输出中看到发生在我的EventHandler中的查询的以下异常:

<openjpa-2.3.0-r422266:1540826 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: Failed to execute query "XXX". Check the query syntax for correctness. See nested exception for details.
        at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:872)[90:org.apache.openjpa:2.3.0]
        at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:794)[90:org.apache.openjpa:2.3.0]
        at org.apache.openjpa.kernel.DelegatingQuery.execute(DelegatingQuery.java:542)[90:org.apache.openjpa:2.3.0]
        at org.apache.openjpa.persistence.QueryImpl.execute(QueryImpl.java:275)[90:org.apache.openjpa:2.3.0]
        at org.apache.openjpa.persistence.QueryImpl.getResultList(QueryImpl.java:291)[90:org.apache.openjpa:2.3.0]
        ...
Caused by: org.osgi.service.blueprint.container.ServiceUnavailableException: The Blueprint container is being or has been destroyed: (objectClass=java
x.transaction.TransactionManager)
        at org.apache.aries.blueprint.container.ReferenceRecipe.getService(ReferenceRecipe.java:240)[19:org.apache.aries.blueprint.core:1.4.0]
        at org.apache.aries.blueprint.container.ReferenceRecipe.access$000(ReferenceRecipe.java:55)[19:org.apache.aries.blueprint.core:1.4.0]
        at org.apache.aries.blueprint.container.ReferenceRecipe$ServiceDispatcher.call(ReferenceRecipe.java:298)[19:org.apache.aries.blueprint.core:1.
4.0]
        at Proxy8da13f59_1943_4e85_b276_b44a20a26ceb.getTransaction(Unknown Source)[:]
        at org.apache.commons.dbcp.managed.TransactionRegistry.getActiveTransactionContext(TransactionRegistry.java:91)[76:org.apache.servicemix.bundl
es.commons-dbcp:1.4.0.3]
        at org.apache.commons.dbcp.managed.ManagedConnection.updateTransactionStatus(ManagedConnection.java:67)[76:org.apache.servicemix.bundles.commo
ns-dbcp:1.4.0.3]
        at org.apache.commons.dbcp.managed.ManagedConnection.checkOpen(ManagedConnection.java:60)[76:org.apache.servicemix.bundles.commons-dbcp:1.4.0.
3]
        at org.apache.commons.dbcp.DelegatingConnection.prepareStatement(DelegatingConnection.java:293)[76:org.apache.servicemix.bundles.commons-dbcp:
1.4.0.3]
        at org.apache.openjpa.lib.jdbc.DelegatingConnection.prepareStatement(DelegatingConnection.java:135)[90:org.apache.openjpa:2.3.0]
        at org.apache.openjpa.lib.jdbc.LoggingConnectionDecorator$LoggingConnection.prepareStatement(LoggingConnectionDecorator.java:248)[90:org.apach
e.openjpa:2.3.0]
        at org.apache.openjpa.lib.jdbc.DelegatingConnection.prepareStatement(DelegatingConnection.java:133)[90:org.apache.openjpa:2.3.0]
        at org.apache.openjpa.lib.jdbc.ConfiguringConnectionDecorator$ConfiguringConnection.prepareStatement(ConfiguringConnectionDecorator.java:140)[
90:org.apache.openjpa:2.3.0]
        at org.apache.openjpa.lib.jdbc.DelegatingConnection.prepareStatement(DelegatingConnection.java:133)[90:org.apache.openjpa:2.3.0]
        at org.apache.openjpa.jdbc.kernel.JDBCStoreManager$RefCountConnection.prepareStatement(JDBCStoreManager.java:1643)[90:org.apache.openjpa:2.3.0
]
        at org.apache.openjpa.lib.jdbc.DelegatingConnection.prepareStatement(DelegatingConnection.java:122)[90:org.apache.openjpa:2.3.0]
        at org.apache.openjpa.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:508)[90:org.apache.openjpa:2.3.0]
        at org.apache.openjpa.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:488)[90:org.apache.openjpa:2.3.0]
        at org.apache.openjpa.jdbc.sql.SQLBuffer.prepareStatement(SQLBuffer.java:477)[90:org.apache.openjpa:2.3.0]
        at org.apache.openjpa.jdbc.kernel.PreparedSQLStoreQuery$PreparedSQLExecutor.executeQuery(PreparedSQLStoreQuery.java:110)[90:org.apache.openjpa
:2.3.0]
        at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:1005)[90:org.apache.openjpa:2.3.0]
        at org.apache.openjpa.kernel.QueryImpl.execute(QueryImpl.java:863)[90:org.apache.openjpa:2.3.0]
        ... 15 more

我的理解是,这个异常是由于我的测试方法被执行并且Pax Exam开始向下移动容器的事实我的EventHandler仍在处理bundle,当TransactionManager是时,愉快地从DB读取和写入在它的脚下扫过。所以我的问题是,有没有办法迫使Pax Exam等待我的EventHandler在关闭Karaf之前完成处理?

1 个答案:

答案 0 :(得分:0)

在测试方法返回之前,您似乎需要建立一个信号量。遇到终止条件后,EventHandler会释放信号量。

除此之外,如果您使用的是karaf 2.x,那么可能是blueprint synchronization issue.