New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Test with PowerMock fails when run on java 1.7.0_65 #524
Comments
From LifusExi...@gmail.com on July 25, 2014 03:27:38 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.system.issuetabpanels:all-tabpanel http://zeroturnaround.com/forums/topic/verifyerror-bad-method-call-from-inside-of-a-branch/ |
From JDever...@gmail.com on August 13, 2014 13:34:22 I believe the original bug was patched in 1.7's 67 patch, but the bug still seems to exist with PowerMock... |
From awo...@fedora-commons.org on August 19, 2014 06:29:08 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? |
From epa...@gmail.com on August 19, 2014 13:03:07 I wonder if PowerMock needs to be rebuilt with a newer JDK version. |
From thinking...@gmail.com on August 20, 2014 14:47:48 There is a work-around for this issue: run the junit tests with a '-noverify' jvm argument |
From lauri.va...@gmail.com on August 21, 2014 05:21:03 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 |
From johan.ha...@gmail.com on August 24, 2014 23:00:22 I'm not sure if there's anything I can do from the PowerMock side to improve this? |
From johan.ha...@gmail.com on August 24, 2014 23:01:22 Issue 505 has been merged into this issue. |
From f...@noidea.de on August 27, 2014 06:06:57 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. |
From johan.ha...@gmail.com on August 27, 2014 10:34:49 Could you help out and provide a pull request for this? That would be great. |
From johan.ha...@gmail.com on August 28, 2014 04:39:32 Hmm I really would like to solve this but I'm not sure how to solve this without branching.. |
From f...@noidea.de on August 28, 2014 05:18:03 Just disable constructor mocking if
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. |
From matt.mil...@gmail.com on August 28, 2014 22:07:07 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. |
From johan.ha...@gmail.com on August 28, 2014 22:22:57 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). Status: Accepted |
From jam...@gmail.com on September 16, 2014 03:41:59 Hey guys, any progress on this? Thanks. |
From BinisBe...@gmail.com on September 19, 2014 05:25:47 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) {}} |
From f...@noidea.de on September 19, 2014 05:29:50 This might be the simplified version you could use to reproduce the error.. code.append("if(value == ").append(MockGateway.class.getName()).append(".PROCEED) {"); 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. |
From matt.mil...@gmail.com on September 23, 2014 18:30:00 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. |
From johan.ha...@gmail.com on September 23, 2014 22:10:50 Thanks a lot for sharing this. |
From jrh...@gmail.com on October 14, 2014 13:48:02 As an FYI: this appears to no longer be an issue on Oracle JDK7u72. |
From johan.ha...@gmail.com on October 14, 2014 22:12:09 Thanks, good to know |
From jeff.pa...@gmail.com on October 15, 2014 15:43:35 I'm still getting it with Oracle MacOS, java full version "1.7.0_72-b14" |
From jrh...@gmail.com on October 16, 2014 06:13:04 That's weird - same OS and same build and update version here. I'm not sure what the difference is there. |
From johan.ha...@gmail.com on October 16, 2014 06:40:35 Perhaps you have different test scenarios? It works in some cases but fails in others?! But then it could be another issue altogether? |
From emla...@gmail.com on October 16, 2014 15:09:31 Oracle released 8U25 on October 14th and this jdk fixed this error for me. |
From Cameron...@gmail.com on October 23, 2014 14:21:26 Simply to give another voice, installing jdk1.7.0_72 fixed this for me as well. |
From japear...@agiledigital.com.au on November 06, 2014 22:07:34 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 |
From rubenale...@gmail.com on November 17, 2014 16:02:48 This issue is present for me I tried 72. |
From iamascr...@gmail.com on January 04, 2015 15:41:14 fwiw - I was experiencing the issue on 7u71, but it is ok on 7u72. |
From kguel...@gmail.com on January 12, 2015 03:37:31 7u72 fixed this for me. |
From q...@cyngn.com on January 20, 2015 10:41:18 for Java SE 8u20 add the following to pom.xml It should work if you are using Java SE 8u25 java version "1.8.0_25" |
From chirag.o...@gmail.com on February 23, 2015 23:14:33 For Java SE 8u25, is it working other except option -noverify ? |
From f...@noidea.de on May 08, 2015 00:47:57 I would close this issue as it is either fixed with jdk 7u72, jdk 8u25 or can be circumvented with -noverify. |
From johan.ha...@gmail.com on May 08, 2015 02:26:01 Ok I'm closing it for now. Status: WontFix |
From begul1234 on July 17, 2014 10:28:21
What steps will reproduce the problem? - Have a unit test annotated with @RunWith(PowerMockRunner.class) @PrepareForTest(MyEndpoint.class)
and use mockStatic(MyEndpoint.class); in the setUp method of the test. What is the expected output? What do you see instead? I would expect that the test runs normally and without error as it did before with older java versions (1.7.0_55 works).
Instead the test fails with the following stacktrace:
java.lang.VerifyError: Bad method call from inside of a branch Exception Details: Location: net/sample/api/endpoint/AbstractB2CJaxRsEndpoint.(Lorg/powermock/core/IndicateReloadClass;)V @41: invokespecial Reason: Error exists in the bytecode Bytecode: 0000000: 2a2b 4e4d 1210 b800 1604 bd00 0d59 032d 0000010: 5313 0126 b800 1bb8 0021 3a05 1905 b200 0000020: 25a5 000e 2a01 c000 27b7 002a a700 0a2c 0000030: 2db7 002a 0157 b1 Stackmap Table: full_frame(@47,{UninitializedThis,Object[#39],UninitializedThis,Object[#39],Top,Object[#13]},{}) full_frame(@54,{Object[#2],Object[#39],Object[#2],Object[#39],Top,Object[#13]},{})
java.lang.VerifyError: Bad method call from inside of a branch
Exception Details:
Location:
net/sample/api/endpoint/AbstractB2CJaxRsEndpoint.(Lorg/powermock/core/IndicateReloadClass;)V @41: invokespecial
Reason:
Error exists in the bytecode
Bytecode:
0000000: 2a2b 4e4d 1210 b800 1604 bd00 0d59 032d
0000010: 5313 0126 b800 1bb8 0021 3a05 1905 b200
0000020: 25a5 000e 2a01 c000 27b7 002a a700 0a2c
0000030: 2db7 002a 0157 b1
Stackmap Table:
full_frame(@47,{UninitializedThis,Object[#39],UninitializedThis,Object[#39],Top,Object[#13]},{})
full_frame(@54,{Object[#2],Object[#39],Object[#2],Object[#39],Top,Object[#13]},{})
Original issue: http://code.google.com/p/powermock/issues/detail?id=504
The text was updated successfully, but these errors were encountered: