dhamini-poornachandra / mockito

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

Deserialization of a mock fails when run inside a container #268

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Compile the attached Fail.java class with Mockito on the classpath.
2. Run it.
3. See the ClassNotFoundException.

I'm on JDK 1.6.21x64 on Ubuntu.

What's happening is that JDK deserialization can't find the classes that 
Mockito sometimes creates. When Mockito creates a class, it sometimes creates a 
new classloader, too, and loads the class from that classloader. But only that 
class maintains the reference to that classloader. JDK deserialization doesn't 
know about it; it doesn't have a smart way of finding the classloader to use.

Mockito uses some code from JMock to interface with cglib, and it is this code 
that decides to create a new classloader. But it only actually creates one when 
the thread's context classloader is different from the class-to-be-mocked's 
classloader (apparently so JMock will work with Maven Surefire - see 
http://jira.codehaus.org/browse/JMOCK-135).

The attached example artificially sets the thread classloader to be a new 
classloader with the standard one as the parent. But when I run in a container, 
the thread class loader is different, and I get this problem.

When the ClassImposteriser creates a mock, it calls 
SearchingClassLoader.combineLoadersOf(Class...) and sets the resulting 
classloader as the Enhancer's classloader. The new class will be loaded from 
this classloader. 

Original issue reported on code.google.com by ladlest...@gmail.com on 1 Jul 2011 at 3:50

Attachments:

GoogleCodeExporter commented 8 years ago

Original comment by brice.du...@gmail.com on 29 Nov 2012 at 9:54

GoogleCodeExporter commented 8 years ago
Hey could you try our latest snapshot on the matter, I've tweaked mock 
serialization to enable serialization/deserialization across classloaders / jVM.

Original comment by brice.du...@gmail.com on 8 Jan 2013 at 4:48

GoogleCodeExporter commented 8 years ago

Original comment by brice.du...@gmail.com on 8 Jan 2013 at 4:49

GoogleCodeExporter commented 8 years ago
I have a somewhat unusual setup and ran into similar issue. We have a test 
framework written in python. It was initially used to launch C++ apps and 
interact with them through some sort of transport. I have added support for 
running java using pyjnius package, which is based on JNI Invocation API. 
Basically cpython runs JVM in process and wraps java classes as python classes. 
I have tried to take the framework a bit further and enable use of mockito, 
which would be a huge improvent in writing actual test cases. However I tan 
into an issue where mockito generated classes are not visible from system class 
loader. Any suggestions how to get around this ?

Original comment by Eugf...@gmail.com on 6 Feb 2013 at 10:28

GoogleCodeExporter commented 8 years ago
Hi,

Your use case looks quite specific. I'm not sure how your stuff works, but with 
JNI or even things like cpython, I cannot guarantee mockito will work fine.

About generated mocks not visible in the system classloader, I'm not sure what 
you mean, but bytecode is injected at runtime in a subclassloader (not the 
system classloader ; the one that is null when calling getClassloader()). So 
that is expected.

At a first glance it doesn't seem related to deserialization, shall we move 
this discussion on the mailing list ?

Did you tried the last snapshot of mockito ?

Cheers,
Brice

Original comment by brice.du...@gmail.com on 8 Feb 2013 at 2:51