Documented method of using Wrapper types fails with Java 17 library target
See original GitHub issueI have created a minimal reproduction of this issue here:
https://github.com/mglazer/repro-javaseventeen-immutables
The crux of the issue, is that when using Java 17 as a library target, if you have a Wrapper type, using:
@Value.Style(
typeAbstract = "*Wrapper",
typeImmutable = "*",
visibility = Value.Style.ImplementationVisibility.PUBLIC,
defaults = @Value.Immutable(builder = false, copy = false))
public @interface Wrapped {}
and:
import com.fasterxml.jackson.annotation.JsonValue;
import org.immutables.value.Value;
public abstract class Wrapper<T> {
@JsonValue
@Value.Parameter
abstract T value();
@Override
public final String toString() {
return value().toString();
}
}
And then attempt to use that construction, only with Java 17 will you get compilation errors:
> Task :repro-javaseventeen-immutables-core:compileJava FAILED
Round 1:
input files: {com.palantir.reprojavaseventeenimmutables.UseRepro, com.palantir.reprojavaseventeenimmutables.Wrapper, com.palantir.reprojavaseventeenimmutables.Wrapped, com.palantir.reprojavaseventeenimmutables.ReproIssueWrapper}
annotations: [org.immutables.value.Value.Immutable, com.fasterxml.jackson.annotation.JsonValue, org.immutables.value.Value.Parameter, java.lang.Override, org.immutables.value.Value.Style, com.palantir.reprojavaseventeenimmutables.Wrapped]
last round: false
Processor org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor matches [/org.immutables.value.Value.Immutable] and returns false.
Processor org.gradle.api.internal.tasks.compile.processing.SupportedOptionsCollectingProcessor matches [/com.palantir.reprojavaseventeenimmutables.Wrapped, /com.fasterxml.jackson.annotation.JsonValue, java.base/java.lang.Override, /org.immutables.value.Value.Immutable, /org.immutables.value.Value.Parameter, /org.immutables.value.Value.Style] and returns false.
warning: Was unable to read source file for com.palantir.reprojavaseventeenimmutables.UseRepro[com.sun.tools.javac.code.Symbol$ClassSymbol.class]: java.io.FileNotFoundException: com/palantir/reprojavaseventeenimmutables/UseRepro.java
Round 2:
input files: {com.palantir.reprojavaseventeenimmutables.ImmutableUseRepro, com.palantir.reprojavaseventeenimmutables.ReproIssue}
annotations: [org.immutables.value.Generated, java.lang.SuppressWarnings, javax.annotation.ParametersAreNonnullByDefault, javax.annotation.processing.Generated, javax.annotation.concurrent.Immutable, javax.annotation.CheckReturnValue, javax.annotation.concurrent.NotThreadSafe, javax.annotation.Nullable, com.google.errorprone.annotations.CanIgnoreReturnValue, java.lang.Override]
last round: false
warning: Was unable to read source file for com.palantir.reprojavaseventeenimmutables.UseRepro[com.sun.tools.javac.code.Symbol$ClassSymbol.class]: java.io.FileNotFoundException: com/palantir/reprojavaseventeenimmutables/UseRepro.java
Processor org.gradle.api.internal.tasks.compile.processing.TimeTrackingProcessor matches [] and returns false.
Processor org.gradle.api.internal.tasks.compile.processing.SupportedOptionsCollectingProcessor matches [/javax.annotation.concurrent.NotThreadSafe, /javax.annotation.Nullable, /com.google.errorprone.annotations.CanIgnoreReturnValue, /javax.annotation.CheckReturnValue, java.compiler/javax.annotation.processing.Generated, /javax.annotation.concurrent.Immutable, /org.immutables.value.Generated, java.base/java.lang.SuppressWarnings, java.base/java.lang.Override, /javax.annotation.ParametersAreNonnullByDefault] and returns false.
Round 3:
input files: {}
annotations: []
last round: true
error: warnings found and -Werror specified
1 error
1 warning
error: warnings found and -Werror specified
The most noticeable error which occurs when verbose processor logging is disabled is the:
warning: Was unable to read source file for com.palantir.reprojavaseventeenimmutables.UseRepro[com.sun.tools.javac.code.Symbol$ClassSymbol.class]: java.io.FileNotFoundException: com/palantir/reprojavaseventeenimmutables/UseRepro.java
Otherwise, I have been unable to find anything that sticks out from the compilation messages.
I have attempted this with both Immutables 2.8.8 and 2.9.0 and it reproduces on both.
Issue Analytics
- State:
- Created a year ago
- Reactions:3
- Comments:16 (5 by maintainers)
Top Results From Across the Web
java.util (Java SE 17 & JDK 17) - Oracle Help Center
A Red-Black tree based NavigableMap implementation. A NavigableSet implementation based on a TreeMap . Unchecked exception thrown when an unknown conversion is ...
Read more >Building Java & JVM projects - Gradle User Manual
Gradle uses a convention-over-configuration approach to building JVM-based projects that borrows several conventions from Apache Maven.
Read more >Java project in Eclipse: The type java.lang.Object cannot be ...
The solution I found was to remove the project from Eclipse (not from disk), remove the project's Eclipse files from the disk, and...
Read more >Building a Native Executable - Quarkus
This means that you may see the following error when using gu : ... the application code, required libraries, Java APIs, and a...
Read more >Spring Boot Reference Documentation
You can use Spring Boot in the same way as any standard Java library. To do so, include the appropriate spring-boot-*.jar files on...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Oh gosh, I see the difference between the command-line and javac cases: running within idea, we’re missing some exports that are necessary for immutables, so despite both using javac, running within idea uses the SourceExtractor.DefaultExtractor while on the command line we get the SourceExtractor.JavacSourceExtractor` due to:
Why does this only occur in the IDE? A gradle plugin in my default template uses error-prone static analysis, which requires some compiler exports to function, which allow the SourceExtractor code to work correctly in jdk-17. 🌶️ The plugin doesn’t apply error-prone when it detects intellij for historical reasons 🌶️
I’ve pushed a commit to my repro which opts out of error-prone, allowing a repro from the command line. I suspect we may want to bring back the compiler warning where we can recommend adding exports to support the annotation processor.
The using
TwoTuple
is a key difference. When compilingOne {... TwoTuple issue()
, the class/interfaceTwoTuple
is known to compiler, it knows the package it comes from, full name/path etc. In the generated code all imports are processed properly. But when usingOne {... Two issue()
, the compiler says to us (to Immutables processor), “— look, here’s some broken and not available type called Two, I wash my hands”, then processor says to itself, “— Oki-doki, we’ll use this type anyway in case it will be generated, but if it comes from another package we’re busted, only if there would be source code available, we could try to parse imports from there…”, and the annotation processor uses ~dark magic~ javac/ecj specific ways to access the underlying source code and if it succeeds and founds import from another package forTwo
it will put such an import into generated file, but if it’s not – then type nameTwo
copied into the generated code as is (if it’s happens to be generated in the same package – that will work, but will fail for another package).