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
Fix incremental compilation with JDK16 using toolchains #16066
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. The one workaround with the --add-opens
is fine but it would be good to look into my comment and see if we can continue without it
@@ -349,6 +353,10 @@ private DefaultJavaCompileSpec createBaseSpec() { | |||
private void applyToolchain(ForkOptions forkOptions) { | |||
final JavaInstallationMetadata metadata = getToolchain(); | |||
forkOptions.setJavaHome(metadata.getInstallationPath().getAsFile()); | |||
if (isToolchainCompatibleWithJava16()) { | |||
// used by the incremental compiler plugin, see org.gradle.internal.compiler.java.ClassNameCollector | |||
forkOptions.getJvmArgs().addAll(Arrays.asList("--add-opens", "jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I might be worthing looking to actually fixing this without the add opens. I pushed a small WIP here that I played around with, we might not need this workaround for this. WDYT?
So that they are compatible with Java 8. On Java 8, calling ((JavacTask) delegate).getElements() in the IncrementalCompileTask of the incremental compiler plugin, somehow makes the the deprecation messages print the class names with their fully qualified names, in this case - com.example.Foo.
@@ -68,7 +68,7 @@ public void setLocale(Locale locale) { | |||
@Override | |||
public Boolean call() { | |||
if (delegate instanceof JavacTask) { | |||
ClassNameCollector collector = new ClassNameCollector(relativize); | |||
ClassNameCollector collector = new ClassNameCollector(relativize, ((JavacTask) delegate).getElements()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calling javacTask.getElements()
here has a rather weird side effect on deprecation messages in Java 8 - see this commit: b04b5ab
Not sure if there can be more implications here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the side effect is not too bad but would be good to capture in the tests instead of ignoring it. Initially, I thought they dropped the class name completely which is not great.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And would be nice to pull the cast out as we do the same cast in the next line. Time to switch to Java 14 with pattern matching :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder also if the instanceof-or-throw
can be pulled out to the constructor so that the delegate
field is always a JavacTask
here. Let's see what CI thinks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor nits and some questions. Generally good to go. Let me know if I should review the remaining changes
if (symbol.endsWith("module-info")) { | ||
symbol = "module-info"; | ||
} else if (typeElement.getNestingKind().isNested()) { | ||
symbol = elements.getBinaryName(typeElement).toString(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice
@@ -68,7 +68,7 @@ public void setLocale(Locale locale) { | |||
@Override | |||
public Boolean call() { | |||
if (delegate instanceof JavacTask) { | |||
ClassNameCollector collector = new ClassNameCollector(relativize); | |||
ClassNameCollector collector = new ClassNameCollector(relativize, ((JavacTask) delegate).getElements()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the side effect is not too bad but would be good to capture in the tests instead of ignoring it. Initially, I thought they dropped the class name completely which is not great.
@@ -68,7 +68,7 @@ public void setLocale(Locale locale) { | |||
@Override | |||
public Boolean call() { | |||
if (delegate instanceof JavacTask) { | |||
ClassNameCollector collector = new ClassNameCollector(relativize); | |||
ClassNameCollector collector = new ClassNameCollector(relativize, ((JavacTask) delegate).getElements()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And would be nice to pull the cast out as we do the same cast in the next line. Time to switch to Java 14 with pattern matching :)
|
||
} | ||
|
||
def "can compile Java using different JDKs"() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe use #javaVersion
to see which iterations are skipped?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We get this information without explicitly embedding the variable in the test header (since Spock 2 I believe): https://ge.gradle.org/s/vhyeam6vqgtqi/tests
}; | ||
} | ||
} | ||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need to check for anonymous classes using method-level nested classes?
class Anonymous2 {
SomeInterface getAnonymous() {
class Foobar implements SomeInterface {
}
return new Foobar() {
public int foo() {
return 42;
}
};
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, for our use case, do lambdas behave the same as anonymous classes for this use case?
Is this maybe possible to backport to 6.x? |
#15538