Closed GoogleCodeExporter closed 8 years ago
Fixed in trunk for version 1.2
Original comment by johan.ha...@gmail.com
on 19 Jan 2009 at 8:43
Issue 89 has been merged into this issue.
Original comment by johan.ha...@gmail.com
on 22 Jan 2009 at 1:42
There seems to be a similar problem for classes implementing equals() as a final
method which calls another method of that class.
The attached example provokes a StackOverflowError when executed.
StackTrace:
java.lang.StackOverflowError
at java.lang.reflect.Field.<init>(Field.java:103)
at java.lang.reflect.Field.copy(Field.java:126)
at java.lang.reflect.ReflectAccess.copyField(ReflectAccess.java:122)
at sun.reflect.ReflectionFactory.copyField(ReflectionFactory.java:289)
at java.lang.Class.copyFields(Class.java:2711)
at java.lang.Class.getDeclaredFields(Class.java:1715)
at org.powermock.reflect.internal.WhiteboxImpl.getField(WhiteboxImpl.java:188)
at org.powermock.core.MockGateway.fieldCall(MockGateway.java:117)
at powermocktest.ClassToMock.equals(PowerMockEqualsTest.java)
at org.easymock.internal.ExpectedInvocation.matches(ExpectedInvocation.java:77)
at org.easymock.internal.UnorderedBehavior.addActual(UnorderedBehavior.java:38)
at org.easymock.internal.MocksBehavior.addActual(MocksBehavior.java:74)
at org.easymock.internal.ReplayState.invokeInner(ReplayState.java:37)
at org.easymock.internal.ReplayState.invoke(ReplayState.java:33)
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:27)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:61)
at
org.powermock.api.easymock.internal.signedsupport.SignedSupportingClassProxyFact
ory$1.intercept(SignedSupportingClassProxyFactory.java:125)
at powermocktest.ClassToMock$$EnhancerByCGLIB$$8fa55cb1.equals(<generated>)
at powermocktest.ClassToMock.equals(PowerMockEqualsTest.java:45)
at org.easymock.internal.ExpectedInvocation.matches(ExpectedInvocation.java:77)
at org.easymock.internal.UnorderedBehavior.addActual(UnorderedBehavior.java:38)
at org.easymock.internal.MocksBehavior.addActual(MocksBehavior.java:74)
at org.easymock.internal.ReplayState.invokeInner(ReplayState.java:37)
at org.easymock.internal.ReplayState.invoke(ReplayState.java:33)
at org.easymock.internal.MockInvocationHandler.invoke(MockInvocationHandler.java:27)
at org.easymock.internal.ObjectMethodsFilter.invoke(ObjectMethodsFilter.java:61)
at
org.powermock.api.easymock.internal.signedsupport.SignedSupportingClassProxyFact
ory$1.intercept(SignedSupportingClassProxyFactory.java:125)
...
Original comment by marcel.f...@googlemail.com
on 15 Apr 2009 at 12:49
Attachments:
I'll look into it asap, thanks!
Original comment by johan.ha...@gmail.com
on 15 Apr 2009 at 1:51
I've verified the problem and it's a bug. Thanks for finding this! We'll do our
best
to solve it.
Original comment by johan.ha...@gmail.com
on 16 Apr 2009 at 11:45
Original comment by jan.kron...@gmail.com
on 27 Apr 2009 at 4:21
Original comment by jan.kron...@gmail.com
on 27 Apr 2009 at 4:56
Original comment by johan.ha...@gmail.com
on 19 Sep 2009 at 7:41
I'm facing a similar issue when trying to mock a final class. My test code is
something like this:
Project project = PowerMock.createMock(Project.class);
EasyMock.expect(project.getURL()).andReturn(url);
PowerMock.replay(project);
Then the replay method throws a StackOverflowError:
java.lang.StackOverflowError
at org.powermock.reflect.internal.WhiteboxImpl$2.run(WhiteboxImpl.java:1287)
at org.powermock.reflect.internal.WhiteboxImpl$2.run(WhiteboxImpl.java:1284)
at java.security.AccessController.doPrivileged(Native Method)
at org.powermock.reflect.internal.WhiteboxImpl.getAllMethods(WhiteboxImpl.java:1284)
at org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl.java:1526)
at org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl.java:1564)
at
org.powermock.reflect.internal.WhiteboxImpl.getBestMethodCandidate(WhiteboxImpl.
java:836)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:82)
at org.powermock.core.MockGateway.methodCall(MockGateway.java:148)
at ProjectSuperClass.identical(ProjectSuperClass.java)
at Project.equals(Project.java:789)
at org.easymock.internal.Invocation.equals(Invocation.java:95)
The problem lies on Easymock's relying on the equals() method defined in the
class
being mocked:
public boolean equals(Object o) {
if (o == null || !o.getClass().equals(this.getClass()))
return false;
Invocation other = (Invocation) o;
return this.mock.equals(other.mock) && this.method.equals(other.method)
&& this.equalArguments(other.arguments);
}
Which in the case of Project is something like:
public final boolean equals(Object o)
{
if ( o == null || o.getClass() != getClass() ) {
return false;
} else {
return identical(o);
}
}
Because o.getClass() != getClass() fails (as o's class is the bytecode-enhanced
class), it calls method identical(), which recursively calls equals(). I think
the
solution would be to not rely on equals() in this case, but in other mechanism
like
System.identityHashCode:
return System.identityHashcode(this.mock) ==
System.identityHashcode(other.mock)&& ...
-- Felipe
Original comment by felip...@gmail.com
on 5 May 2010 at 5:52
Hi,
We're aware of this. I've actually made fixes in trunk which solves the
issue(s) with
Mockito making it possible to mock/suppress/stub final toString, equals and
hashcode
methods. However for EasyMock you'd have to modify the internals of EasyMock
for this
to work (just as you point out). Perhaps you could bring this up on the
EasyMock
mailinglist? Mockito doesn't have this issue so there must another way for them
to do
it.
/Johan
Original comment by johan.ha...@gmail.com
on 7 May 2010 at 6:09
Changing Easymock's Invocation to use System.identityHashMap() fixes it. I will
try
to write a simpler test case (that does not rely on PowerMock) to reproduce the
issue, then submit a patch to Easymock.
Original comment by felip...@gmail.com
on 7 May 2010 at 4:36
Excellent!
Original comment by johan.ha...@gmail.com
on 7 May 2010 at 5:43
Original comment by johan.ha...@gmail.com
on 22 Jul 2010 at 9:16
Changing to a lower priority since this will hopefully be solved by the
EasyMock team.
Original comment by johan.ha...@gmail.com
on 8 Aug 2010 at 9:02
We have a similar problem with StackOverflowError, using either PowerMock
version 1.3.8 with mockito 1.8.4 or PowerMock version 1.4.5 with mockito 1.8.5.
Relevant lines from the stack trace:
java.lang.StackOverflowError
at java.security.AccessController.doPrivileged(Native Method)
at org.powermock.reflect.internal.WhiteboxImpl.getAllMethods(WhiteboxImpl.java:1626)
at org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl.java:1909)
at org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl.java:1952)
at org.powermock.reflect.internal.WhiteboxImpl.getBestMethodCandidate(WhiteboxImpl.java:1056)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:89)
at org.powermock.core.MockGateway.methodCall(MockGateway.java:168)
at com.google.gwt.core.client.JavaScriptObject.equals(JavaScriptObject.java)
at org.mockito.internal.invocation.InvocationMatcher.matches(InvocationMatcher.java:57)
at org.mockito.internal.stubbing.InvocationContainerImpl.findAnswerFor(InvocationContainerImpl.java:72)
at org.mockito.internal.MockHandler.handle(MockHandler.java:93)
at org.powermock.api.mockito.internal.invocationcontrol.MockitoMethodInvocationControl.performIntercept(MockitoMethodInvocationControl.java:267)
at org.powermock.api.mockito.internal.invocationcontrol.MockitoMethodInvocationControl.invoke(MockitoMethodInvocationControl.java:169)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:105)
at org.powermock.core.MockGateway.methodCall(MockGateway.java:168)
at com.google.gwt.core.client.JavaScriptObject.equals(JavaScriptObject.java)
...
We can also post source code if needed or try to minimize to a suitable test
case.
As I read this bug, and according to comment 10, it should have been fixed for
mockito with the following commit:
http://code.google.com/p/powermock/source/detail?r=1294
which is also mentioned in the change log for PowerMock 1.3.8.
So is this fixed for any combination of PowerMock / Mockito? Has it been
released?
If you need more info feel free to ask!
Thanks,
-fotos
Original comment by gfo...@gmail.com
on 31 Aug 2010 at 9:15
[deleted comment]
[deleted comment]
I've also been getting StackOverflowErrors when trying to mock a class with a
final method. The class has a superclass that overrides equals(). If I remove
the equals() implementation then the error does not occur and the test
completes normally. I am using powermock 1.4.6 (also tried 1.4.5) with JUnit
4.8.1, downloaded with maven:
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.4.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.4.6</version>
<scope>test</scope>
</dependency>
Original comment by teevee...@hotmail.co.uk
on 19 Oct 2010 at 3:31
I have the same issue. Has the fix been released?
Original comment by linh.dan...@gmail.com
on 24 Jan 2011 at 9:13
I am having the same issue as well. I am using PowerMock 1.4.9 with Mockito
1.8.5. Following is the stack trace:
java.lang.StackOverflowError
at java.lang.ref.Reference.get(Reference.java:160)
at java.lang.ref.SoftReference.get(SoftReference.java:93)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2421)
at java.lang.Class.getDeclaredMethods(Class.java:1791)
at org.powermock.reflect.internal.WhiteboxImpl$3.run(WhiteboxImpl.java:1608)
at org.powermock.reflect.internal.WhiteboxImpl$3.run(WhiteboxImpl.java:1605)
at java.security.AccessController.doPrivileged(Native Method)
at org.powermock.reflect.internal.WhiteboxImpl.getAllMethods(WhiteboxImpl.java:1605)
at org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl.java:1888)
at org.powermock.reflect.internal.WhiteboxImpl.getMethods(WhiteboxImpl.java:1931)
at org.powermock.reflect.internal.WhiteboxImpl.getBestMethodCandidate(WhiteboxImpl.java:1025)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:89)
at org.powermock.core.MockGateway.methodCall(MockGateway.java:168)
at net.sf.ehcache.Element.equals(Element.java)
at org.mockito.internal.invocation.InvocationMatcher.matches(InvocationMatcher.java:57)
at org.mockito.internal.stubbing.InvocationContainerImpl.findAnswerFor(InvocationContainerImpl.java:72)
at org.mockito.internal.MockHandler.handle(MockHandler.java:93)
at org.powermock.api.mockito.internal.invocationcontrol.MockitoMethodInvocationControl.performIntercept(MockitoMethodInvocationControl.java:291)
at org.powermock.api.mockito.internal.invocationcontrol.MockitoMethodInvocationControl.invoke(MockitoMethodInvocationControl.java:193)
at org.powermock.core.MockGateway.doMethodCall(MockGateway.java:105)
at org.powermock.core.MockGateway.methodCall(MockGateway.java:168)
...
at net.sf.ehcache.Element.equals(Element.java)
at org.mockito.internal.invocation.InvocationMatcher.matches(InvocationMatcher.java:57)
at org.mockito.internal.stubbing.InvocationContainerImpl.findAnswerFor(InvocationContainerImpl.java:72)
Original comment by forthw...@gmail.com
on 10 Aug 2011 at 8:31
I have the same issue. Has the fix been released? Where can I get it?
Original comment by michael....@gmail.com
on 8 Sep 2011 at 9:04
Unfortunately not. I'd really appreciate some help with this.
Original comment by johan.ha...@gmail.com
on 8 Sep 2011 at 10:01
ok it works, if you remove the "final" from the "equals"-method
Original comment by michael....@gmail.com
on 8 Sep 2011 at 1:21
But, why?
Original comment by michael....@gmail.com
on 8 Sep 2011 at 1:21
When I wrote this, only God and I understood what I was doing. Now, God only
knows.
Original comment by johan.ha...@gmail.com
on 8 Sep 2011 at 2:02
Hi guys,
Still reproducible with Mockito 1.9.0 and Powermock 1.4.11. Actually, it's
reproducible with any final equals().
Regards,
Daniel
Original comment by gloeckne...@gmail.com
on 25 Jan 2012 at 11:51
There has been no work on this from my side. Please help out.
Original comment by johan.ha...@gmail.com
on 25 Jan 2012 at 12:11
I am having this issue as well - any plans to solve it in near future?
Original comment by kals...@gmail.com
on 2 Apr 2012 at 3:53
I would really appreciate some help with this issue. Provide a patch and I'll
include it in the next release.
Original comment by johan.ha...@gmail.com
on 2 Apr 2012 at 5:38
Hi all,
I've attached some simple code to parse a .class file and generate a new .class
file with all final Opcodes removed.
I'm not really familiar with how ClassLoaders work but I guess this could be
adapted to modify the target classes at runtime removing final from only the
equals method.
Not sure if this is helpful or not. For now I'm just parsing my 3rd party
libraries class files with it so that I can run the tests.
Karle
Original comment by karlek...@gmail.com
on 15 May 2012 at 11:48
Attachments:
Oops, chopped off imports from above:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
Dependencies: asm-4.0.jar
Original comment by karlek...@gmail.com
on 15 May 2012 at 11:49
Also seeing this issue: Mockito 1.8.5 & Powermocks 1.4.9. I don't have control
over the code with the offending final equals.. any suggestions on a workaround
to mock it..?
Original comment by mark.dav...@gmail.com
on 2 Jul 2012 at 4:41
I think I might have found a fix for that.
The idea is to add an identity check to
org.mockito.internal.invocation.InvocationMatcher.matches(Invocation). The code
here looks as follows:
public boolean matches(Invocation actual) {
return invocation.getMock().equals(actual.getMock()) &&
hasSameMethod(actual)
&& new ArgumentsComparator().argumentsMatch(this, actual);
}
It seems to me that calling equals on invocation.getMock() ends up in the same
method and thereby triggers the StackOverflow. My solution to that would be to
make an identity comparision. When the identity is the same the objects must be
equal too, at least for common java standards. When I change the matches-method
to the following:
public boolean matches(Invocation actual) {
return (
invocation.getMock() == actual.getMock()
|| invocation.getMock().equals(actual.getMock())
) && hasSameMethod(actual) && new ArgumentsComparator().argumentsMatch(this,
actual);
}
My test completes
I cannot really tell if this has any unwanted side-effects, but as I just
wrote, according to java standards it should not.
Original comment by peer.har...@gmail.com
on 10 Apr 2014 at 4:24
Is this code change required inside Mockito? Is there anything we can do from
the PowerMock side?
Original comment by johan.ha...@gmail.com
on 11 Apr 2014 at 9:12
Yes I think so. You could identify that problem in the MockGateway class and
perform a workaround there. I attach an updated version with a fix. It uses
Mockito's MethodGuru to identify the situation and then simply returns PROCEED
which results in a call to the real method.
Since AFAIK it is not possible to Mock equals-Methods with mockito, that should
be the desired behavior. But again I am not an expert on PowerMock's internal
concepts...
Original comment by peer.har...@gmail.com
on 29 Apr 2014 at 7:53
Attachments:
Could you please provide this patch as a pull request on github??
Original comment by johan.ha...@gmail.com
on 4 Jun 2014 at 6:07
I was able to work around this issue by setting:
MockGateway.MOCK_STANDARD_METHODS = false;
It makes MockGateway not mock toString, hashcode, and equals.
Original comment by rsroman...@gmail.com
on 13 Jun 2014 at 7:16
This should now have been fixed in master. Published a new snapshot, depend on
version 1.5.6-SNAPSHOT to try it out after having added the following repo:
<repositories>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
<snapshots />
</repository>
</repositories>
Original comment by johan.ha...@gmail.com
on 10 Jul 2014 at 6:34
Original comment by johan.ha...@gmail.com
on 10 Jul 2014 at 6:35
I could still see this issue. I can see that the status has been updated to
Fixed. But can you please provide the Mockito and PowerMock versions post which
we will not see this issue?
Original comment by siddhart...@gmail.com
on 23 Sep 2014 at 4:00
Try the latest version of PowerMock and Mockito
Original comment by johan.ha...@gmail.com
on 23 Sep 2014 at 5:14
Original issue reported on code.google.com by
johan.ha...@gmail.com
on 16 Jan 2009 at 5:40