Probes conflicts with PAX-Exam 4
Edit: this bug is even worst than what I was thinking.
The explaination below is incomplete. The bug occurred randomly. And probe names were a wrong lead. In fact, I have a race condition when loading bundles. I limited its impact by defining an Import-Package header in my probe.
// Force the use of the AgentMessagingInterface from the agent's bundle. probe.setHeader( "Import-Package", "net.roboconf.agent" );
It imports the package that was conflicting. This way, I am sure my probe does not inject its own version of the package. But still, this is a very curious bug.
Here is the original post…
I have just lived an unexpected thing while adding a new integration test on Roboconf. “Just lived” is a little bit exagerated. I spent two hours to understand and try to solve it. Anyway, these tests are run with PAX-Exam 4. They allow us to verify our OSGi bundles work as expected in an OSGi environment.
So, here is what happened.
I have one test called AgentInitializationTest. And I added DelayedAgentInitializationTest. Run individually in Eclipse, they both worked. Run in a single row with Maven, the last one was failing.
I had an @Inject annotation which was failing.
There was an IllegalArgumentException thrown by Field.java:741. I did not understand why I had this. I tested a workaround by injecting the bundle context and retrieving my service reference by hand. But I still had errors when casting my service to its interface.
ServiceReference serviceReference = context.getServiceReference( AgentInterface.class ); AgentInterface itf = (AgentInterface) context.getService( serviceReference );
That was not working, while context.getService() returned an instance of AgentInterface. As reminded on Oracle’s web site, there are two reasons for such a thing to happen. Either both objects have no relation (which is not the case here, one implements the other), or theirs definitions come from different class loaders.
And indeed: my service and its interface came from different class loaders. The Agent class was exported by its bundle whereas the AgentInterface interface was exported by a PAX-Exam probe. This was not normal at all, since my new test was not adding agent classes in its probe. Said differently, both tests had different probes configurations. Besides, my tests were all annotated with the PerMethod reactor strategy to isolate my tests.
Eventually, I @ignored AgentInitializationTest and run my tests with Maven. Miracle, DelayedAgentInitializationTest was now working. I eventually renamed my new test in AgentWithDelayedInitializationTest and now, everything is working fine.
Clearly, the probe from a previous test was injected into my new test. And this is most likely related to the test names. My intuition is that if they are wrongly chosen, there can be conflicts in probes injection. So, if you encounter the same issue one day, just make sure all your tests have different names and that no one prefixes another test name.