Reputation: 5325
In my project, I could see all the JUnit Test cases are written in eclipse fragments not in eclipse plugin. And we do run each test classes as JUnit plugin. I am not very much clear about the concepts. I am relatively new to this concept.
I just googled to get better knowledge about using fragments over Plugins for Tests. What I have understood is, fragments and host plugins share the same class loader.Please correct me if my understanding is wrong.
However I did not understand the meaning of the below line.
If we create the tests in eclipse plugin, test classes will be loaded by a separate Classloader and will therefore not have access to the non-public methods of the classes under test.
Why it does not have access to the non-public methods? can any one help me in understanding the meaning of the above with simple example?
Upvotes: 2
Views: 460
Reputation: 3211
To understand this you need to understand how classes and classloading actually works in Java. Often we think of loading in terms of 'the classpath', but this is a massive simplification of how things work. In many Java SE envrionments this just works, but in multi-tenanted environments like OSGi it gets more complicated.
Essentially in Java classes are scoped by three things:
It is perfectly possible to have two instances of myPackage.MyClass loaded in the JVM at more than once, you just need multiple classloaders. Even though these classes could be loaded from identical .class files they will be different at runtime. This can cause much confusion when you write code like this:
MyClass c = (MyClass)obj;
and get a ClassNotFoundException: MyClass
.
Classes exist in packages and there are special visibility rules associated with this. Types, methods and fields with no stated visibility are visible to all types in the same package. When a class is loaded it gets associated with a java.lang.reflect.Package and the visibility rules are resolved by essentially checking that the classes are associated with the same java.lang.reflect.Package instance. So in the case of mypackage.MyClass if you load it twice using two different classloaders you will get two Package instances for mypackage.
OSGi is designed to support multi-tenanted class loading, this is what allows you to have two different versions of a class or package in the same JVM at once. This solve many problems caused if you have different version dependencies. It implements this by using a different Classloader for each bundle. Fragments work differently that bundles in that they are associated with a bundle and classes in them are loaded by the bundle's Classloader rather than having their own one.
To relate this back to your original question if you put your junit tests in a bundle (rather than a fragment) your class will be loaded by a different classloader, so it'll be associated with a different instance of java.lang.reflect.Package so when the JVM tests for member accessability it will fail.
Upvotes: 2