An apt replacement

Showing that no rule is so broad as to not admit an exception, the apt tool and its associated API, com.sun.mirror.\*, are being deprecated in JDK 7. The plan is to remove the tool and its API to the next major JDK release after JDK 7.

As a com.sun.\* API, the apt API is not governed by the JCP; however, we don't usually mass-deprecate com.sun.\* APIs either. We introduced apt in JDK 5 to gain experience with annotation processing before standardizing this facility with JSR 269 in JDK 6, which added the javax.annotation.processing and javax.lang.model.\* packages and added annotation processing options to javac.

As the lead engineer for both apt and JSR 269, the JSR 269 API and tool experience should be uniformly better than apt; the newer API is easier to use, more flexible, and should run faster as well. I unconditionally recommend transitioning to the JSR 269 API and javac (or its compiler API) for all your annotation processing needs.

The table below summarizes the apt deprecation information.

Summary of deprecated apt API replacements
apt type Standard Replacement
Package com.sun.mirror.apt
AnnotationProcessor javax.annotation.processing.Processor
AnnotationProcessorEnvironment javax.annotation.processing.ProcessingEnvironment
AnnotationProcessorFactory javax.annotation.processing.Processor
AnnotationProcessorListener No analog.
AnnotationProcessors No analog.
Filer javax.annotation.processing.Filer
Filer.Location javax.tools.StandardLocation
Messager javax.annotation.processing.Messager
RoundCompleteEvent No analog.
RoundCompleteListener No analog.
RoundState javax.annotation.processing.RoundEnvironment
Package com.sun.mirror.declaration
AnnotationMirror javax.lang.model.element.AnnotationMirror
AnnotationTypeDeclaration javax.lang.model.element.TypeElement
AnnotationTypeElementDeclaration javax.lang.model.element.ExecutableElement
AnnotationValue javax.lang.model.element.AnnotationValue
ClassDeclaration javax.lang.model.element.TypeElement
ConstructorDeclaration javax.lang.model.element.ExecutableElement
Declaration javax.lang.model.element.Element
EnumConstantDeclaration javax.lang.model.element.VariableElement
EnumDeclaration javax.lang.model.element.TypeElement
ExecutableDeclaration javax.lang.model.element.ExecutableElement
FieldDeclaration javax.lang.model.element.VariableElement
InterfaceDeclaration javax.lang.model.element.TypeElement
MemberDeclaration javax.lang.model.element.Element
MethodDeclaration javax.lang.model.element.ExecutableElement
Modifier javax.lang.model.element.Modifier
PackageDeclaration javax.lang.model.element.PackageElement
ParameterDeclaration javax.lang.model.element.VariableElement
TypeDeclaration javax.lang.model.element.TypeElement
TypeParameterDeclaration javax.lang.model.element.TypeParameterElement
Package com.sun.mirror.type
AnnotationType javax.lang.model.type.DeclaredType
ArrayType javax.lang.model.type.ArrayType
ClassType javax.lang.model.type.DeclaredType
DeclaredType javax.lang.model.type.DeclaredType
EnumType javax.lang.model.type.DeclaredType
InterfaceType javax.lang.model.type.DeclaredType
MirroredTypeException javax.lang.model.type.MirroredTypeException
MirroredTypesException javax.lang.model.type.MirroredTypesException
PrimitiveType javax.lang.model.type.PrimitiveType
PrimitiveType.Kind javax.lang.model.type.TypeKind
ReferenceType javax.lang.model.type.ReferenceType
TypeMirror javax.lang.model.type.TypeMirror
TypeVariable javax.lang.model.type.TypeVariable
VoidType javax.lang.model.type.NoType
WildcardType javax.lang.model.type.WildcardType
Package com.sun.mirror.util
DeclarationFilter javax.lang.model.util.ElementFilter
DeclarationScanner javax.lang.model.util.ElementScanner6
DeclarationVisitor javax.lang.model.element.ElementVisitor
DeclarationVisitors No replacement.
Declarations javax.lang.model.util.Elements
SimpleDeclarationVisitor javax.lang.model.util.SimpleElementVisitor6
SimpleTypeVisitor javax.lang.model.util.SimpleTypeVisitor6
SourceOrderDeclScanner javax.lang.model.util.SimpleElementVisitor6
SourcePosition No replacement.
TypeVisitor javax.lang.model.element.TypeVisitor
Types javax.lang.model.util.Types
Comments:

