WIP: Add support for java 9#1393
Conversation
291e67d to
03417ca
Compare
velo
left a comment
There was a problem hiding this comment.
Having two copies of the sources is not an option... as nobody should be expected to patch two locations every time something changes.
Why do we need that?
| - test: | ||
| jdk: '14-buster' | ||
| jdk: 'circleci/openjdk:14-buster' | ||
| name: 'jdk 14' |
There was a problem hiding this comment.
I think as we add jdk 16 "support" we could drop 14.
There was a problem hiding this comment.
I have an uncommitted change for this, moving to cimg/openjdk:16.0.0 (since that's where circleci appears to be migrating its images to).
Honestly just so I could get to fixing the tests. I'll be rewriting history to remove all the duplicate classes that are unnecessary when I can get maven to stop complaining. |
03417ca to
88b07ca
Compare
|
Unit tests are run via the compile output classpath, not via jar as per the maven lifecycle meaning the 'Multi-Release JAR Files' can't be used in tests. (As the multi-release jar doesn't exist until the package goal has run). That means we can't run java 16 unit-tests against this project, since java 16 doesn't like this code. (That's not entirely the truth, we could add |
|
Not sure yet how to handle the jdk8 builds. They don't like the |
|
Looks like the build file currently releases most jars under java 8, and one jar under java 11. Wonder if it would be ok to move all the jars under 11, then use the |
| * method must be called on the result before invoke is called. | ||
| */ | ||
| @IgnoreJRERequirement | ||
| final class DefaultMethodHandler implements MethodHandler { |
There was a problem hiding this comment.
Maybe we could add to https://github.com/OpenFeign/feign/tree/master/java11
I read mixed reviews of multi release support
There was a problem hiding this comment.
Multi release has pretty sparse documentation from what I've found. It seems strange that there's no built-in functionality that would let your run unit-tests against the multi-release classes. The support for running tests against jars only exists in the failsafe plugin.
It might be possible to make a ServiceLocator that can load the different MethodHandlers, but that seems like a lot of complexity to add when using multi-release jars feels like it was built for exactly this purpose.
There was a problem hiding this comment.
Yeah, having that on the java11 module instead, would lead to much better testability as well.
There was a problem hiding this comment.
At least according to the gradle team, they don't recommend multi release jars according to this blog post. On the other hand, there's just one class that needs to be updated for java 9+, and we don't need a new api surface to support it, or jdk11 variant jars either. (The java 11 module looks like it just adds support for the new httpclient, and doesn't replace any existing functionality.)
There was a problem hiding this comment.
Yeah, right now, java11 module only contain an http2 client. But nothing prevent from adding a new package with a better MethodHandler implementation.
Does java16 work at all with existing DefaultMethodHandler?
There was a problem hiding this comment.
As you are finding out, trying to use the multi-release concept, even in theory, is difficult and wrought with drawbacks. We strive to keep complexity to a minimum. The simple if/else suggestion solves the problem without requiring us to support a multi-release infrastructure. This same advice is echoed by the Maven team themselves.
Libraries should make a decision based on: do I need this new Java feature? Can I make this Java version the new requirement? Would it be acceptable to solve this with an else/if-statement as mentioned in the first paragraph?
Given this change is isolated to the DefaultMethodHandler, I'd like to keep the changes small, even if we have, what amounts to a temporary if statement.
There was a problem hiding this comment.
Are you thinking of maybe there being a class in the java11 package, similar to my branch above, but instead of going around with a full serviceloader and whatnot we instead use a Class.forName("DefaultMEthodHandlerJava11") and then fall back to 8 if unavailable? I don't exactly see the 'if/else statement' as being necessarily easier or less complex, it just shifts where the complexity is.
Have you looked at the other prototype branch above? It's not quite as simple as an if statement, but the locator nonesense could be removed in favor of something simpler. Would still require the java11 jar though.
There was a problem hiding this comment.
I made an alternative change, with DefaultMethodHandler configurable
#1394
What do you thing of it?!
There was a problem hiding this comment.
My only issue (which is specific to where I work) is for the most part clients ship their own instantiation of the Feign.builder() call, so end-users would have no ability to alter what method handler to use, making this not a viable solution.
EDIT: Might be specific to my work. Might also be rough for people who are supplied pre-existing clients, or where feign is an implementation concern, and not exposed as part of the api.
There was a problem hiding this comment.
Also thinking about this further, this doesn't seem something pluggable in the same way jackson or the network library is imo, this is just about 'use this for one version of the jdk, this other thing for another version of the jdk'
| public DefaultMethodHandler(Method defaultMethod) { | ||
| try { | ||
| final Class<?> declaringClass = defaultMethod.getDeclaringClass(); | ||
| final Lookup lookup = MethodHandles.privateLookupIn(declaringClass, MethodHandles.lookup()); |
There was a problem hiding this comment.
I think I have a solution for this...
can we just use reflection on the existing DefaultMethodHandler?
We just need try to invoke the new API using reflection, if that fail, fallback to existing code
There was a problem hiding this comment.
Will create a pr for this tonight
There was a problem hiding this comment.
I just did, had some time allocated at work to be around feign =)
There was a problem hiding this comment.
The changes look good! Really like the use of deny to get java 11 to help test this change.
| <groupId>org.apache.maven.plugins</groupId> | ||
| <artifactId>maven-surefire-plugin</artifactId> | ||
| <configuration> | ||
| <argLine>--illegal-access=deny</argLine> |
|
💯 |
* Add support for java 9 * Move multi-release to java 9 only * Have a single DefaultMethodHandle for java 8 and 11 that don't print warnings * Bump spring version Co-authored-by: Clayton Walker <cwalker@sofi.org> Co-authored-by: Marvin Froeder <marvin.froeder@dovetailstudios.com>
* Add support for java 9 * Move multi-release to java 9 only * Have a single DefaultMethodHandle for java 8 and 11 that don't print warnings * Bump spring version Co-authored-by: Clayton Walker <cwalker@sofi.org> Co-authored-by: Marvin Froeder <marvin.froeder@dovetailstudios.com>
Attempt at fixing #935 via velo#4 and using multi-release jars.