Skip to content

Update dependencies for Java 11 support #952

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

Merged
merged 4 commits into from
Nov 7, 2018

Conversation

ijuma
Copy link
Contributor

@ijuma ijuma commented Oct 29, 2018

cglib, bytebuddy, javassist and easymock.

@ijuma
Copy link
Contributor Author

ijuma commented Oct 29, 2018

cc @thekingnothing

@ijuma ijuma force-pushed the bump-deps-java11 branch 4 times, most recently from 191b6fd to 00442da Compare October 29, 2018 14:13
@ijuma
Copy link
Contributor Author

ijuma commented Oct 29, 2018

Looks like some code no longer compiles with the new version of EasyMock. Will look into that later.

@ijuma
Copy link
Contributor Author

ijuma commented Oct 30, 2018

Hmm, compiling with the new EasyMock version seems to cause problems:

samples.powermockito.junit4.agent.AnnotationUsageTest > annotationsAreEnabledWhenUsingTheJUnitRule[0] FAILED
    java.lang.VerifyError: Expecting a stackmap frame at branch target 38
    Exception Details:
      Location:
        org/easymock/EasyMockSupport.resetAll()V @16: ifeq
      Reason:
        Expected stackmap frame at this location.
      Bytecode:
        0x0000000: 2ab4 0016 b900 7201 004c 2bb9 0078 0100
        0x0000010: 9900 162b b900 7c01 00c0 0021 4d2c b900
        0x0000020: 8401 00a7 ffe7 b1           

cc @henri-tremblay in case he has any thoughts.

As an aside, 2.0.0-RC.2 does not include all the modules. For example: https://repo1.maven.org/maven2/org/powermock/powermock-module-junit4/

@thekingn0thing
Copy link
Member

@ijuma the 2.0.0-RC.2 should not be sync to Maven central at all. I didn't add [ci maven-central-release] to comments. I wanted to wait for your pull request before releasing artefacts to the central repository.

@ijuma
Copy link
Contributor Author

ijuma commented Oct 30, 2018

That makes sense with regards to 2.0.0-RC.2, thanks (I misread the build output).

@henri-tremblay
Copy link
Contributor

It looks like a call to resetAll done by generated code without a stackmap. Last time I saw that was because I was on an old ASM or Cglib I think. It is really far in my head. A workaround might have been to tell the code it's pre Java 7 (I think that's when stackmap was introduce). All this is from top of my head. The problem comes possible by EasyMock being Java 8 code now so what you were doing with it isn't working anymore. Cross your fingers you won't have to create a stackmap.

@ijuma
Copy link
Contributor Author

ijuma commented Oct 31, 2018

@thekingnothing any thoughts on how to fix this? Otherwise, we can maybe stick to EasyMock 3.6 for now.

@henri-tremblay
Copy link
Contributor

That would be sad sad sad. I can have a look but in a couple of days.

@thekingn0thing
Copy link
Member

thekingn0thing commented Oct 31, 2018 via email

@ijuma
Copy link
Contributor Author

ijuma commented Nov 3, 2018

javassist 3.24.0-GA has been released, but using that results in more test failures:

AnnotationUsageTest. annotationsAreEnabledWhenUsingTheJUnitRule[0]
AnnotationUsageTest. annotationsAreEnabledWhenUsingTheJUnitRule[1]
LargeMethodTest. largeMethodShouldBeAbleToBeMocked
LargeMethodTest. largeMethodShouldBeAbleToBeMockedAndThrowException
LargeMethodTest. largeMethodShouldBeAbleToBeSuppressed
LargeMethodTest. largeMethodShouldBeOverridden

The new failures are not particularly informative:

java.lang.NoClassDefFoundError: Could not initialize class org.powermock.api.easymock.EasyMockConfiguration
	at org.powermock.api.extension.listener.AnnotationEnabler.beforeTestMethod(AnnotationEnabler.java:62)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.powermock.reflect.internal.WhiteboxImpl.performMethodInvocation(WhiteboxImpl.java:1854)
	at org.powermock.reflect.internal.WhiteboxImpl.invokeMethod(WhiteboxImpl.java:706)
	at org.powermock.reflect.Whitebox.invokeMethod(Whitebox.java:415)
	at org.powermock.modules.junit4.rule.PowerMockStatement.injectMocksUsingAnnotationEnabler(PowerMockRule.java:125)
	at org.powermock.modules.junit4.rule.PowerMockStatement.evaluate(PowerMockRule.java:71)