Good riddance! Too bad apt was not deprecated in Java SE 6 so we could totally kill it now.

Suggestion: unbundle this turd from the JDK now, keeping it available as a separate download -- with "unsupported" status and deprecation tags -- for people who need it. There is no reason that stuff that's (a) deprecated, (b) planned for total elimination in next release, should be conveniently bundled in the JDK.

JSR-269 has been available for 2.5 years since Java SE 6 so you must assume that only the most lazy or conservative users are still depending on apt; some people follow too hard the "if it ain't broken, don't fix it" rule. These are exactly the users who will typically ignore deprecation warnings, and they will be still using apt when JDK 8 ships completely without apt.

You do a favor to these laggards to make a bit harder to use apt with JDK 7; with unbundling, they will see their builds breaking and be forced to download and install apt separately. This should be enough "writing on the wall" to make people migrate faster.

Remember that the Java platform has a long tradition of never removing any legacy feature, we have all garbage deprecated in JDK1.1 and up still in the latest version. So many developers get used to simply ignore deprecation in core libs.

Posted by Osvaldo Pinali Doederlein on July 27, 2009 at 05:31 AM PDT #

I'm currently using apt for its SourcePosition information, which isn't available in JSR 269. Too bad for me!

In spite of that, I think this is the right move.

Posted by Jesse Wilson on July 28, 2009 at 05:47 AM PDT #

Jesse,

The Tree API of JDK6 provides a much richer API for getting source positions. The API focuses on character offsets in files, rather than lines and columns which simply doesn't provide a good canonical representation.

However, it is a little expensive for the compiler to account for all the source positions, so we didn't make them first class citizens in the API. Here is a collection of all the relevant API:

http://java.sun.com/javase/6/docs/technotes/guides/javac/index.html

The first thing you need to do is get an instance of Trees using this method: http://java.sun.com/javase/6/docs/jdk/api/javac/tree/com/sun/source/util/Trees.html#instance(javax.annotation.processing.ProcessingEnvironment)

Now that you have this instance, grab an instance of the sources positions utility using getSourcePositions().
Use the Trees instance to get the path of an element using getPath().

From the path you can get the compilation unit and leaf node. Use them to get a start or end position from the SourcePositions instance. These positions are character offsets from the beginning of a file, you can convert them to lines and columns using the line map of the compilation unit.

I know this is a complex API compared to com.sun.mirror, but we felt it was important to be able to expose the underlying representation inside javac directly without building heavy wrapper objects thus sacrificing speed and memory footprint. We hope the exposed API is flexible enough to not constrain future optimizations of javac. I think you will find that annotation processing inside javac is much faster than apt. All the element, type, and tree objects that you get are the objects used directly inside javac, not costly wrapper objects with slightly out-of-sync semantics.

Cheers,
Peter

Posted by Peter von der Ahé on July 29, 2009 at 04:54 PM PDT #

@Jesse and @Peter,

Within the apt API, source positions are only consumed by the Messager. Because of that, in JSR 269 we just pass elements in question to the Messager to allow the source position to be implicitly reconstructed.

If you need the source positions for some other purpose, Peter's suggestion of using the tree API is the right approach.

Posted by Joe Darcy on July 30, 2009 at 12:13 AM PDT #

Joe,

I thought the replacements you listed are already available in Java 6? At least I can't find javax.annotation.processing.ProcessingEnvironment for example. I have to migrate an apt based model driven development approach and would appreciate any hints to good documentation, tutorials, migration guides ...

Cheers,
Roger

Posted by Roger Wegner on August 26, 2009 at 11:57 PM PDT #

@Roger,

Yes, all the replacements are available as of JDK 6; the type in question is documented at
http://java.sun.com/javase/6/docs/api/javax/annotation/processing/ProcessingEnvironment.html

See slides 56 and 57 of the 2006 JavaOne talk
"Annotation Processing With JSR 269,"
by Joseph D. Darcy, Scott Seligman, Jess Garms, Bruce Chapman
to get an overview of some of the fundamental changes between apt the the JSR 269-based annotation processing in javac.

Posted by Joe Darcy on August 27, 2009 at 01:22 AM PDT #

@Joe,

sorry! It was right before my eyes!

Cheers,
Roger

Posted by Roger Wegner on August 27, 2009 at 02:26 AM PDT #

Post a Comment:
Comments are closed for this entry.
About

darcy

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today
News

No bookmarks in folder

Blogroll