我正在使用 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 的一部分部署的其中一个包有一个 EventHandler,它侦听正在启动的包并将有关每个已启动包的一些信息写入数据库。我假设这是与我的测试方法的执行异步发生的事情。因此,在我的测试方法执行后,我可以在我的测试输出中看到以下异常,该异常发生在我的 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 仍在处理包,愉快地从 DB 读取和写入,当 TransactionManager 被扫过它时脚。所以我的问题是,有没有办法强制 Pax Exam 在关闭 Karaf 之前等待我的 EventHandler 完成处理?