X

Musings on JDK development

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

Join the discussion

Comments ( 7 )
  • Osvaldo Pinali Doederlein Monday, July 27, 2009

    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.


  • Jesse Wilson Tuesday, July 28, 2009

    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.


  • Peter von der Ahé Wednesday, July 29, 2009

    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


  • Joe Darcy Thursday, July 30, 2009

    @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.


  • Roger Wegner Thursday, August 27, 2009

    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


  • Joe Darcy Thursday, August 27, 2009

    @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.


  • Roger Wegner Thursday, August 27, 2009

    @Joe,

    sorry! It was right before my eyes!

    Cheers,

    Roger


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.Captcha
Oracle

Integrated Cloud Applications & Platform Services