Skip to content
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

Use Lookup class loading strategy if available #895

Merged

Conversation

marcphilipp
Copy link
Member

In order to create mock objects on Java 11, ProxyBasedMockFactory now uses ByteBuddy's Lookup-based ClassLoadingStrategy, if available.

Resolves #843.

In order to create mock objects on Java 11, `ProxyBasedMockFactory`
now uses ByteBuddy's `Lookup`-based `ClassLoadingStrategy`, if
available.

Resolves #843.
@marcphilipp marcphilipp self-assigned this Sep 7, 2018
* Serves as a reference point for method handle based class loading and is makes the containing package
* non-empty so generated classes can be legally defined inside of it.
*/
public class CodegenDummy {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd call it CodegenTarget

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fine with me. 👍

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about just Target?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also ok

@@ -89,6 +93,9 @@ private Object createDynamicProxyMock(Class<?> mockType, List<Class<?>> addition

private static final TypeCache<TypeCache.SimpleKey> CACHE =
new TypeCache.WithInlineExpunction<>(TypeCache.Sort.SOFT);
private static final Random RANDOM = new Random();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm Random is not thread-safe IIRC that about ThreadLocalRandom?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instances of java.util.Random are threadsafe. However, the concurrent use of the same java.util.Random instance across threads may encounter contention and consequent poor performance. Consider instead using java.util.concurrent.ThreadLocalRandom in multithreaded designs.

So it's thread-safe but may have poor performance... I'll change it to ThreadLocalRandom.

if (ClassInjector.UsingReflection.isAvailable()) {
return ClassLoadingStrategy.Default.INJECTION;
}
throw new IllegalStateException("No class loading strategy available");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we fall back to WRAPPER

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In which cases would that get used?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If a pre Java-9 JVM does not support Unsafe but I would not know any.

@leonard84
Copy link
Member

The code should include a notice of origin pointing to Mockito

What about the classloader check https://github.com/mockito/mockito/blob/4f72147c464c1a8a642d01fc3334e98e92b464cd/src/main/java/org/mockito/internal/creation/bytebuddy/SubclassInjectionLoader.java#L75 don't we need this also?

@leonard84
Copy link
Member

@raphw maybe you could also take a look

@codecov
Copy link

codecov bot commented Sep 7, 2018

Codecov Report

Merging #895 into master will decrease coverage by 0.03%.
The diff coverage is 72.41%.

Impacted file tree graph

@@             Coverage Diff              @@
##             master     #895      +/-   ##
============================================
- Coverage     75.05%   75.02%   -0.04%     
+ Complexity     3427     3426       -1     
============================================
  Files           368      368              
  Lines         10552    10579      +27     
  Branches       1333     1342       +9     
============================================
+ Hits           7920     7937      +17     
- Misses         2165     2168       +3     
- Partials        467      474       +7
Impacted Files Coverage Δ Complexity Δ
...kframework/mock/runtime/ProxyBasedMockFactory.java 84.46% <72.41%> (-5.01%) 6 <0> (ø)
...ckframework/spring/mock/DelegatingInterceptor.java 52.5% <0%> (-5%) 6% <0%> (-1%)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 8478419...9c92669. Read the comment docs.

@raphw
Copy link
Contributor

raphw commented Sep 7, 2018

Mockito sometimes creates class loaders if a mock is loaded by a class loader that cannot see Mockito. This is a problem especially in OSGi environments, therefore the indirection and the check.

@raphw
Copy link
Contributor

raphw commented Sep 7, 2018

Looks good otherwise!

@marcphilipp
Copy link
Member Author

@leonard84 PTAL! 🙂

@leonard84 leonard84 merged commit a463f1b into spockframework:master Sep 9, 2018
MartyIX referenced this pull request in MartyIX/spock Oct 14, 2018
In order to create mock objects on Java 11+, `ProxyBasedMockFactory`
now uses ByteBuddy's `Lookup`-based `ClassLoadingStrategy`, if
`Reflection` strategy is not available.

Resolves #843
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.

None yet

3 participants