Joseph D. Darcy's Sun Weblog

Joseph D. Darcy's Sun Weblog


20090727 Monday July 27, 2009

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
(2009-07-27 11:27:01.0) Permalink Comments [7]

20090721 Tuesday July 21, 2009

Pick a path, any path

As heard at JavaOne this year, classpath is dead, being killed by the modularity features in JDK 7, JSR 294 and Project Jigsaw.

Today the full logical classpath available to an application or used in javac is actually a twisty little maze of concatenated sub-paths, starting with the bootclasspath, followed by the extension directories, and finally the classpath setting itself. The endorsed standards override mechanism is used to selectively update various components logically included on the bootclasspath as part of the JDK, either components for standards that evolve outside of the JCP, like Corba, or standalone JSRs also shipped with the JDK, like JAX-WS. The extension mechanism can be used to support technologies not shipped with the JDK, such as an independent JSR or even a site-wide library.

The table below shows the different command line options to java and javac that can be used to configure the sub-paths. These options have evolved over time. The bootclasspath and extension directories were added in JDK 1.2, the ability to prepend to the bootclasspath was added in JDK 1.3, endorsed standards were added in JDK 1.4, JDK 5 harmonized the path options on the java and javac command lines, and JDK 6 allowed classpath wildcards, but only for the strict classpath component and not for bootclasspath or the Class-Path Jar manifest attribute. Check the documentation for the JDK release in question for matching configuration information.

There is certainly plenty of opportunity for modularity in JDK 7 to simplify the configuration options needed to resolve dependencies!

Path Setting in java and javac
bootclasspath/p: Endorsed standards bootclasspath[/a:] Extension Directories classpath
java options -Xbootclasspath/p: -Djava.endorsed.dirs= -Xbootclasspath:
-Xbootclasspath:/a
-Djava.ext.dirs= -cp
-classpath
$CLASSPATH
javac options -Xbootclasspath/p: -Djava.endorsed.dirs= -bootclasspath
-Xbootclasspath:
-Xbootclasspath:/a
-extdirs
-Djava.ext.dirs=
-cp
-classpath
$CLASSPATH
Classloaders
bootstrap
extension
application

(2009-07-21 17:58:59.0) Permalink Comments [9]

20090716 Thursday July 16, 2009

Project Coin: Literal Grammar Hackery

Correction: External to this blog, it was been pointed out to me that the original grammar disallowed two-digit numbers, which is unintended. The fix is to make the DigitsAndUnderscores component in Digit DigitsAndUnderscores Digit optional, as done in the corrected grammar below

Circling back to look at some unresolved technical details of the underscores in numbers proposal, I wrote up a combined grammar to allow binary literals as well as underscores as separators between digits. That is, underscores cannot appear as the first or last character in a sequence of digits.

The basic grammar change is to convert the definition of Digits (in any base) from the simple left recursive list of digits found in JLSv3, like

Digits:
Digit
Digits Digit

to a list where underscores can appear between numbers but the list must start and end with a digit:

Digits:
Digit
Digit DigitsAndUnderscoresopt Digit
DigitsAndUnderscores:
DigitOrUnderscore
DigitsAndUnderscores DigitOrUnderscore

This grammar is unambiguous, but as written it requires a look ahead of more than 1 because the recursion is in the middle of the Digits production. I have not attempted any of the usual grammar refactorings to restore a look ahead of 1 since in practice purging the underscores will be implemented by a small amount of additional logic in the scanner as opposed to the actual parsing machinery.

The existing rules for distinguishing decimal and octal literals cause minor grammar complications to accommodate underscores immediately after the first digit. Octal numbers must start with a leading zero digit and nonzero decimal numbers must start with a nonzero digit, requirements reflected in rules like NonZeroDigit Digitsopt. To allow underscores after the first digit, a new rule requiring at least one underscore is added, such as NonZeroDigit Underscores Digits. The structure of binary literals is straightforward and entirely analogous to hexadecimal ones. Changing the digit-level productions automatically allows underscores in floating-point literals without the need to explicitly update the rules for those literals.

Productions in blue below are additional or changed productions to existing non-terminals; the other non-terminals below are newly introduced to support the enhanced literal syntax.

IntegerLiteral:
DecimalIntegerLiteral
HexIntegerLiteral
OctalIntegerLiteral
BinaryIntegerLiteral
BinaryIntegerLiteral:
BinaryNumeral IntegerTypeSuffixopt
BinaryNumeral:
0 b BinaryDigits
0 B BinaryDigits
DecimalNumeral:
0
NonZeroDigit Digitsopt
NonZeroDigit Underscores Digits
Underscores:
_
Underscores _
Digits:
Digit
Digit DigitsAndUnderscoresopt Digit
DigitsAndUnderscores:
DigitOrUnderscore
DigitsAndUnderscores DigitOrUnderscore
DigitOrUnderscore:
Digit
_
HexDigits:
HexDigit
HexDigit HexDigitsAndUnderscoresopt HexDigit
HexDigitsAndUnderscores:
HexDigitOrUnderscore
HexDigitsAndUnderscores HexDigitOrUnderscore
HexDigitOrUnderscore:
HexDigit
_
OctalNumeral:
0 OctalDigits
0 Underscores OctalDigits
OctalDigits:
OctalDigit
OctalDigit OctalDigitsAndUnderscoresopt OctalDigit
OctalDigitsAndUnderscores:
OctalDigitOrUnderscore
OctalDigitsAndUnderscores OctalDigitOrUnderscore
OctalDigitOrUnderscore:
OctalDigit
_
BinaryDigits:
BinaryDigit
BinaryDigit BinaryDigitsAndUnderscoresopt BinaryDigit
BinaryDigitsAndUnderscores:
BinaryDigitOrUnderscore
BinaryDigitsAndUnderscores BinaryDigitOrUnderscore
BinaryDigitOrUnderscore:
BinaryDigit
_
BinaryDigit: one of
0 1
(2009-07-16 16:28:41.0) Permalink Comments [2]

20090714 Tuesday July 14, 2009

Deprecation in the JDK

A quick note on the deprecation policy used in the JDK, a question which comes up from time to time. The general policy for several feature releases is that core JDK components are only marked as deprecated if they are actively harmful. If using a class or method is just ill-advised, that is usually not sufficient to earn the deprecated mark.

The platform javadoc falls short of deprecating, but does discourage the use of certain API elements, from particular methods, like the no-arg Boolean constructor, to entire classes, like Vector and Hashtable. At some point, this kind of advice might be formalized with a less-harmful-than-deprecated "denigration" facility based a combination of javadoc tags and annotations to allow programmatic checks be made for usage of these less harmful API elements too (4941777, 6583872).

When an API element is deprecated, the recommended practice is to both apply the @Deprecated annotation as well as use the "@deprecated" javadoc tag. Using the annotation places more of the semantics of the code in the source code proper as opposed to a comment while using the javadoc tag allows alternate functionality to be recommended along with the specification for the element.

(2009-07-14 16:23:30.0) Permalink Comments [7]

Calendar

« July 2009 »
SunMonTueWedThuFriSat
   
1
2
3
4
5
6
7
8
9
10
11
12
13
15
17
18
19
20
22
23
24
25
26
28
29
30
31
 
       
Today

RSS Feeds

XML
All
/Annotation Processing
/General
/Java
/JavaOne
/Numerics
/OpenJDK

Search

Links

    Blogroll
  • Download the JRE

    News

Navigation



Referers

Today's Page Hits: 1382