Проблемы с синхронизацией экзамена Pax

Я использую 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 все еще обрабатывает пакеты, успешно читая и записывая из БД, когда TransactionManager подметается под его ноги. Итак, мой вопрос: есть ли способ заставить Pax Exam ждать, пока мой EventHandler завершит свою обработку, прежде чем закрыть Karaf?


person Christina    schedule 06.05.2014    source источник


Ответы (1)


Кажется, вам нужно установить семафор до возврата тестового метода. Семафор будет освобожден EventHandler после выполнения условия завершения.

Кроме этого, если вы используете karaf 2.x, возможно, это какая-то проблема синхронизации чертежей.

person Wojciech Kudla    schedule 06.05.2014
comment
Нет, я использую Karaf 3.0.1, поэтому я думаю, что это не проблема синхронизации чертежей, о которой вы говорите. Я немного скептически отношусь к семафору, поскольку тест и EventHandler находятся в двух разных пакетах, поэтому я бы использовал логику одного пакета в зависимости от тестов другого. Возможно, у вас есть пример того, как это будет работать, который я вижу? - person Christina; 07.05.2014