Closed GoogleCodeExporter closed 8 years ago
Most likely, it's a JDK bug
Root cause(?):
https://bugs.openjdk.java.net/browse/JDK-8051012
Related issues:
https://jira.codehaus.org/browse/GROOVY-6951?page=com.atlassian.jira.plugin.syst
em.issuetabpanels:all-tabpanel
http://zeroturnaround.com/forums/topic/verifyerror-bad-method-call-from-inside-o
f-a-branch/
Original comment by LifusExi...@gmail.com
on 25 Jul 2014 at 10:27
I believe the original bug was patched in 1.7's 67 patch, but the bug still
seems to exist with PowerMock...
Original comment by JDever...@gmail.com
on 13 Aug 2014 at 8:34
This is a show-stopper for our use of PowerMock. Are there plans on the
horizon? or is the recommendation to move to a different test library?
Original comment by awo...@fedora-commons.org
on 19 Aug 2014 at 1:29
I wonder if PowerMock needs to be rebuilt with a newer JDK version.
Original comment by epa...@gmail.com
on 19 Aug 2014 at 8:03
There is a work-around for this issue: run the junit tests with a '-noverify'
jvm argument
Original comment by thinking...@gmail.com
on 20 Aug 2014 at 9:47
I added a comment to https://issues.jboss.org/browse/JASSIST-228 that suggest
another workaround for this problem. (unfortunatelly they are maintaining their
server currently and i cannot quote myself from there)
However, if you still feel that you need to have your java class file verifyed
(hence -noverify is out for you) you can use -XX:-UseSplitVerifier option when
you start your tests.
And if you are like me, and start your tests with maven, then you need to add
something similar to your pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.10</version>
<configuration>
<argLine>-XX:-UseSplitVerifier</argLine>
</configuration>
</plugin>
</plugins>
</build>
Original comment by lauri.va...@gmail.com
on 21 Aug 2014 at 12:21
I'm not sure if there's anything I can do from the PowerMock side to improve
this?
Original comment by johan.ha...@gmail.com
on 25 Aug 2014 at 6:00
Issue 505 has been merged into this issue.
Original comment by johan.ha...@gmail.com
on 25 Aug 2014 at 6:01
You must avoid branching before a super call.
You could change the ExprEditor in the MainMockTransformer Line 269-273 to use
no branching. Or use branching only if really needed and verify it. (I don't
know how to call the JVM verifier, using CtClasses
.toClass().getDeclaredConstructors() would throw a Exception) From thereon you
could show a nice error message explaining the details.
Original comment by f...@noidea.de
on 27 Aug 2014 at 1:06
Could you help out and provide a pull request for this? That would be great.
Original comment by johan.ha...@gmail.com
on 27 Aug 2014 at 5:34
Hmm I really would like to solve this but I'm not sure how to solve this
without branching..
Original comment by johan.ha...@gmail.com
on 28 Aug 2014 at 11:39
Just disable constructor mocking if
CtClass ctClass = ClassPool.getDefault().makeClass("TestForBadOperandWhenInvokingInit");
// java.lang.VerifyError: Bad operand type when invoking <init>
ctClass.addConstructor(CtNewConstructor.make(new CtClass[0], new CtClass[0], "{if (1 != 2){ super();}}", ctClass));
final Class<?> clazz = ctClass.toClass();
clazz.getDeclaredConstructors();
throws an Exception and log it out. There is already a fix commited for the
next JDK version, so this bug should not haunt us for long.
Original comment by f...@noidea.de
on 28 Aug 2014 at 12:18
I don't believe that this is a bug in the JDK. Oracle has decided to make their
byte code verification rules stricter-details here
http://www.takipiblog.com/oracles-latest-java-8-update-broke-your-tools-how-did-
it-happen/.
I also don't believe that there will be a fix in future versions of java as it
is not a bug it is a feature. Oracle Java 8u20 still has this "feature".
The suggestion to use the SplitVerifier may work in Java 7 but I believe that
the SplitVerifier has been removed in java 8. There is the option to turn off
verification completely for tests (ie -noverify) but the confidence is lost
that your code will work in production without this option and I don't think
disabling bytecode verification in production is a great idea.
The OpenJDK team may of reverted the change but I don't think oracle will be so
nice :)
The only real option is to fix the offending PowerMock class.
Original comment by matt.mil...@gmail.com
on 29 Aug 2014 at 5:07
If you're right we need to figure out a way to fix it. How it works now is that
before the call to super the MockGateway is invoked to decide whether or not to
call the super method or call another constructor (generated by PowerMock).
This is used for constructor suppression (suppress(constructor(X.class))) if I
remember it correctly. All method invocations, field invocations etc works in
the same way (they all ask the MockGateway if they should continue or replace
the call with a mock). For constructors I'm not sure how to solve this unless
we insert this if statement (which I believe is the cause of the error) before
the super call in the constructor byte-code. If you have any ideas for a
workaround I would be really happy.
A really ugly work-around would be to let the user somehow configure PowerMock
not to byte-code manipulate constructors (if you don't need to use this
functionality). That way I assume that some errors can go away but PowerMock
will be left in a degraded state. Not sure if I want to go down this route..
However I've been thinking about implementing something like this before to
speed up the byte-code manipulation (such as turing off field interception
which is quite slow and not used very often afaik).
Original comment by johan.ha...@gmail.com
on 29 Aug 2014 at 5:22
Hey guys, any progress on this?
It is affecting us too.
Thanks.
Original comment by jam...@gmail.com
on 16 Sep 2014 at 10:41
ctClass.addConstructor(CtNewConstructor.make(new CtClass[0], new CtClass[0],
"{if (1 != 2){ super();}}", ctClass));
Looks like this line makes new constructor with code. Right?
{if (1 != 2){ super();}}". Not sure why 1 != 2 check is needed but this is what
is causing the problem. the first thing you have to invoke in the constructor
is the super constructor. So probably it should be something like this
{super(); if (1 != 2) {}}
Original comment by BinisBe...@gmail.com
on 19 Sep 2014 at 12:25
This might be the simplified version you could use to reproduce the error..
The original code is:
code.append("if(value ==
").append(MockGateway.class.getName()).append(".PROCEED) {");
code.append(" $_ = $proceed($$);");
code.append("} else {");
code.append(" $_ =
").append(getCorrectReturnValueType(returnTypeAsCtClass)).append(";");
code.append("}}");
It is there to decide if another constructor should be called.. that code must
be changed to call super() first. YOu would loose the ability of on demand
constructor mocking.. or you would have to replace the mocked constructors
during mocking.
Original comment by f...@noidea.de
on 19 Sep 2014 at 12:29
So I had a chat to some of of the developers here and I've learnt that the
Oracle JDK is built on top of OpenJDK so any fixes made in OpenJDK will find
their way through to the Oracle JDK. Therefore this "feature" has been reverted
as per this issue https://bugs.openjdk.java.net/browse/JDK-8051012 and we just
need to wait for the relevant version to be released. For java 8 it looks like
8u20 b31 has it fixed, the latest public release is for 8u20 is b26 so the fix
hasn't been released yet. I couldn't find a release date for build 31 anywhere.
Original comment by matt.mil...@gmail.com
on 24 Sep 2014 at 1:30
Thanks a lot for sharing this.
Original comment by johan.ha...@gmail.com
on 24 Sep 2014 at 5:10
As an FYI: this appears to no longer be an issue on Oracle JDK7u72.
Original comment by jrh...@gmail.com
on 14 Oct 2014 at 8:48
Thanks, good to know
Original comment by johan.ha...@gmail.com
on 15 Oct 2014 at 5:12
I'm still getting it with Oracle MacOS, java full version "1.7.0_72-b14"
Original comment by jeff.pa...@gmail.com
on 15 Oct 2014 at 10:43
That's weird - same OS and same build and update version here. I'm not sure
what the difference is there.
Original comment by jrh...@gmail.com
on 16 Oct 2014 at 1:13
Perhaps you have different test scenarios? It works in some cases but fails in
others?! But then it could be another issue altogether?
Original comment by johan.ha...@gmail.com
on 16 Oct 2014 at 1:40
[deleted comment]
Oracle released 8U25 on October 14th and this jdk fixed this error for me.
Original comment by emla...@gmail.com
on 16 Oct 2014 at 10:09
Simply to give another voice, installing jdk1.7.0_72 fixed this for me as well.
Original comment by Cameron...@gmail.com
on 23 Oct 2014 at 9:21
For reference, the bug that is apparently fixed is:
http://bugs.java.com/view_bug.do?bug_id=8051012
It is referenced from this page:
http://www.oracle.com/technetwork/java/javase/2col/7u72-bugfixes-2298229.html
I presume the bug isn't marked as resolved, because update 72, is some weird
sort of halfway release, where Oracle recommends you use update 71 unless you
need fixes from 72:
http://www.oracle.com/technetwork/java/javase/7u72-relnotes-2296190.html
Original comment by japear...@agiledigital.com.au
on 7 Nov 2014 at 6:07
This issue is present for me I tried 72.
It works with the UseSplitVerifier option. But, that will be deprecated:
https://code.google.com/p/powermock/issues/detail?id=504
So, unless this is fixed, will have to migrate to a different framework. I'll
take a look to the code later on to see if there is something I can help with.
Original comment by rubenale...@gmail.com
on 18 Nov 2014 at 12:02
fwiw - I was experiencing the issue on 7u71, but it is ok on 7u72.
Original comment by iamascr...@gmail.com
on 4 Jan 2015 at 11:41
7u72 fixed this for me.
Original comment by kguel...@gmail.com
on 12 Jan 2015 at 11:37
for Java SE 8u20
java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
add the following to pom.xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
<configuration>
<argLine>-noverify</argLine>
</configuration>
</plugin>
It should work if you are using Java SE 8u25
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
Original comment by q...@cyngn.com
on 20 Jan 2015 at 6:41
For Java SE 8u25, is it working other except option -noverify ?
Original comment by chirag.o...@gmail.com
on 24 Feb 2015 at 7:14
[deleted comment]
I would close this issue as it is either fixed with jdk 7u72, jdk 8u25 or can
be circumvented with -noverify.
Original comment by f...@noidea.de
on 8 May 2015 at 7:47
Ok I'm closing it for now.
Original comment by johan.ha...@gmail.com
on 8 May 2015 at 9:26
Was facing issue with gradle, testng, and powermock. In case, someone wants to
add -noverify in gradle, here is the reference link to add jvm args in gradle:
https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html
Original comment by hiteshms...@gmail.com
on 24 Aug 2015 at 12:50
Original issue reported on code.google.com by
begul1234
on 17 Jul 2014 at 8:28