@henri-tremblay
Copy link
Contributor

henri-tremblay commented Nov 4, 2018 via email

@thekingn0thing
Copy link
Member

@henri-tremblay, you may use /gradlew idea to generate idea files and the open in IDE.

@thekingn0thing
Copy link
Member

As I see, the tests are falling only in case if PowerMock uses in agent mode. In addition, the tests are falling randomly when different EasyMock methods are called.

This root cause of the java.lang.NoClassDefFoundError is that org.powermock.api.easymock.EasyMockConfiguration has static initilization where EasyMockSupport class is loaded.

java.lang.NoClassDefFoundError: Could not initialize class org.powermock.api.easymock.EasyMockConfiguration

@ijuma
Copy link
Contributor Author

ijuma commented Nov 4, 2018

The errors above were with Java 8. I had tried Java 11 first and got the activation issue too. I pushed the javassist upgrade to check what happens in CI.

@thekingn0thing
Copy link
Member

Interesting moment, that PowerMock should not modify EasyMock classes, but only load them with ucstom class loader. This logic is hardcoded in PowerMockClassLoader.

@ijuma
Copy link
Contributor Author

ijuma commented Nov 4, 2018

CI after the javassist upgrade:

6 tests completed, 6 failed
Finished generating test XML results (0.016 secs) into: /home/travis/build/powermock/powermock/tests/easymock/junit4-agent/build/test-results/test
Generating HTML test report...
Finished generating test html results (0.006 secs) into: /home/travis/build/powermock/powermock/tests/easymock/junit4-agent/build/reports/tests/test
:tests:easymock:junit4-agent:test (Thread[main,5,main]) completed. Took 5.307 secs.

@thekingn0thing
Copy link
Member

I thinking about ignoring agent's tests and create an issue to investigate what the difference between agent and class loader ways bytecode transformation.

@ijuma
Copy link
Contributor Author

ijuma commented Nov 4, 2018

@thekingnothing When is agent mode used?

@ijuma
Copy link
Contributor Author

ijuma commented Nov 4, 2018

@thekingnothing I pushed a commit that ignores the agent tests that were failing.

@thekingn0thing
Copy link
Member

thekingn0thing commented Nov 4, 2018 via email

@thekingn0thing thekingn0thing merged commit aab8813 into powermock:release/2.x Nov 7, 2018
@ijuma
Copy link
Contributor Author

ijuma commented Nov 10, 2018

Thanks for the 2.0.0 RC3 release. Kafka has been updated to use it along with EasyMock 4.0.1:

apache/kafka#5846

@thekingn0thing
Copy link
Member

Thanks for your pull request.

thekingn0thing pushed a commit that referenced this pull request Mar 30, 2020
When using the powermock-module-junit4-rule-agent there are java.lang.VerifyErrors.
For example if you have some project with Spock 1.0 and use use the rule, it works just fine.
As soon as you upgrade to 1.2 or 1.3 which dropped Java 6 support, you get various of these verify errors.

They are all about "Expected stackmap frame at this location.".

I'm no Byte Buddy expert, but from what I have read, the combination of ClassWriter.COMPUTE_MAXS with ClassReader.SKIP_FRAMES is not the best idea.
ClassReader.SKIP_FRAMES will skip reading and visiting stack maps and stack map tables.
The JavaDoc of that attribute says it is for example useful if you use ClassWriter.COMPUTE_FRAMES as it recalculates the stackmap frames anyway, so there is no need to parse and visit them.
But like it is currently, they are neither parsed, nor visited, nor computed and thus they are missing when verifying.

As far as I understood there are two ways to handle this, either use ClassWriter.COMPUTE_FRAMES and ClassReader.SKIP_FRAMES,
as then the frames are not parsed or visited, but recalculated, or do not use both as they are then parsed, visited and in
the case of this visitor just copied.

As the visitor only removes the final modifiers for methods and classes now, I renamed it,
disabled even the MAXS computation and disabled the frame skipping.

From my test it seems to work better with this setting now and also all your tests are green
(except three tests that are red for me even without my changes).

Fixes #1005
Probably fixes #956, #1024, #926, #549, #558, #873, #693, #543

Update: also re-enabled the tests that were disabled due to this error in #952
I think the exclusion of TestNG classes in commit e948b49 was also due to this error and could probably be reverted.

Work-around: Use JVM option -noverify to disable the verification that complains about the missing stackmap frames.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants