joepadde / mockito

Automatically exported from code.google.com/p/mockito
0 stars 0 forks source link

MockMaker plugin framework's discovery mechanism doesn't work on Android Eclair #354

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Mockito 1.9.5 attempts to load a MockMaker instance by looking up the name of 
the MockMaker implementation in a resource. On Android, this mechanism works 
fine on Froyo (Android 2.2) and above, but does not work on Eclair (Andoid 2.1).

The root cause is that Mockito's ClassPathLoader uses the calling thread's 
context ClassLoader to find the resource file that contains the name of the 
MockMaker implementation class. On Android Eclair (and, perhaps, earlier, but I 
haven't tested) this ClassLoader has a path of "." instead of listing the 
APKs/JARs comprising the running app. Substituting the context ClassLoader for 
the ClassLoader that loaded Mockito's ClassPathLoader class (i.e., 
ClassPathLoader.class.getClassLoader()) seems to work just fine on Eclair and 
above.

I don't know whether there is a scenario where Mockito should use the thread's 
context ClassLoader. Thus, I'm not submitting a particular patch yet.

If there's no need to use the thread's context ClassLoader, then the simplest 
fix is to replace Thread.currentThread().getContextClassLoader() with 
ClassPathLoader.class.getClassLoader() in ClassPathLoader.java 
(http://code.google.com/p/mockito/source/browse/src/org/mockito/internal/configu
ration/ClassPathLoader.java?r=4307f1dcee600f516c7825e39959a7a33fb3bae3#113).

Original issue reported on code.google.com by klyu...@google.com on 3 Jul 2012 at 10:44

GoogleCodeExporter commented 8 years ago
It looks like the Thread.currentThread().getContxtClassLoader() line appeared 
in c27e9c7d7688c1f497af95ef004e7d6439c42080 where it replaced 
java.util.ServiceLoader.load(Class) which uses the thread's context ClassLoader.

Thus, it seems to me that using the thread's context ClassLoader is the right 
thing to do. The question is how to fix this issue for Android Eclair (if at 
all -- its share of Android devices is around 5% and dwindling) without 
affecting other cases.

The issue on Android Eclair might be caused by 
http://code.google.com/p/android/issues/detail?id=5697.

Original comment by klyu...@google.com on 9 Jul 2012 at 11:37

GoogleCodeExporter commented 8 years ago
I don't think we want to fix this for Eclair, which is the problem. Work-around 
for Eclair devices with this line of code:
    Thread.currentThread().setContextClassLoader(getClass().getClassLoader());

Original comment by limpbizkit on 10 Jul 2012 at 2:22

GoogleCodeExporter commented 8 years ago
Fair enough. Feel free to close this issue.

Original comment by klyu...@google.com on 10 Jul 2012 at 9:51

GoogleCodeExporter commented 8 years ago
OK, thx for the information :)
Issue closed.

Original comment by brice.du...@gmail.com on 16 Jul 2012 at 12:35

GoogleCodeExporter commented 8 years ago
For posterity, the fixed I implemented in our project is here: a custom 
InstrumentationTestRunner that sets the thread's context class loader to the 
one that works: 
http://code.google.com/p/google-authenticator/source/browse/tests/src/com/google
/android/apps/authenticator/MockitoWorkaroundForEclairInstrumentationTestRunner.
java??r=441dc15b40d9d6c19d05913653fee5b351824b93&repo=android&repo=android.

Original comment by klyu...@google.com on 16 Jul 2012 at 8:34