java.lang.IllegalAccessError
. The reason is simple: each OSGi bundle runs it's own class loader and therefore the classes appear not to be in the same package. There are different solutions:
- Make all methods and classes you want to test public (really bad idea)
- Put the unit tests into the same plugin as your code and make the dependency to JUnit optional (not a good separation of concerns).
- Only test public classes and methods (I think this is to restrictive and often to coarse grain)
- Make your test plugin a fragment. One problem is that other plugins cannot access classes defined in fragments (as Patrick Paulin points out in a more detailed discussion about fragments in unit tests). Another problem is that plugin.xml in a fragment is ignored. And therefore you test plugin cannot contribute
I tried out turning a plugin into a fragment. It is as simple as adding adding a line following line to your MANIFEST.MF
Fragment-Host: org.eclipse.the.plugin.you.want.to.testand removing the plugin you want to test from the required plugins. As long as your test plugin is not part of a bigger test case and it does not need to contribute extensions Patrick Paulin describes a solution for that using reflection, fragments are a good solution.
A good way to avoid having to use extensions (plugin.xml) in your test plugin is to use dependency injection for your classes.
But I think there should be a better way to write a test plugin that can access non public classes and members. I understand why the security concept of OSGi introduces those problems, but I am still looking for a solution for my JUnit tests.
Any ideas?