Christina
Christina

Reputation: 3732

Pax Exam synchronisation issues

I am using Pax Exam to perform integration tests to my OSGi application. The application is comprised of a number of different bundles which I deploy to the test container using a ConfigurationFactory as follows:

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"));
}
}

This works great and I can then write test methods to test my application, I have however the following problem which I understand is in essence a synchronisation issue. One of the bundles I deploy as part of my-feature has an EventHandler which listens for bundles being started and writes some information about each started bundle to the DB. This I assume is something that takes place asynchronously to the execution of my test method. After my test method is executed I can therefore see the following exception in my test output for a query that takes place in my 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

My understanding is that this exception is due to the fact that at the moment my test methods are executed and Pax Exam starts shuting down the container my EventHandler is still handling bundles, happily reading and writing from the DB, when the TransactionManager is swept under its feet. So my question is, is there a way to force Pax Exam to wait for my EventHandler to finish its processing before shutting down Karaf?

Upvotes: 0

Views: 534

Answers (1)

Wojciech Kudla
Wojciech Kudla

Reputation: 56

It seems you need to establish a semaphore before the test method returns. The semaphore would get released by the EventHandler after meeting a termination condition.

Other than that, if you're on karaf 2.x then maybe it's some blueprint synchronization issue.

Upvotes: 0

Related Questions