Hi!
The @Generated annotation causes some troubles with JPMS.
History on @Generated
Originally, it was designed to show static code analyzers which classes to ignore. Nowadays, they will usually look for .gitignored files or something line target/generated-* or any @*Generated annotation. So that's that.
Why it is a problem with JPMS
I do not want code which uses my record builders to require the java.compiler module -- it is not needed, because none of that code would read the @Generated annotation. So, instead of using requires java.compiler;, the correct approach is requires static java.compiler -- which translates to "only use this module for compiling".
However, the compiler is a bit dumb, sees the @Generated annotation and complains that it will be there on the .class file -- which it will be not, because it does not know about annotations and their @RetentionPolicy, so it assumes it will be there.
This will yield the following compiler warning:
[WARNING] /path/to/my/target/generated-sources/annotations/MyRecordBuilder.java:[217,6] class javax.annotation.processing.Generated in module java.compiler is not indirectly exported using 'requires transitive'
Alternatives
1.: Do not generate @Generated at all
An option with all its drawbacks
2.: Only add @Generated if it is in the classpath
mapstruct uses this approach
3.: let the user decide (boolean)
Booleans are meh. Use an enum.
4. let the user decide (enum)
-AgeneratedAnnotation = enum AddGeneratedAnnotation { ON, OFF, USER_SUPPLIED, IF_ON_CLASSPATH }
Default: IF_ON_CLASSPATH
When USER_SUPPLIED is set, the user would also need to specify -AgeneratedUserAnnotation=com.my.project.MyProjectGenerated or so.
names are not meant to be final. Let some native speaker pick something better :)
Hi!
The
@Generatedannotation causes some troubles with JPMS.History on
@GeneratedOriginally, it was designed to show static code analyzers which classes to ignore. Nowadays, they will usually look for
.gitignored files or something linetarget/generated-*or any@*Generatedannotation. So that's that.Why it is a problem with JPMS
I do not want code which uses my record builders to require the
java.compilermodule -- it is not needed, because none of that code would read the@Generatedannotation. So, instead of usingrequires java.compiler;, the correct approach isrequires static java.compiler-- which translates to "only use this module for compiling".However, the compiler is a bit dumb, sees the
@Generatedannotation and complains that it will be there on the.classfile -- which it will be not, because it does not know about annotations and their@RetentionPolicy, so it assumes it will be there.This will yield the following compiler warning:
Alternatives
1.: Do not generate
@Generatedat allAn option with all its drawbacks
2.: Only add
@Generatedif it is in the classpathmapstruct uses this approach
3.: let the user decide (boolean)
Booleans are meh. Use an enum.
4. let the user decide (enum)
-AgeneratedAnnotation=enum AddGeneratedAnnotation { ON, OFF, USER_SUPPLIED, IF_ON_CLASSPATH }Default:
IF_ON_CLASSPATHWhen
USER_SUPPLIEDis set, the user would also need to specify-AgeneratedUserAnnotation=com.my.project.MyProjectGeneratedor so.names are not meant to be final. Let some native speaker pick something better :)