AnnotationClaim is a simple annotation processor for the Java compiler,
which simply "claims" whichever annotations you specify. This makes it
possible to avoid the javac
Xlint warning: No processor claimed any of these annotations: org.example.Annotation
when using javac's -Xlint
option
together with (a) other annotation processors and (b) other "runtime" annotations.
This is useful if you are trying to eliminate all compiler warnings, at least until https://bugs.openjdk.java.net/browse/JDK-6999068 is fixed.
Specify the annotation option org.zanata.annotationclaim.annotations
with a
list of annotation names you want to claim. For instance:
javac Example.java -processorpath annotationclaim.jar \
-Aorg.zanata.annotationclaim.annotations=org.junit.runner.RunWith,org.junit.Test
If you are using Maven or Gradle to compile, you may wish to use a project property to hold the list of annotations. You can separate multiple annotations with commas or whitespace characters, including newlines.
You can also specify the additional annotation org.zanata.annotationclaim.verbose=true
to enable more logging. Note that this may trigger a minor but annoying
warning bug in the compiler: https://bugs.openjdk.java.net/browse/JDK-8162455
AnnotationClaim will tell javac
to send it whichever annotations you tell
it. When javac
comes across one of these annotations, it will pass it to
AnnotationClaim, and AnnotationClaim will report to javac
that the annotation
has been claimed, ie processed. This will prevent the annotation from being
seen by any other annotation processor, so make sure the annotation is not
needed by your other annotation processors before telling AnnotationClaim to
claim it. As long as every annotation has been claimed by an annotation
processor, you should avoid the Xlint warning No processor claimed any of these annotations: org.example.Annotation
.
You have to list all of the runtime annotations for which you want to suppress
the warning, and there are often a lot of them. It would be better if you
could just list the small number of annotations which your other annotation
processors want to use at compile time, but this would require AnnotationClaim
to declare support for wildcard annotations, javac
would pass all
annotations on a code element to AnnotationClaim, and then AnnotationClaim
could (a) claim them all (thus preventing other processors from working) or
(b) not claim them all (thus failing to prevent the "No processor claimed..."
warning).
Hard-coding a list of "runtime" annotations into AnnotationClaim would reduce
the need for large lists, but would increase the maintenance burden of
AnnotationClaim, and also increase the likelihood of blocking an important
annotation. For instance, the annotation javax.annotation.Nullable
is
typically not used by any compile-time annotation processor, but this is not
true for projects which use the Checker Framework's Nullness Checker.
When javac
outputs a warning for one or more new runtime annotations -
warning: No processor claimed any of these annotations: org.example.Annotation1,org.example.Annotation2
- you can just add the listed annotations to the
org.zanata.annotationclaim.annotations
parameter. But before you do, please make sure the annotations don't belong to a new annotation processor which you forgot to activate, or you will stop that other annotation processor from doing its job.
# Compiling with an annotation processor, but without activating the AnnotationClaim processor:
$ javac src/main/java/org/zanata/annotationclaim/AnnotationClaim.java \
-Xlint -processorpath ~/.m2/repository/org/projectlombok/lombok/1.16.6/lombok-1.16.6.jar
warning: No processor claimed any of these annotations: javax.annotation.processing.SupportedOptions
1 warning
$
# With the AnnotationClaim processor activated:
$ javac src/main/java/org/zanata/annotationclaim/AnnotationClaim.java \
-Xlint -processorpath ~/.m2/repository/org/projectlombok/lombok/1.16.6/lombok-1.16.6.jar:build/libs/annotationclaim-1.0-SNAPSHOT.jar \
-Aorg.zanata.annotationclaim.annotations=javax.annotation.processing.SupportedOptions
$
See https://bugs.openjdk.java.net/browse/JDK-6999068 for more details about the javac warning.
Note that this does not work reliably for multi-module projects - for some reason takari-lifecycle-plugin seems to leave annotation processors like AnnotationClaim off the classpath when doing recursive builds.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
...
<properties>
<annotationclaim.annotations>
com.google.common.annotations.Beta
com.google.common.annotations.VisibleForTesting
com.google.gwt.user.client.rpc.RemoteServiceRelativePath
com.google.gwtmockito.GwtMock
com.tngtech.java.junit.dataprovider.DataProvider
com.tngtech.java.junit.dataprovider.UseDataProvider
edu.umd.cs.findbugs.annotations.SuppressFBWarnings
java.beans.ConstructorProperties
java.lang.FunctionalInterface
javax.annotation.CheckForNull
javax.annotation.Nonnull
javax.annotation.Nullable
javax.annotation.ParametersAreNonnullByDefault
javax.annotation.PostConstruct
javax.annotation.PreDestroy
javax.annotation.Priority
javax.annotation.Resource
javax.ejb.MessageDriven
javax.enterprise.context.ApplicationScoped
javax.enterprise.context.Dependent
javax.enterprise.context.RequestScoped
javax.enterprise.context.SessionScoped
javax.enterprise.event.Observes
javax.enterprise.inject.Alternative
javax.enterprise.inject.Any
javax.enterprise.inject.Default
javax.enterprise.inject.Disposes
javax.enterprise.inject.Model
javax.enterprise.inject.Produces
javax.enterprise.inject.Stereotype
javax.enterprise.util.Nonbinding
javax.faces.application.ResourceDependencies
javax.faces.bean.ViewScoped
javax.faces.component.FacesComponent
javax.faces.render.FacesRenderer
javax.inject.Inject
javax.inject.Named
javax.inject.Qualifier
javax.interceptor.AroundInvoke
javax.interceptor.Interceptor
javax.interceptor.InterceptorBinding
javax.persistence.Access
javax.persistence.Basic
javax.persistence.Cacheable
javax.persistence.Column
javax.persistence.DiscriminatorColumn
javax.persistence.DiscriminatorValue
javax.persistence.ElementCollection
javax.persistence.Embeddable
javax.persistence.EmbeddedId
javax.persistence.Entity
javax.persistence.EntityListeners
javax.persistence.Enumerated
javax.persistence.GeneratedValue
javax.persistence.Id
javax.persistence.IdClass
javax.persistence.Inheritance
javax.persistence.JoinColumn
javax.persistence.JoinTable
javax.persistence.Lob
javax.persistence.ManyToMany
javax.persistence.ManyToOne
javax.persistence.MapKey
javax.persistence.MapKeyColumn
javax.persistence.MapKeyEnumerated
javax.persistence.MapKeyJoinColumn
javax.persistence.MappedSuperclass
javax.persistence.NamedQueries
javax.persistence.OneToMany
javax.persistence.OneToOne
javax.persistence.OrderBy
javax.persistence.OrderColumn
javax.persistence.PersistenceUnit
javax.persistence.PostLoad
javax.persistence.PostPersist
javax.persistence.PostUpdate
javax.persistence.PrePersist
javax.persistence.PreRemove
javax.persistence.PreUpdate
javax.persistence.Table
javax.persistence.Temporal
javax.persistence.Transient
javax.persistence.Version
javax.servlet.annotation.WebFilter
javax.servlet.annotation.WebServlet
javax.validation.Constraint
javax.validation.constraints.NotNull
javax.validation.constraints.Pattern
javax.validation.constraints.Size
javax.ws.rs.ApplicationPath
javax.ws.rs.ConstrainedTo
javax.ws.rs.Consumes
javax.ws.rs.DELETE
javax.ws.rs.DefaultValue
javax.ws.rs.GET
javax.ws.rs.HeaderParam
javax.ws.rs.POST
javax.ws.rs.PUT
javax.ws.rs.Path
javax.ws.rs.PathParam
javax.ws.rs.Produces
javax.ws.rs.QueryParam
javax.ws.rs.container.PreMatching
javax.ws.rs.core.Context
javax.ws.rs.ext.Provider
javax.xml.bind.annotation.XmlAttribute
javax.xml.bind.annotation.XmlElement
javax.xml.bind.annotation.XmlElementRef
javax.xml.bind.annotation.XmlRootElement
javax.xml.bind.annotation.XmlType
org.apache.deltaspike.core.api.common.DeltaSpike
org.apache.deltaspike.core.api.exception.control.ExceptionHandler
org.apache.deltaspike.core.api.exception.control.Handles
org.apache.deltaspike.core.api.exclude.Exclude
org.apache.deltaspike.core.api.lifecycle.Destroyed
org.apache.deltaspike.core.api.lifecycle.Initialized
org.apache.deltaspike.core.api.scope.ConversationGroup
org.apache.deltaspike.core.api.scope.GroupedConversationScoped
org.apache.deltaspike.core.api.scope.WindowScoped
org.apache.deltaspike.jpa.api.transaction.Transactional
org.apache.deltaspike.jsf.api.listener.phase.JsfPhaseListener
org.apache.deltaspike.scheduler.api.Scheduled
org.apache.deltaspike.security.api.authorization.Secured
org.apache.deltaspike.security.api.authorization.Secures
org.apache.deltaspike.security.api.authorization.SecurityBindingType
org.codehaus.jackson.annotate.JsonIgnore
org.codehaus.jackson.annotate.JsonIgnoreProperties
org.codehaus.jackson.annotate.JsonProperty
org.codehaus.jackson.annotate.JsonPropertyOrder
org.codehaus.jackson.map.annotate.JsonSerialize
org.hibernate.annotations.AttributeAccessor
org.hibernate.annotations.BatchSize
org.hibernate.annotations.Cache
org.hibernate.annotations.Immutable
org.hibernate.annotations.ListIndexBase
org.hibernate.annotations.NaturalId
org.hibernate.annotations.Type
org.hibernate.annotations.TypeDef
org.hibernate.annotations.TypeDefs
org.hibernate.annotations.Where
org.hibernate.search.annotations.AnalyzerDefs
org.hibernate.search.annotations.AnalyzerDiscriminator
org.hibernate.search.annotations.ClassBridge
org.hibernate.search.annotations.Factory
org.hibernate.search.annotations.Field
org.hibernate.search.annotations.FieldBridge
org.hibernate.search.annotations.FullTextFilterDef
org.hibernate.search.annotations.Indexed
org.hibernate.search.annotations.IndexedEmbedded
org.hibernate.search.annotations.SortableField
org.hibernate.validator.constraints.Email
org.hibernate.validator.constraints.NotEmpty
org.jboss.arquillian.container.test.api.Deployment
org.jboss.arquillian.container.test.api.RunAsClient
org.jboss.arquillian.core.api.annotation.Inject
org.jboss.arquillian.core.api.annotation.Observes
org.jboss.arquillian.test.api.ArquillianResource
org.jboss.arquillian.test.spi.annotation.ClassScoped
org.jboss.arquillian.test.spi.annotation.TestScoped
org.jboss.resteasy.annotations.providers.jaxb.Wrapped
org.jboss.resteasy.annotations.providers.multipart.MultipartForm
org.jglue.cdiunit.AdditionalClasses
org.jglue.cdiunit.AdditionalClasspaths
org.jglue.cdiunit.InRequestScope
org.jglue.cdiunit.InSessionScope
org.jglue.cdiunit.ProducerConfig
org.jglue.cdiunit.ProducesAlternative
org.jglue.cdiunit.deltaspike.SupportDeltaspikeCore
org.junit.After
org.junit.AfterClass
org.junit.Before
org.junit.BeforeClass
org.junit.ClassRule
org.junit.Ignore
org.junit.Rule
org.junit.Test
org.junit.experimental.categories.Categories.IncludeCategory
org.junit.experimental.categories.Category
org.junit.runner.RunWith
org.junit.runners.Parameterized.Parameter
org.junit.runners.Parameterized.Parameters
org.junit.runners.Parameterized.UseParametersRunnerFactory
org.junit.runners.Suite.SuiteClasses
org.mockito.Captor
org.mockito.Mock
org.ocpsoft.rewrite.annotation.RewriteConfiguration
</annotationclaim.annotations>
</properties>
<build>
<plugins>
<plugin>
<groupId>io.takari.maven.plugins</groupId>
<artifactId>takari-lifecycle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<annotationProcessorOptions>
<org.zanata.annotationclaim.annotations>${annotationclaim.annotations}</org.zanata.annotationclaim.annotations>
</annotationProcessorOptions>
<proc>proc</proc>
</configuration>
<dependencies>
<dependency>
<groupId>org.zanata</groupId>
<artifactId>annotationclaim</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
...
</project>