Description
This is about getting an error like the following when compiling with a module-info.java
and the compiler flags -Xlint:all
and -Werror
:
> Compilation failed; see the compiler output below.
log4j-api-2.24.3.jar(/org/apache/logging/log4j/message/ParameterizedMessage.class): warning: Cannot find annotation method 'replacement()' in type 'InlineMe': class file for com.google.errorprone.annotations.InlineMe not found
log4j-api-2.24.3.jar(/org/apache/logging/log4j/message/ParameterizedMessage.class): warning: Cannot find annotation method 'imports()' in type 'InlineMe'
log4j-api-2.24.3.jar(/org/apache/logging/log4j/status/StatusData.class): warning: Cannot find annotation method 'value()' in type 'SuppressFBWarnings': class file for edu.umd.cs.findbugs.annotations.SuppressFBWarnings not found
log4j-api-2.24.3.jar(/org/apache/logging/log4j/status/StatusData.class): warning: Cannot find annotation method 'justification()' in type 'SuppressFBWarnings'
log4j-api-2.24.3.jar(/org/apache/logging/log4j/util/SystemPropertiesPropertySource.class): warning: Cannot find annotation method 'value()' in type 'ServiceProvider': class file for aQute.bnd.annotation.spi.ServiceProvider not found
log4j-api-2.24.3.jar(/org/apache/logging/log4j/util/SystemPropertiesPropertySource.class): warning: Cannot find annotation method 'resolution()' in type 'ServiceProvider'
log4j-api-2.24.3.jar(/org/apache/logging/log4j/util/Activator.class): warning: Cannot find annotation method 'value()' in type 'Headers': class file for org.osgi.annotation.bundle.Headers not found
log4j-api-2.24.3.jar(/org/apache/logging/log4j/util/Activator.class): warning: Cannot find annotation method 'name()' in type 'Header': class file for org.osgi.annotation.bundle.Header not found
log4j-api-2.24.3.jar(/org/apache/logging/log4j/util/Activator.class): warning: Cannot find annotation method 'value()' in type 'Header'
log4j-api-2.24.3.jar(/org/apache/logging/log4j/util/Activator.class): warning: Cannot find annotation method 'name()' in type 'Header'
log4j-api-2.24.3.jar(/org/apache/logging/log4j/util/Activator.class): warning: Cannot find annotation method 'value()' in type 'Header'
error: warnings found and -Werror specified
1 error
11 warnings
The error is triggered by using classes from Log4j that use annotations on public members from the annotation libraries indicated in the error message. There are two layers of missing dependencies that cause this:
- The annotation library's Jar file (e.g.
com.google.errorprone:error_prone_annotations:2.36.0
) is not on the Classpath/Module Path - The annotation library's Java Module (e.g.
com.google.errorprone.annotations
) is not defined asrequire static
in the correspondingmodule-info.class
of Log4j
For (1) it's debatable if it can be fixed in a good way, as POM does not have a scope that resembles Gradle's compileOnlyApi scope: visible transitively but ONLY on the compile classpath.
For (2) you can argue that it is a bug, because if the code of Log4j would be compiled on the Module Path (i.e. with the compiler checking the module-info.java
) it would not compile.
Workarounds for users
(1)
- Adding the missing dependencies directly as
compileOnly
(<provided>
) to your own project. - Patching the POM metadata with a rule (possible in Gradle)
(2)
- Calling the compiler with additional
--add-reads
arguments - Patching the
module-info.class
itself (possible in Gradle with plugin)
This is a minimal example showing all the annotation libraries that need to be "patched in":
https://github.com/jjohannes/gradle-demos/blob/main/log4j-metadata/build.gradle.kts
Possible improvements in Log4j
(1) This was already discussed here. The dependencies marked as <provided>
here would need to be switched to <compile>
. But that has the unwanted effect that ALL users will get them as unnecessary RUNTIME dependencies.
There is the option to publish additional Gradle Metadata that supports the compileOnlyApi
scope. If you are interested, I can make a contribution for that as I maintain the Maven plugin for publishing such metadata with Maven (it's used by Jackson for example). But I can understand if you don't want to have additional complexity in your build setup.
(2) Maybe you can check if the additional requires could be added to all module-info
:
requires static transitive com.google.errorprone.annotations;
requires static transitive com.github.spotbugs.annotations;
requires static transitive biz.aQute.bnd.annotation;
requires static transitive org.osgi.annotation.bundle;
*requires static
works also, but conceptually requires static transitive
feels more correct as the annotations are transitively visible.
All of this can also be avoided by turning of the classfiles
line check of javac
...
I can understand if there is nothing you can/want to do at this point. Then, feel free to close this issue.
Having this written down can be helpful for users who run into this in any case.
If you want to do something I can help with, let me know.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status