X

Musings on JDK development

Recent Posts

Java

Advice on removing javac lint warnings

Over the last twelve months or so, one of my projects has been fixing and reviewing fixes of javac lint warnings in the JDK 9 code base (varargs, fallthrough, serial,finally,overrides,deprecation,raw and unchecked) and once a warning category is cleared, making new instances of that category a fatal build error.Ultimately, all the warnings in the jdk repository were resolved and -Xlint:all -Werror is now used in the build.Being involved in fixing several thousand warnings, I'd like to share some tips for developers who want to undertake an analogous task of cleaning up the technical debt of javac lint warnings in their own code base.First, I recommend tackling the warnings in a way that aligns well with the build system of the project, with a consideration of getting some code protected by the compiler from some warning categories as soon as possible.While the build of the JDK has been re-engineered over the course of the warnings cleanup, to a first approximation the build has been organized around Hg repositories. (At present, in JDK 9 the build is actually arranged around modules. A few years ago, the build was organized around Java packages rather than repositories.)A warnings cleanup isn't really done until introducing new instances of the warning cause a build failure; new warnings are too easy to ignore otherwise.Therefore, for JDK 9, the effort was organized around clearing the whole jdk repository of a warning category and then enabling that warning category in the build as opposed to, say, completely clearing a particular package of all warnings and then moving to the next package.There are two basic approaches to resolving a warning: suppressing it using the @SuppressWarnings mechanism or actually fixing the code triggering the warning.The first approach is certainly more expedient. While it doesn't directly improve the code base, it can offer an indirect benefit of creating a situation where new warnings can be kept out of the code base by allowing a warning to be turned on in the build sooner.The different warning categories span a range of severity levels and while some warnings are fairly innocuous, others are suspicious enough that I'd recommend always fixing them if a fix is feasible.When resolving warnings in the JDK, generally the non-deprecation warnings categories were fixed while the deprecation warnings were suppressed with a follow-up bug filed. The non-deprecation warnings mostly require Java language expertise to resolve and little area expertise; deprecation warnings are the reverse, often quite deep area expertise is needed to develop and evaluate a true fix.Tips on addressing specific categories of lint warnings:[cast]: Warn about use of unnecessary casts.Since these warnings are generated entirely from the the contents of method bodies, there is no impact to potential callers of the code. Also, the casts analyzed as redundant by javac are easy and safe to remove; fixing cast warnings is essentially a zero-risk change.[fallthrough]: Warn about falling through from one case of a switch statement to the next.When such a falling through is not intentional, it can be a very serious bug. All fallthrough switch cases should be examined for correctness.An idiomatic and intentional fallthrough should have two parts: first, the cases in question should be documented in comments explaining that the fallthrough is expected and second, an @SuppressWarnings({"fallthrough"}) annotation should be added to the method containing the switch statement.See also the discussion of switch statements in Java Puzzlers, Puzzler 23: No Pain, No Gain.[static]: Warn about accessing a static member using an instance.This is an unnecessary and misleading coding idiom that should be unconditionally removed. The fix is to simply refer to the static member using the name of the type rather than an instance of the type.This coding anti-pattern is discussed in Java Puzzlers, Puzzle 48: All I Get Is Static.[dep-ann]: Warn about items marked as deprecated in JavaDoc but not using the @Deprecated annotationSince Java SE 5.0, the way to mark an element as deprecated is to modify it with a @Deprecated annotation. While a @deprecated javadoc tag should be used to describe all @Deprecated elements, the javadoc tag is informative only and does not mean the element is treated as deprecated by the compiler.A element should have an @deprecated javadoc tag in its javadoc if and only if the element is @Deprecated.Therefore, the fix should be to either remove the @deprecated javadoc tag if the element should not be deprecated or add the @Deprecated annotation if it should be deprecated.[serial]: Warn about Serializable classes that do not provide a serialVersionUID.Serialization is a subtle and complex protocol whose compatibility impact on evolving a type should not be underestimated.To check for compatibility between the reader of serial stream data and the writer of the data, besides matching the names of the reader and writer, identification codes of the reader and the writer are also compared and the serial operation fails if the codes don't match.When present, a serialVersionUID field of a class stores the identification code, called a Stream Unique Identifier (SUID) in serialization parlance. When a serialVersionUID field is not present, a particular hashing algorithm is used to compute the SUID instead. The hash algorithm is perturbed by many innocuous changes to a class and can therefore improperly indicate a serial incompatibility when no such incompatibility really exists.To avoid this hazard, a serialVersionUID field should be present on all Serializable classes following the usual cross-version serialization contracts, including Serializable abstract superclasses.If a Serializable class without a serialVersionUID has already been shipped in a release, running the serialver tool on the type in the shipped release will return the serialVersionUID declaration needed to maintain serial compatibility.For further discussion, see Effective Java, 2nd Edition, Item 74: Implement Serializable judiciously.[overrides]: Warn about issues regarding method overrides.As explained in Effective Java, 2nd Edition, Item 9: Always Override hashCode when you override equals, for objects to behave properly when used in collections, they must have correct equals and hashCode implementations.The invariant checked by javac is more nuanced than the one discussed in Effective Java; javac checks that if a class overrides equals, hashCode has been overriden somewhere in the superclass class chain of the class.It is common for a set of related classes to be able to share a hashCode implementation, say a function of a private field in the root superclass in a set of related types. However, each class will still need to have its own equals method for the usual instanceof check on the argument to equals.[deprecation]: Warn about use of deprecated items.Well documented @Deprecated elements suggest a non-deprecated replacement.When using a replacement is not feasible, or no such replacement exists, @SuppressWarnings("deprecation") can be used to acknowledge the situation and remove the warning.A small language change made in JDK 9 makes suppressing deprecation warnings tractable.[rawtypes]: Warn about use of raw types.[unchecked]: Warn about unchecked operations. Both rawtypes and unchecked warnings are linked to the same underlying cause: incomplete generification of APIs and their implementations.Generics shipped in 2004 as part of Java SE 5.0; Java code written and used today should be generics aware!Being generics-aware has two parts, using generics properly in the signature / declaration of a method, constructor, or class and using generics properly in method and constructor bodies.Many uses of generics are straightforward; if you have a list that only contains strings, it should probably be declared as a List<String>. However, some uses of generics can be subtle and are out of scope for this blog entry. However, extensive guides are available with detailed advice.IDEs also provide refactorings for generics; check their documentation for details.I hope these tips help you make your own Java project warnings-free.

Over the last twelve months or so, one of my projects has been fixing and reviewing fixes of javac lint warnings in the JDK 9 code base (varargs,fallthrough,serial,finally,overrides,deprecation,raw and...

Annotation Processing

JSR 269 Maintenance Review for Java SE 8

The annotation processing API, both the processor-specific portion of the API in javax.annotation.processing and the language modeling portions in javax.lang.model.*, are being updated to support the new language features in Java SE 8.Procedurally, the proposed changes are covered by the second maintenance review of JSR 269: Maintenance Draft Review 2.As summarized on on the maintenance review page, there are three categories of changes from the version of the API shipped with Java SE 7: Cleaning up the existing specification without changing its semantics (adding missing javadoc tags, etc.)API changes to support the language changes being made in Project Lambda /JSR 335.These includes adding javax.lang.model.type.IntersectionType as well as javax.lang.model.element.ExecutableElement.isDefault.API changes to support the language changes being made under JSR 308, Annotations on Java Types. These include javax.lang.model.AnnotatedConstruct and updating javax.annotation.processing.Processor. The small repeating annotations language change, discussed on an OpenJDK alias, is also supported by the proposed changes.A detailed specification difference is available. Please post any comments here or send them to me through email.

The annotation processing API, both the processor-specific portion of the API in javax.annotation.processing and the language modeling portions in javax.lang.model.*, are being updated to support the...

Annotation Processing

javax.lang.model backed by core reflection

Back when the javax.lang.model API was being designed as part of JSR 269, while the API was primarily intended for use at compile-time with annotation processing, the expert group also wanted the API to be usable in other contexts as well, including at runtime.JEP 119, javax.lang.model Implementation Backed by Core Reflection, proposed adding such an alternative runtime implementation of javax.lang.model to JDK 8. Such an implementation has recently been pushed as sample code in the JDK 8 langtools repository.At a high level, the sample code is at its core repeated uses of the adapter pattern, translating between the core reflection API and the javax.lang.model API.However, there were a number of design issues in what interface the javax.lang.model implementation for core reflection should expose.First, should a core reflection specialization of javax.lang.model expose a more specific interface? There are some advantages to just implementing the base API defined in the existing interfaces; it is the simplest approach and would appear to maximize the ability to inter-operate with other implementations. However, javax.lang.model depends on hidden state to define concepts like equality, so there is intrinsically limited inter-operation between disjoint implementations. Therefore, especially in sample code, it was viewed as worthwhile to experiment with a more specific API in the core reflection case.To make the javax.lang.model backed by core reflection more specific, for each FooElement interface in javax.lang.model.element, a ReflectionFooElement subinterface was defined, as shown in the diagram below.The subinterfaces are specialized in a few ways: If a method in the base interface was defined to return a FooElement, a covariant override in the subinteface was defined to return a ReflectionFooElement.If a method in the base interface was defined to return a List< ? extends FooElement>, a covariant override in the subinteface was defined to return a List<ReflectionFooElement>.For getBar(FooElement arg) methods defined in the Elements helper interface, add a getBar() method to the ReflectionFooElement subinterface.Add a getSource method to the root ReflectionElement interface to return the underlying core reflection object being adapted and add covariant overrides in subinterfaces as appropriate.The root ReflectionElement interface implements the full AnnotatedElement interface, not just the subset of its methods found in the base javax.lang.model.element.A cost of specializing the API is the need to define a new visitor interface as well. Covariant overrides cannot be used as in the element modeling interfaces since the visitor methods take elements in the argument position rather than the return position.Generally, working on the core reflection specialization proceeded as expected.Equality determinations were generally delegated to core reflection source object; in other words, two ReflectionElement objects are equal if they are instances of the same interface and if their sources are .equals.Writing the sample code highlighted several shortcomings of the core reflection API which have been addressed in Java SE 8, including the addition of an Executable type to abstract over the commonalities of Method and Constructor.The sample code also benefited from other reflection changes in Java SE 8, such as the introduction of a java.lang.reflect.Parameter class and retrofitting TypeVariable to extend AnnotatedElement.While significantly more testing would be needed to productize javax.lang.model backed by core reflection, even as sample code it validates a number of the technological decisions made in JSR 269 and is an interesting demonstration of how one of the platform's reflective APIs can be bridged to another.

Back when the javax.lang.model API was being designed as part of JSR 269, while the API was primarily intended for use at compile-time with annotation processing, the expert group also wanted the API...

Java

Changing Sources and Moving Targets: Evolving the javac command line

As written up in JEP 182: Policy for Retiring javac -source and -target Options, we're implementing a policy to over time clean up the -source and -target portions of javacs command line:Class files going all the way back to version 45.3 generated by JDK 1.0.2 will continue to be recognized by javac when put on the classpath, etc.The never-documented -target options 1.4.1, 1.4.2, and jsr14 have been removed in JDK 8 (8010179).In JDK 8, source and target options for 1.5 and below will be deprecated and a warning will be printed on their use (8011043).In JDK 9, source and target options for 1.5 and below will be removed (8011044).Starting in JDK 9, a "one plus three back" policy will apply to source and target options. JDK 9 will support (9/1.9, 8/1.8, 7/1.7, 6/1.6) and JDK 10 will support (10/1.10, 9/1.9, 8/1.8, 7/1.7) and so on.Removing support for the old options will ease compiler maintenance in several ways. First, there will be direct benefits from allowing some code to be deleted. Nixing jsr14 allowed about 250 lines of code to be excised. Second, fewer interactions between new language features and old source levels need to be handled in the compiler. The Java Language Specification only deals with a single version of the language and there is no formal specification of many aspects of how a Java compiler is supposed to behave. To use a recent example, there is no specification for how a new-in-8 default method being introduced to the language and core libraries by Project Lambda should appear to code being compiled under, say, -source 6. Limiting the span of source and target version supported reduces the need to define such cross-version interactions. (The practical impact of source cross-version interfaces would be greatly reduced if developers more often follwed the recommended practice of setting the bootclasspath when cross-compiling to an older platform version.)This policy will help balance stability versus progress and should cover releases having public updates when a new JDK is released.

As written up inJEP 182: Policy for Retiring javac -source and -target Options, we're implementing a policy to over time clean up the -source and -target portions of javacs command line: Class files...

Java

Functional Interfaces

As part of Project Lambda, after discussion with the JSR 335 expert group, we decided to add a FunctionalInterface annotation type to the platform.To a first approximation, functional interfaces are those interface types which define only a single method and are therefore usable in lambda expressions.(There are some tricky details in the definition of a functional interface relating to generics and also some details about excluding from consideration methods defined on java.lang.Object.)The new annotation type allows a library designer to clearly indicate the property of intending an interface type to be used with lambda expressions along with an implied commitment to keep that property true in the future.However, the compiler will allow any interface type meeting the structural properties of a functional interface to be used for a lambda expression regardless of whether or not the interface has a @FunctionalInterface annotation.They types being added in the java.util.function package are by design functional interfaces and can be annotated with @FunctionalInterface from early days.However, many existing Java SE types are also functional interfaces and we want to identify and annotate those appropriately too.To find those candidate interfaces to be annotated, I ran an annotation processor over the code, using the same methodology as used to find Closeable candidates during JDK 7.A significant number of candidates were found throughout the JDK.After suitable discussion and review, the first batch of core libraries changes have been pushed.Analogous discussions have been started in the2D,awt, andswing areas.For guidance in retrofitting @FunctionalInterface to an existing candidate type, if the type is routinely instantiated using an anonymous class, it is a good candidate for being annotated with @FunctionalInterface.

As part of Project Lambda, after discussion with the JSR 335 expert group, we decided to add a FunctionalInterface annotation type to the platform. To a first approximation, functional interfaces are...

Java

JDK bug migration: components and subcomponents

One subtask of the JDK migration from the legacy bug tracking system to JIRA was reclassifying bugs from a three-level taxonomy in the legacy system, (product, category, subcategory), to a fundamentally two-level scheme in our customized JIRA instance, (component, subcomponent).In the JDK JIRA system, there is technically a third project-levelclassification, but by design a large majority of JDK-related bugswere migrated into a single "JDK" project.In the end, over 450 legacy subcategories were simplified into about120 subcomponents in JIRA. The 120 subcomponents are distributed among 17components. A rule of thumb used was that a subcategory had to have atleast 50 bugs in it for it to be retained.Below is a listing the component / subcomponent classification of theJDK JIRA project along with some notes and guidance on which OpenJDKemail addresses cover different areas.Eventually, a separate incidents project to host new issues filed atbugs.sun.com will use a slightly simplified version of this scheme.The preponderance of bugs and subcomponents for the JDK are inlibrary-related areas, with components named foo-libs andsubcomponents primarily named after packages.While there was an overall condensation of subcomponents in themigration, in some cases long-standing informal divisions in corelibraries based on naming conventions in the description were promotedto formal subcomponents. For example, hundreds of bugs in thejava.util subcomponent whose descriptions started with "(coll)" weremoved into java.util:collections. Likewise, java.lang bugs startingwith "(reflect)" and "(proxy)" were moved into java.lang:reflect.client-libs (Predominantly discussed on2d-dev andawt-dev andswing-dev.)2d demo java.awt java.awt:i18n java.beans(See beans-dev.) javax.accessibility javax.imageio javax.sound(See sound-dev.) javax.swingcore-libs (See core-libs-dev.)java.io java.io:serialization java.lang java.lang.invoke java.lang:class_loading java.lang:reflect java.math java.net java.nio(Discussed on nio-dev.) java.nio.charsets java.rmi java.sql java.sql:bridge java.text java.util java.util.concurrent java.util.jar java.util.logging java.util.regex java.util:collections java.util:i18n javax.annotation.processing javax.lang.model javax.naming (JNDI) javax.script javax.script:javascript javax.sql org.openjdk.jigsaw(See jigsaw-dev.)security-libs (See security-dev.)java.security javax.crypto (JCE: includes SunJCE/MSCAPI/UCRYPTO/ECC) javax.crypto:pkcs11 (JCE: PKCS11 only) javax.net.ssl (JSSE, includes javax.security.cert) javax.security javax.smartcardio javax.xml.crypto org.ietf.jgss org.ietf.jgss:krb5other-libscorba corba:idl corba:orb corba:rmi-iiop javadb other (When no other subcomponent is more appropriate; use judiciously.)Most of the subcomponents in the xml component are related to jaxp.xml jax-ws jaxb javax.xml.parsers (JAXP) javax.xml.stream (JAXP) javax.xml.transform (JAXP) javax.xml.validation (JAXP) javax.xml.xpath (JAXP) jaxp (JAXP) org.w3c.dom (JAXP) org.xml.sax (JAXP)For OpenJDK, most JVM-related bugs are connected to the HotSpot Java virtual machine.hotspot (See hotspot-dev.)build compiler (See hotspot-compiler-dev.) gc (garbage collection, see hotspot-gc-dev.) jfr (Java Flight Recorder)jni (Java Native Interface) jvmti (JVM Tool Interface) mvm (Multi-Tasking Virtual Machine) runtime (See hotspot-runtime-dev.) svc (Servicability) testcore-svc (See serviceability-dev.)debugger java.lang.instrument java.lang.management javax.management toolsThe full JDK bug database contains entries related to legacy virtualmachines that predate HotSpot as well as retired APIs.vm-legacyjit (Sun Exact VM) jit_symantec (Symantec VM, before Exact VM) jvmdi (JVM Debug Interface ) jvmpi (JVM Profiler Interface ) runtime (Exact VM Runtime)Notable command line tools in the $JDK/bin directory have corresponding subcomponents.tools appletviewer apt (See compiler-dev.) hprof jar javac (See compiler-dev.) javadoc(tool) (See compiler-dev.) javah (See compiler-dev.) javap (See compiler-dev.) jconsole launcher updaters (Timezone updaters, etc.) visualvmSome aspects of JDK infrastructure directly affect JDK Hg repositories, but other do not.infrastructurebuild(See build-dev and build-infra-dev.) licensing (Covers updates to the third party readme, licenses, and similar files.) release_eng (Release engineering) staging (Staging of web pages related to JDK releases.)The specification subcomponent encompasses the formal language and virtual machine specifications.specification language (The Java Language Specification) vm (The Java Virtual Machine Specification)The code for the deploy and install areas is not currently included in OpenJDK.deploydeployment_toolkit plugin webstart installauto_update install servicetagsIn the JDK, there are a number of cross-cutting concerns whoseorganization is essentially orthogonal to other areas. Since theseareas generally have dedicated teams working on them, it is easier tofind bugs of interest if these bugs are grouped first by theircross-cutting component rather than by the affected technology.docsdoclet guides hotspot release_notes tools tutorialembeddedbuild hotspot librariesglobalizationlocale-data translation performancehotspot librariesThe list of subcomponents will no doubt grow over time, but my inclination is to resist that growth since the addition of each subcomponent makes the system as a whole more complicated and harder to use.When the system gets closer to being externalized, I plan to post more blog entries describing recommended use of various custom fields in the JDK project.

One subtask of the JDK migration from the legacy bug tracking system to JIRA was reclassifying bugs from a three-level taxonomy in the legacy system, (product, category, subcategory), to...

OpenJDK

JDK bug migration: bugs.sun.com now backed by JIRA

The JDK bug migration from a Sun legacy system to JIRA has reached another planned milestone: the data displayed on bugs.sun.com is now backed by JIRA rather than by the legacy system.Besides maintaining the URLs to old bugs, bugs filed since the migration to JIRA are now visible too.The basic information presented about a bug is the same as before, but reformatted and using JIRA terminology:Instead of a "category", a bug now has a "component / subcomponent" classification. As outlined previously, part of the migration effort was reclassifying bugs according to a new classification scheme; I'll write more about the new scheme in a subsequent blog post.Instead of a list of JDK versions a bug is "reported against," there is a list of "affected versions." The names of the JDK versions have largely been regularized; code names like "tiger" and "mantis" have been replaced by the release numbers like "5.0" and "1.4.2".Instead of "release fixed," there are now "Fixed Versions."The legacy system had many fields that could hold a sequence of text entries, including "Description," "Workaround", and "Evaluation." JIRA instead only has two analogous fields labeled as "Description" and a unified stream of "Comments."Nearly coincident with switching to JIRA, we also enabled an agent which automatically updates a JIRA issue in response to pushes into JDK-related Hg repositories. These comments include the changeset URL, the user making the push, and a time stamp.These comments are first added when a fix is pushed to a team integration repository and then added again when the fix is pushed into the master repository for a release.We're still in early days of production usage of JIRA for JDK bug tracking, but the transition to production went smoothly and over 1,000 new issues have already been filed. Many other facets of the migration are still in the works, including hosting new incidents filed at bugs.sun.com in a tailored incidents project in JIRA.

The JDK bug migration from a Sun legacy system to JIRA has reached another planned milestone: the data displayed on bugs.sun.com is now backed by JIRA rather than by the legacy system.Besides...

Java

JDK bug migration milestone: JIRA now the system of record

I'm pleased to announce the OpenJDK bug database migration project has reached a significant milestone: the JDK has switched from the legacy Sun "bugtraq" system to a new internal JIRA instance as the system of record for our bug tracking.This completes the initial phase of the previously described plan of getting OpenJDK onto an externally visible and writable bug tracker. The identities contained in the current system include recognized OpenJDK contributors.The bug migration effort to date has been sizable in multiple dimensions. There are around 140,000 distinct issues imported into the JDK project of the JIRA instance, nearly 165,000 if backport issues to track multiple-release information are included.Separately, the Code Tools OpenJDK project has its own JIRA project populated with several thousands existing bugs.Once the OpenJDK JIRA instance is externalized, approved OpenJDK projects will be able to request the creation of a JIRA project for issue tracking.There are many differences in the schema used to model bugs between the legacy bug system and the schema for the new JIRA projects.We've favored simplifications to the existing system where possible and, after much discussion, we've settled on five main states for the OpenJDK JIRA projects:NewOpenIn progressResolvedClosedThe Open and In-progress states can have a substate Understanding field set to track whether the issues has its "Cause Known" or "Fix understood". In the closed state, a Verification field can indicate whether a fix has been verified, unverified, or if the fix has failed.At the moment, there will be very little externally visible difference between JIRA for OpenJDK and the legacy system it replaces. One difference is that bug numbers for newly filed issues in the JIRA JDK project will be 8000000 and above. If you are working with JDK Hg repositories, update any local copies of jcheck to the latest version which recognizes this expanded bug range. (The bug numbers of existing issues have been preserved on the import into JIRA). Relatively soon, we plan for the pages published on bugs.sun.com to be generated from information in JIRA rather than in the legacy system.When this occurs, there will be some differences in the page display and the terminology used will be revised to reflect JIRA usage, such as referring to the "component/subcomponent" of an issue rather than its "category".The exact timing of this transition will be announced when it is known.We don't currently have a firm timeline for externalization of the JIRA system. Updates will be provided as they become available.However, that is unlikely to happen before JavaOne next week!

I'm pleased to announce the OpenJDK bug database migration project has reached a significant milestone: the JDK has switched from the legacy Sun "bugtraq" system to a new internal JIRA instance as...

Java

Moving monarchs and dragons: migrating the JDK bugs to JIRA

Among insects, monarch butterflies and dragonflies have the longest migrations; migrating JDK bugs involves a long journey as well! As previously announced by Mark back in March, we've been working according to a revised plan to transition the JDK bug management from Sun's legacy system to initially an Oracle-internal JIRA instance which is afterward made visible and usable externally. I've been busily working on this project for the last few months and the team has made good progress on many aspects of the effort:JDK bugs will be imported into JIRA regardless of age; bugs will also be imported regardless of state, including closed bugs. Consequently, the JDK bug project will start pre-populated with over 100,000 existing bugs, some dating all the way back to 1994. This will allow a continuity of information and allow new issues to be linked to old ones.Using a custom import process, the Sun bug numbers will be preserved in JIRA. For example, the Sun bug with bug number 4040458 will become "JDK-4040458" in JIRA. In JIRA the project name, "JDK" in our case, is part of the bug's identifier. Bugs created after the JIRA migration will be numbered starting at 8000000; bugs imported from the legacy system have numbers ranging between 1000000 and 79999999.We're working with the bugs.sun.com team to try to maintain continuity of the ability to both read JDK bug information as well as to file new incidents. At least for now, the overall architecture of bugs.sun.com will be the same as it is today: it will be a gateway bridging to an Oracle-internal system, but the internal system will change to JIRA from the legacy database. Generally we are aiming to preserve the visibility of bugs currently viewable on bugs.sun.com; however, bugs in areas not related to the JDK will not be visible after the transition to JIRA. New incoming incidents will be sent to a separate JIRA project for initial triage before possibly being moved into the JDK project.JDK bug management leans heavily on being able to track the state of bugs in multiple releases, especially to coordinate delivering synchronized security releases (known as CPUs, critital patch updates, in Oracle parlance). For a security release, it is common for half a dozen or more release trains to be affected (for example, JDK 5, JDK 6 update, OpenJDK 6, JDK 7 update, JDK 8, virtual releases for HotSpot express, etc.). We've determined we need to track at least the tuple of (release, responsible engineer/assignee for the release, status in the release) for the release trains a fix is going into. To do this in JIRA, we are creating a separate port/backport issue type along with a custom link type to allow the multiple release information to be easily grouped and presented together.The Sun legacy system had a three-level classification scheme, product, category, and subcategory. Out of the box, JIRA only has a one-level classification, component. We've implemented a custom second-level classification, subcomponent. As part of the bug migration we've taken the opportunity to think about how bugs should be grouped under a two-level system and we'll the new system will be simpler and more regular. The main top-level components of the JDK product will include:core-libsclient-libsdeployinstallsecurity-libsother-libstoolshotspotFor the libs areas, the primary name of the subcomponent will be the package of the API in question. In the core-libs component, there will be subcomponents like:java.langjava.lang.class_loadingjava.mathjava.utiljava.util:i18nIn the tools component, subcomponents will primarily correspond to command names in $JDK/bin like, jar, javac, and javap.The first several bulk imports of the JDK bugs into JIRA have gone well and we're continuing to refine the import to have greater fidelity to the current data, including by reconstructing information not brought over in a structured fashion during the previous large JDK bug system migration back in 2004.We don't currently have a firm timeline of when the new system will be usable externally, but as it becomes available, I'll share further information in follow-up blog posts.

Among insects, monarch butterflies and dragonflies have the longest migrations; migrating JDK bugs involves a long journey as well! As previously announced by Mark back in March, we've been working...

Java

Goto for the Java Programming Language

Work on JDK 8 is well-underway, but we thought this late-breaking JEP for another language change for the platform couldn't wait another day before being published.Title: Goto for the Java Programming LanguageAuthor: Joseph D. DarcyOrganization: Oracle.Created: 2012/04/01Type: FeatureState: FundedExposure: OpenComponent: core/langScope: SEJSR: 901 MRDiscussion: compiler dash dev at openjdk dot java dot netStart: 2012/Q2Effort: XSDuration: STemplate: 1.0Reviewed-by: DukeEndorsed-by: Edsger DijkstraFunded-by: Blue Sun CorporationSummaryProvide the benefits of the time-testing goto control structure toJava programs. The Java language has a history of adding new controlstructures over time, the assert statement in 1.4, the enhancedfor-loop in 1.5,and try-with-resources in 7. Having support for gotois long-overdue and simple to implement since the JVM already has gotoinstructions.Success MetricsThe goto statement will allow inefficient and verbose recursivealgorithms and explicit loops to be replaced with more compact code.The effort will be a success if at least twenty five percent of theJDK's explicit loops are replaced with gotos. Coordination withIDE vendors is expected to help facilitate this goal.MotivationThe goto construct offers numerous benefits to the Java platform,from increased expressiveness, to more compact code, to providing newprogramming paradigms to appeal to a broader demographic.In JDK 8, there is a renewed focus on using the Java platform onembedded devices with more modest resources than desktop or serverenvironments. In such contexts, static and dynamic memory footprintis a concern. One significant component of footprint is the codeattribute of class files and certain classes of important algorithmscan be expressed more compactly using goto than using otherconstructs, saving footprint. For example, to implement statemachines recursively, some parties have asked for the JVM to supporttail calls, that is, to perform a complex transformation with securityimplications to turn a method call into a goto. Such complicatedmachinery should not be assumed for an embedded context. A bettersolution is just to expose to the programmer the desiredfunctionality, goto.The web has familiarized users with a model of traversing links amongdifferent HTML pages in a free-form fashion with some state beingmaintained on the side, such as login credentials, to effect behavior.This is exactly the programming model of goto and code. While in thepast this has been derided as leading to "spaghetti code," spaghettiis a tasty and nutritious meal for programmers, unlikequiche. The invokedynamic instruction added by JSR 292 exposes the JVM'slinkage operation to programmers. This is a low-level operation thatcan be leveraged by sophisticated programmers. Likewise, goto is aalso a low-level operation that should not be hidden from programmerswho can use more efficient idioms.Some may object that goto was consciously excluded from the original design of Java asone of the removed feature from C and C++. However, the designers ofthe Java programming languages have revisited these removals before.The enum construct was also left outonly to be added in JDK 5 and multiple inheritance was left out,only to be added back by the virtual extension method methods ofProject Lambda.As a living language, the needs of the growing Java community todayshould be used to judge what features are needed in the platformtomorrow; the language should not be forever bound by the decisions ofthe past.DescriptionFrom its initial version, the JVM has had two instructions forunconditional transfer of control within a method, goto(0xa7)and goto_w(0xc8).The goto_w instruction is used for larger jumps. All versions of theJava language have supported labeledstatements;however, only the break and continue statements were able tospecify a particular label as a target with the onerous restrictionthat the label must be lexically enclosing.The grammar addition for the goto statement is:GotoStatement: goto Identifier ;The new goto statement similar to break except that the targetlabel can be anywhere inside the method and the identifier ismandatory. The compiler simply translates the goto statement intoone of the JVM goto instructions targeting the right offset in themethod. Therefore, adding the goto statement to the platform isonly a small effort since existing compiler and JVM functionality isreused.Other language changes to support goto include obvious updates todefinite assignment analysis, reachability analysis, and exceptionanalysis.Possible future extensions include a computed goto as found in gcc,which would replace the identifier in the goto statement with anexpression having the type of a label.TestingSince goto will be implemented using largely existing facilities,only light levels of testing are needed.ImpactCompatibility: Since goto is already a keyword, there are no source compatibility implications.Performance/scalability: Performance will improve with more compact code. JVMs already need to handle irreducible flow graphs since goto is a VM instruction.

Work on JDK 8 is well-underway, but we thought this late-breaking JEP for another language change for the platform couldn't wait another day before being published. Title: Goto for the Java Programming...

Java

Repeating annotations in the works

Work has commenced on the repeating annotations feature discussed in JEP 120: Repeating Annotations. First, the meta-annotation type used to declare the containing annotation has been added to java.lang.annotation.Updates to the AnnotatedElement interface will be made later.Next, with feedback from other members of the compiler team, I've written a draft specification of the needed language changes:Updates to JLS 9.6 Annotation Types:If annotation type T is annotated with an annotation a of type ContainerAnnotation then:The value of the @ContainerAnnotation annotation is called the containing annotation type TC.TC must declare a value() method whose return type is T[], or a compile-time error occurs.(This implies that TC can be the containing annotation type for only a single annotation type.)[Note: Since an annotation type T cannot declare a method that returns T or T[] as a value, that implies that it is a compile time error for an annotation type to specify itself as a container annotation type.]TC may declare methods other than value(). Any such methods must have a default clause, or a compile-time errors occurs.[Note: this is a bit weird "action at a distance" in terms of compiler errors. The error message here is given at the site of the T since the containing annotation might only be present as a class file.]It is a compile time error if the retention of T is not a subset of the retention of TC. This comparison is made taking default retention into consideration. In more detail, if the retention of the TC is SOURCE, the retention of T must be SOURCE. If the retention of TC is CLASS, the retention of T may be either CLASS or SOURCE. if the retention of the TC is RUNTIME, the retention of T may be SOURCE, CLASS, or RUNTIME.It is a compile time error if T is @Documented and TC is not @Documented.[Note that it is permissible TC to be @Documented and for T to not be @Documented.]It is a compile time error if T is @Inherited and TC is not @Inherited.[Note that it is permissible TC to be @Inherited and for T to not be @Inherited.]It is a compile time error if T has target values that are not included in the target set of TC, taking default target values into account.Note that an annotation type TC may be a container type for annotation type T while also having its own container type TCC.[However, two annotation types cannot be containers for each other because that would create an illegal cyclic annotation type situation. For example, the following program is rejected by javac:public @interface Mutual { Omaha[] value() default {};}@interface Omaha { Mutual[] value() default {};}@Mutual({@Omaha, @Omaha})@Omaha({@Mutual, @Mutual})class Foo {}with the messageMutual.java:2: error: cyclic annotation element type Omaha[] value() default {}; ^1 error]Updates to JLS 9.7 Annotations:"It is a compile-time error if a declaration is annotated with more than one annotation for a given annotation type."Change to "unless the annotation type is annotated with an @ContainerAnnotation."Annotation types with an @ContainerAnnotation are known as repeatable annotation types. The presence of an @ContainerAnnotation indicates multiple annotations of that annotation type will be logically replaced with a single annotation synthesized by the compiler. The type of the synthesized annotation, TC, is the type given by the value of the ContainerAnnotation annotation on T. The order of the elements of the value() method of the synthesized TC annotation matches the left to right order of the base repeatable annotations.If an element only has a single repeatable annotation, the annotation is not replaced.It is conventional to place the repeatable annotations of a given type contiguously on an element, but this is not required.It is a compile time error if an element is annotated with both multiple base annotations of a repeatable annotation type T and with one or more annotations of the containing type TC.[In other words, the collapsing of repeatable annotations to their containers is not recursive.]

Work has commenced on the repeating annotations feature discussed in JEP 120: Repeating Annotations. First, the meta-annotation type used to declare the containing annotation has been added to java.la...

Java

Unsigned Integer Arithmetic API now in JDK 8

At long last, after due discussion and review, I've just pushed initial API support for unsigned integer arithmetic into JDK 8!The support is implemented via static methods, primarily on java.lang.Integer and java.lang.Long, that:Provide bidirectional conversion between strings and unsigned integersCompare values as unsignedCompute unsigned divide and remainderColloquially, "unsigned integer" means a 32-bit int or 64-bit long value where all the bits are interpreted as contributing to the magnitude. In the unsigned realm, the values of an integer type of a given bit-width range from 0 to 2width-1 rather than from -(2width-1) to 2width-1-1.A feature of the two's complement encoding of Java integers is that the bitwise results for add, subtract, and multiply are the same if both inputs are interpreted as signed values or both inputs are interpretted as unsigned values.(Other encodings like one's complement and signed magnitude don't have this properly.)Therefore, of the basic arithmetic operations, only a separate divide method needs to be provided to operate on values interpreted as unsigned.To avoid dealing with the overhead of boxed values and to allow reuse of the built-in arithmetic operators, the unsigned API support does not introduce new types like UnsignedInt with instance methods to perform addition, subtraction, etc. However, that lack of separate Java-level unsigned types does mean a programmer can accidentally improperly mix signed and unsigned values. However, new unsigned types aren't the only way to mitigate this hazard. For example, a naming convention of adding a trailing "U" or "_U" to variables holding unsigned values could be adopted. A more structured approach would be to add an @Unsigned annotation type to the platform and apply that annotation to variables and fields holding unsigned values. One of the extra-linguistic checkers to be enabled by JSR 308 could then analyze code for signed/unsigned correctness.I'm glad these methods are finally in the JDK. Later in JDK 8, there may be a few more fun bit-twiddling additions, such as methods to get the high order bits of a full multiply and methods which throw exceptions on integer overflow instead of wrapping around.

At long last, after due discussion and review, I've just pushed initial API support for unsigned integer arithmetic into JDK 8! The support is implemented via static methods, primarily on java.lang.In...

Java

Project Coin Fixes in 7u2

Last month, JDK 7u2 was released.The release has a few correctness fixes for the Project Coin features, two diamond fixes courtesy Maurizio and one fix to strings in switch: Diamond inference with nested classes had an improper interaction. For example, in code likeclass X { class Y { Y(T a, Z b) {...} } public static void main(String... args) { X<String>.Y<String> x1 = new X<String>().new Y<String>("",""); //ok X<String>.Y<String> x2 = new X<String>().new Y<>("",""); // Failed! }diamond was not allowed at the second constructor call, but such code is accepted as of 7u2. (7046778)The compiler erroneously allowed constructs likeFoo<String>[] fooArr = new Foo<>[]{...};Such code is now properly rejected.(7057297)If extra parenthesis were used around the case label of a string switch statement, as inswitch (s) { case ("a"): ...}javac would throw a NullPointerException when compiling the code.(7071246)Previously, the workaround was to remove the unneeded "(" and ")", but javac has been corrected to accept this valid syntax.(We received multiple reports of this bug, so parenthesis around case labels is much more common style than I would have expected!)If you're using the Project Coin language features, I recommend upgrading to 7u2 to get these fixes and to minimize source compatibility concerns going forward.

Last month, JDK 7u2 was released. The release has a few correctness fixes for the Project Coin features, two diamond fixes courtesy Maurizio and one fix to strings in switch: Diamond inference with...

JavaOne

Project Coin at JavaOne 2011

Update: A video of this talk is now available on Parley's.Earlier today, I presented my JavaOne session on The Heads and Tails of Project Coin (slides).The talk included some retrospectives from developing the Coin features which I hope to write up in more detail in the near future.Turning toward the future, the talk also spent a little time discussing possible language changes coming in JDK 8. First, planning for JDK 8 is on-going and the feature list is subject to change; the JEP process will be used to help define the roadmap going forward.With those caveats, small language changes we're considering proposing for JDK 8 include:Refinements to JDK 7 Coin features try-with-resources on an effective final variableremoving restrictions on usage of diamond@SafeVarargs on private methodsCollection literals(?)Repeating Annotations(?)Method and constructor parameter names at runtime(?)Personally, I would welcome programming with collection literals. Repeating annotations and the ability to retrieve the names of method/constructors at runtime are both long-standing requests from our colleagues in EE.However, with the broad scope of language and platform changes coming into JDK 8 courtesy Lambda and Jigsaw, all these smaller language changes have to be made somewhat opportunistically.For that reason, for JDK 8 we are not planning on having another open call for proposals as was done for Project Coin in JDK 7.

Update: A video of this talk is now available on Parley's. Earlier today, I presented my JavaOne session on The Heads and Tails of Project Coin (slides).The talk included some retrospectives from...

Java

JDK 7: Small Library Treats

With JDK 7 out the door, many writeups of the release have naturally focused on its larger features like Project Coin, NIO.2, the fork/join framework, and invokedynamic. However, there are a number of small but useful library conveniences in JDK 7 that shouldn't be overlooked.Library changes I think are handy include: To allow more informative assertion errors to be constructed, AssertionError now includes a constructor taking a string message and a Throwable cause, which is one of the four conventional constructors for exception types. The methods which convert strings to numeric values differed in whether or not a leading plus, "+", was regarded as valid input. Float, Double, and BigDecimal accepted a leading plus while Byte, Short, Integer, Long, and BigInteger did not.As of JDK 7, all those types consistently accept a leading plus in their parseFoo, valueOf, and decode methods.To help write more efficient comparators, Boolean, Byte, Character, Short, Integer, and Long each have a two-argument static compare method that performs the desired comparison operation without boxing overhead. This six checked exception types that can be thrown by core reflection now have a common supertype, ReflectiveOperationException.This additional type complements the improved exception handling available with multi-catch and more precise re-throw from Project Coin. The java.util.Objects class contains a number of small, but commonly used methods, many of them for coping with null inputs. For example, Objects contains a two-argument static equals method which does the right thing on null inputs. I've replaced a half-dozen copies of that method's logic in the JDK; I'm sure many more instances can be removed in other code bases as JDK 7 is adopted. Part of NIO.2, I expect over time the utility methods injava.nio.file.Files to copy, read, and write the contents of file will see heavy usage.

With JDK 7 out the door, many writeups of the release have naturally focused on its larger features like Project Coin, NIO.2, the fork/join framework, and invokedynamic. However, there are a number...

Java

Project Coin: Diamond and Generic Constructors

To address an issue in the specification, the JSR 334 expert group has decided to ban the combination of diamond together with explicit constructor type arguments.For background, a constructor can have two sets of type arguments. In a parameterized class, constructors can have type arguments corresponding to the class's type parameters. This is the common case and the type arguments appear to the right of the class name and "new" as in "new ArrayList<String>()".In addition, if a constructor declares its very own type parameters (which can be done whether or not the enclosing class is parameterized), then those type arguments appear between the "new" token and the class name as in "new <Integer> ConstructorWithTypeParameter(Integer.valueOf(42))". As with generic methods, the type arguments of generic constructors are usually inferred and not explicitly passed. However, generic constructors are much less common than generic methods.After the specification change, using diamond to infer the class type parameters but explicitly passing the constructor type parameters is forbidden. However, the other three combinations of explicitly passing type arguments versus inferring them are supported, as shown in the table below. class Foo<T extends Number> { <S extends T> Foo(S s) {super();}}Class Constructor Supported ExampleExplicit Explicit Yesnew <Integer> Foo<Number>(null);Explicit Inferred Yes new Foo<Integer>(null);Inferred Explicit No new <Integer> Foo<>(null); // compile errorInferred Inferred Yes new Foo<>(null);The substitution that was used to formally describe the semantics of diamond did not fully propagate constraints if there was a typing relationship between the type parameters of the constructor and the type parameters of the class.Lifting the imposed restriction on the banned combination of explicit and inferred type arguments can be revisited in future work in the context of broader type inference getting added to the Java language.Since generic constructors are so uncommon, adding this restriction about combining them with diamond should have little effect to most programs. For example, none of the uses of diamond in the JDK had to be updated as a result of this change.A changeset implementing this specification change has been pushed and will appear in subsequent promoted builds of JDK 7.

To address an issue in the specification, the JSR 334 expert group has decided to ban the combination of diamond together with explicit constructor type arguments.For background, a constructor can...

Java

Project Coin: JSR 334 in Public Review

After successfully going through early draft review, JSR 334 has now entered another phase: public review.Compared to the earlier draft review specification (v0.75), the main changes in the public draft review specification (v0.875) are:The specification for diamond was expanded and clarified. Using diamond on a non-generic class is explicitly forbidden.The specification for multi-catch was expanded and made more precise.Several changes related to the try-with-resources feature:The try-with-resources statement has dropped support for a resource to be given as a general expression without an accompanying explicit variable declaration. An optional trailing semicolon is allowed to terminate the sequence of resources in a resource specification rather than producing a syntax error.The compiler-generated calls to the close method of a resource in a try-with-resources statement only occur if the resource is non-null.Strong warnings were added to the javadoc of AutoCloseable about having the close method throw InterruptedException. The @SafeVarargs annotation was applied to appropriate places in the platform libraries.JLSv3 changes were provided for the simplified varargs method invocation feature. The public review draft of JSR 334 is the last expected JCP milestone before proposed final draft, so get your comments about the public review in soon!

After successfully going through early draft review, JSR 334 has now entered another phase: public review. Compared to the earlier draft review specification (v0.75), the main changes in the public dra...

Annotation Processing

JSR 269 Maintenance Review

As a planned part of Java SE 7, JSR 269, which standardized an API for annotation processing, is now undergoing maintenance review.In the JCP, a maintenance review is a process to take comments on small changes so that those small changes can be formally incorporated into an existing specification without running a whole new JSR.The changes being proposed in the JSR 269 maintenance review are the changes already implemented in the JSR 269 APIs in JDK 7.In summary, those proposed changes are:Clarified interaction between the Filer and rounds.Constructors explicitly added to the kinds of elements that canbe returned by RoundEnvironment.getElementsAnnotatedWith.New enum constantjavax.lang.model.SourceVersion.RELEASE_7.In the package description ofjavax.lang.model.element, requirements on when a modelmust be provided are loosened to remove the requirement in case of an"irrecoverable error that could not be removed by the generation ofnew types," a condition which includes but is not limited to syntaxerrors.New exception typejavax.lang.model.UnknownEntityException added as a commonsuperclass for existing exception typesUnknownAnnotationValueException,UnknownElementException, andUnknownTypeException.New enum constantjavax.lang.model.element.ElementKind.RESOURCE_VARIABLE.New mixin interfaces Parameterizable andQualifiedNameable added to packagejavax.lang.model.element.ExecutableElement and TypeElement areretrofitted to extend Parameterizable;PackageElementand TypeElement areretrofitted to extend QualifiedNameable.Behavior of getEnclosingElement method defined toreturn the generic element of a type parameter instead ofnull.New interfacejavax.lang.model.type.DisjunctiveType to modeldisjunctive types.New enum constantjavax.lang.model.type.TypeKind.DISJUNCTIVE to markdisjunctive types.New method visitDisjunctive added to visitorinterface javax.lang.model.type.TypeVisitor.Utility visitor implementations updated accordingly.In the package javax.lang.model.type,MirroredTypesException retrofitted to be thesuperclass of MirroredTypeException.New utility visitors for release 7 in packagejavax.lang.model.util:AbstractAnnotationValueVisitor7AbstractElementVisitor7AbstractTypeVisitor7ElementKindVisitor7ElementScanner7SimpleAnnotationValueVisitor7SimpleElementVisitor7SimpleTypeVisitor7TypeKindVisitor7The visitors ElementKindVisitor6,ElementScanner6, and SimpleElementVisitor6,are updated to account for new element kindRESOURCE_VARIABLE.The visitor AbstractTypeVisitor6 is updated toaccount for the possibility of visiting aDisjunctiveType.Definition of documentation comment added to javadoc ofjavax.lang.model.util.Elements.getDocComment.

As a planned part of Java SE 7, JSR 269, which standardized an API for annotation processing, is now undergoing maintenance review. In the JCP, a maintenance review is a process to take comments on...

OpenJDK

OpenJDK 6: A changing of the guard

The first public source drop of OpenJDK 6 went out just over three years ago.I've been the release manager for the project for all that time and for the preceding six months while the effort was incubating inside of Sun.Somewhat later than anticipated at the start, all initial goals for the project have long been met, with a public master code repository worked on by both the internal and external community members and a code base that can be used to build a fully compatible implementation of Java SE 6.Combined with the IcedTea 6 set of patches and additions, the code from OpenJDK 6 is used to build the JDK packaged with many Linux distributions.However, to have more time to spend on other projects, effective immediately I've turned over release management responsibilities for OpenJDK 6 to my colleague Kelly O'Hair.Kelly has considerable experience with JDK development in general and OpenJDK 6 in particular.Kelly has made major contributions to OpenJDK 6 throughout all phases of the project, starting from its inception, to the synthesis of its public Mercurial repositories with history information, to the recent purging of the despised binary plugs.While I have some sadness in relinquishing leadership of the project, I'm happy to be leaving OpenJDK 6 release management in Kelly's capable hands.

The first public source drop of OpenJDK 6 went out just over three years ago.I've been the release manager for the project for all that time and for the preceding six months while the effort was...

OpenJDK

OpenJDK 6: b22 regression test results

Running with the jtreg flags, "-a -ignore:quiet -ea -esa" in all repositories, using generally accessible hosts for the network configuration file, and adding "-s" for langtools, the basic regression test results on Linux forOpenJDK 6 build 22 are:HotSpot, 97 tests passed and 1 failed.Langtools, 1,391 tests passed.JDK, 3,300 tests pass, 30 fail, and 3 have errors.The preponderance of changes in b22 were for security fixes; the hotspot and langtools tests results are identical to b21:0: b21-hotspot/summary.txt pass: 97; fail: 11: b22-hotspot/summary.txt pass: 97; fail: 1No differences0: b21-langtools/summary.txt pass: 1,3911: b22-langtools/summary.txt pass: 1,391No differencesAnd in jdk, the results were nearly identical:0: b21-jdka/summary.txt pass: 3,295; fail: 33; error: 41: b22-jdk/summary.txt pass: 3,300; fail: 30; error: 30 1 Testerror pass com/sun/jdi/DoubleAgentTest.javafail pass java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowBlockingTest.javafail pass java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowRetaining.javafail pass java/awt/Focus/TranserFocusToWindow/TranserFocusToWindow.java--- pass tools/launcher/LibraryPath.java5 differences(The b21 baseline for the jdk repository was the test run where assertions where enabled.

Running with the jtreg flags, "-a -ignore:quiet -ea -esa" in all repositories, using generally accessible hosts for the network configuration file, and adding "-s" for langtools, the basic regression...

Java

Project Coin:try-with-resources on a null resource

After due consideration the JSR 334 expert group has decided the semantics of the try-with-resources statement on a null resource should be changed as follows: the compiler-generated calls to close a resource will only occur if the resource is non-null.Concretely, the semantics of the desugaring of the finally block are changed fromfinally { if (#primaryException != null) { try { #resource.close(); } catch(Throwable #suppressedException) { #primaryException.addSuppressed(#suppressedException); } } else { #resource.close(); }} to finally { if (#primaryException != null) { try { if(#resource != null) #resource.close(); } catch(Throwable #suppressedException) { #primaryException.addSuppressed(#suppressedException); } } else { if(#resource != null) #resource.close(); }}This decision was informed by discussions on coin-dev as well as experiments retrofitting try-with-resources onto the JDK libraries.The change allows idioms liketry(Resource r = methodThatMightReturnNull()) { if (r == null) return; // nothing to do}to complete normally without generating a null pointer exception. Note that the programmer still has responsibility to check for a null resource if the resource is used inside the try block; the generated null check does not occur before the try block is entered.Implementing the change is being tracked under Oracle bug 7020047 "Project Coin: generate null-check around try-with-resources close call."

After due consideration the JSR 334 expert group has decided the semantics of the try-with-resources statement on a null resource should be changed as follows: the compiler-generated calls to close a...

OpenJDK

FOSDEM 2011: OpenJDK 6 and Project Coin

At FOSDEM last weekend, I gave two presentations, one on OpenJDK 6 and the other on Project Coin.In "The State of OpenJDK 6," after providing some historical context, I discussed various upcoming changes. As relayed elsewhere, Kelly O'Hair will be assisting in OpenJDK 6 release management and security fixes to OpenJDK 6 from Oracle will continue through the end-of-life of the JDK 6 train, which per Oracle policy will occur no sooner than July 2012 (one year after JDK 7 ships GA).Also of note, after JDK 7 ships GA, Oracle will continue development of the 7 update releases in the open, similar to how it has been done pre-GA. In particular, there will not be the same dichotomy between the OpenJDK 7 code base and the 7 update code base as there is between OpenJDK 6 and the 6 update train.I prepared some additional slides about OpenJDK 6, but did not present them due to time considerations. In the backup portion of slide deck, slide 13 graphs that since b11 the majority of fixes pushed into OpenJDK 6 have been HotSpot changes with the corba, jaxp, and jaxws areas clearly in maintenance. Slides 15 and 16 cover OpenJDK 6 regression test results since b11. There has been a growing number of tests and the overall pass rate is high and generally increasing; langtools and hotspot recently typically have a 100% pass rate and the pass rate for the jdk repository has risen from 98% to 99%.For Project Coin, I presented the current state the language changes, discussed the development of changes, and spoke briefly on some aspects of developing the changes in the open.All in all, another fun year at FOSDEM; next time, I hope I'm less afflicted with jet lag!

At FOSDEM last weekend, I gave two presentations, one on OpenJDK 6 and the other on Project Coin. In "The State of OpenJDK 6," after providing some historical context, I discussed various upcoming...

Java

Project Coin: How to Terminate try-with-resources

In addition to mulling over nulling in the try-with-resources statement, the JSR 334 expert group has decided to slightly amend the syntax of try-with-resources statement: an optional trailing semicolon will now be allowed to terminate the list of resources.Previously, a semicolon could only be used as a separator between two resources as intry(Resource r0 = new Resource(); Resource r1 = new Resource(); Resource r2 = new Resource()) {...} or reformatted as try(Resource r0 = new Resource(); Resource r1 = new Resource(); Resource r2 = new Resource()) {...}However, including an extraneous semicolon at the end of the list would be rejected as a syntax error:try(Resource r0 = new Resource(); Resource r1 = new Resource(); Resource r2 = new Resource();) {...} // Illegal under JSR 334 EDR!While requiring a semicolon at the end of a list of resources would be excessive, especially when there is only a single resource being managed, optionally allowing a terminating resource offers several advantages.First, when adding a resource to the list of resources being managed, there are fewer necessary edits when cutting and pasting.More importantly, programmatic generation of code is simplified since the code generation logic does not need to know ahead of time whether or not a particular resource will be the last one when the declaration for that resource is generated.The simple rule "terminate a resource declaration with a semicolon" will result in acceptable code, even if the code is not ideal style-wise.Finally, allowing an optional trailing semicolon is consistent with the handling of commas in array initializers, int[] values = {1, 2, 3, // Legal };and the handling of commas in the declaration of enum constants.enum PrimaryColor { RED, GREEN, BLUE, // Legal ;}The full amended grammar for try-with-resources which allows the optional trailing semicolon is:TryStatement:try Block Catchestry Block Catchesopt Finallytry ResourceSpecification Block Catchesopt FinallyoptResourceSpecification:( Resources ;opt )Resources:ResourceResource ; ResourcesResource:VariableModifiersopt Type VariableDeclaratorId = ExpressionThe necessary compiler changes to implement the revised grammar have been pushed into a JDK 7 integration repository and will appear in a promoted build in due course.

In addition to mulling over nulling in the try-with-resources statement, the JSR 334 expert group has decided to slightly amend the syntax of try-with-resources statement: an optional...

OpenJDK

OpenJDK 6: b21 regression test results

Running with the usual jtreg flags, "-a -ignore:quiet" in all repositories, using generally accessible hosts for the network configuration file, and adding "-s -ea -esa" for langtools, the basic regression test results on Linux forOpenJDK 6 build 21 are:HotSpot, 97 tests passed and 1 failed.Langtools, 1,391 tests passed.JDK, 3,300 tests pass, 29 fail, and 3 have errors.More HotSpot tests were added and all but one pass; the new failing test is improperly platform-specific:0: b20-hotspot/summary.txt pass: 851: b21-hotspot/summary.txt pass: 97; fail: 10 1 Test--- pass compiler/6431242/Test.java--- pass compiler/6894807/IsInstanceTest.java--- pass compiler/6932496/Test6932496.java--- pass compiler/6946040/TestCharShortByteSwap.java--- pass compiler/6958485/Test.java--- pass compiler/6973329/Test.java--- pass compiler/6982370/Test6982370.java--- pass compiler/7002666/Test7002666.java--- pass gc/6581734/Test6581734.java--- pass runtime/6626217/Test6626217.sh--- pass runtime/6888954/vmerrors.sh--- pass runtime/6925573/SortMethodsTest.java--- fail runtime/6929067/Test6929067.sh13 differencesIn langtools some tests were added and all the tests continue to pass:0: b20-langtools/summary.txt pass: 1,3651: b21-langtools/summary.txt pass: 1,3910 1 Test--- pass tools/javac/6508981/TestInferBinaryName.java--- pass tools/javac/6734819/T6734819a.java--- pass tools/javac/6734819/T6734819b.java--- pass tools/javac/6734819/T6734819c.java--- pass tools/javac/6889255/T6889255.java--- pass tools/javac/T6595666.java--- pass tools/javac/T6625520.java--- pass tools/javac/T6705935.java--- pass tools/javac/T6956638.java--- pass tools/javac/api/6411310/Test.java--- pass tools/javac/api/6440333/T6440333.java--- pass tools/javac/api/6733837/T6733837.java--- pass tools/javac/api/Sibling.java--- pass tools/javac/api/T6483788.java--- pass tools/javac/api/T6501502.java--- pass tools/javac/api/T6838467.java--- pass tools/javac/api/T6877206.javapass --- tools/javac/policy/Test.javapass --- tools/javac/policy/Test.java#id1pass --- tools/javac/policy/Test.java#id2pass --- tools/javac/policy/Test.java#id3pass --- tools/javac/policy/Test.java#id4pass --- tools/javac/policy/Test.java#id5pass --- tools/javac/policy/Test.java#id6pass --- tools/javac/policy/Test.java#id7--- pass tools/javac/policy/test1/Test1a.java--- pass tools/javac/policy/test1/Test1a.java#id1--- pass tools/javac/policy/test1/Test1a.java#id2--- pass tools/javac/policy/test1/Test1a.java#id3--- pass tools/javac/policy/test1/Test1a.java#id4--- pass tools/javac/policy/test1/Test1a.java#id5--- pass tools/javac/policy/test1/Test1a.java#id6--- pass tools/javac/policy/test1/Test1a.java#id7--- pass tools/javac/policy/test1/Test1b.java--- pass tools/javac/policy/test1/Test1b.java#id1--- pass tools/javac/policy/test1/Test1b.java#id2--- pass tools/javac/policy/test1/Test1b.java#id3--- pass tools/javac/policy/test2/Test.java--- pass tools/javac/policy/test2/Test.java#id1--- pass tools/javac/policy/test2/Test.java#id2--- pass tools/javac/policy/test2/Test.java#id3--- pass tools/javac/policy/test3/Test.java42 differencesAnd in jdk, a small percentage of tests were added and the existing tests have generally consistent results:0: b20-jdk/summary.txt pass: 3,273; fail: 33; error: 21: b21-jdk/summary.txt pass: 3,300; fail: 29; error: 30 1 Test--- pass com/sun/java/swing/plaf/gtk/Test6963870.javafail pass java/awt/Focus/NonFocusableWindowTest/NonfocusableOwnerTest.java--- pass java/awt/Frame/FrameSize/TestFrameSize.javafail pass java/awt/Frame/MaximizedToIconified/MaximizedToIconified.javafail pass java/awt/Multiscreen/LocationRelativeToTest/LocationRelativeToTest.javafail pass java/awt/TextArea/UsingWithMouse/SelectionAutoscrollTest.html--- pass java/awt/font/TextLayout/TestSinhalaChar.javapass error java/lang/management/MemoryMXBean/CollectionUsageThresholdConcMarkSweepGC.sh--- pass java/math/BigDecimal/MultiplyTests.javapass fail java/net/InetAddress/IPv4Formats.javapass fail java/net/URL/OpenStream.javapass fail java/net/URLClassLoader/ClassLoad.javapass fail java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java--- pass java/util/logging/AnonLoggerWeakRefLeak.sh--- pass java/util/logging/LoggerWeakRefLeak.sh--- pass javax/imageio/plugins/png/ITXtTest.java--- pass javax/imageio/plugins/png/ItxtUtf8Test.java--- pass javax/swing/JPopupMenu/6675802/bug6675802.java--- pass javax/swing/JPopupMenu/6691503/bug6691503.java--- pass javax/swing/Security/6938813/bug6938813.java--- pass javax/swing/UIDefaults/6622002/bug6622002.java--- pass javax/swing/UIDefaults/6795356/SwingLazyValueTest.java--- pass javax/swing/UIDefaults/6795356/TableTest.java--- pass javax/swing/UIDefaults/6795356/bug6795356.javafail pass javax/swing/plaf/synth/Test6933784.javafail pass sun/nio/cs/Test4200310.sh--- pass sun/security/pkcs11/SecureRandom/TestDeserialization.java--- pass sun/security/pkcs11/Signature/TestRSAKeyLength.java--- pass sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/InvalidateServerSessionRenegotiate.java--- fail sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/CriticalSubjectAltName.java--- pass sun/security/ssl/javax/net/ssl/NewAPIs/JSSERenegotiate.java--- pass sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.java--- pass sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/ConnectionTest.java--- pass sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/NoAuthClientAuth.javafail pass sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/DNSIdentities.javafail pass sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressIPIdentities.javafail pass sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPIdentities.javafail pass sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/Identities.javapass fail sun/security/validator/CertReplace.java--- pass sun/tools/common/CommonTests.sh40 differencesIn addition to the basic results, the hotspot and jdk regression test suites were rerun with assertions and system assertions enabled, -ea -esa. (The langtools tests are already run with assertions enabled.)The results for hotspot were identical to running without assertions; in jdk a few additional tests failed:0: b21-jdk/summary.txt pass: 3,300; fail: 29; error: 31: b21-jdka/summary.txt pass: 3,295; fail: 33; error: 40 1 Testpass error com/sun/jdi/DoubleAgentTest.javapass fail java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowBlockingTest.javapass fail java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowRetaining.javapass fail java/awt/Focus/TranserFocusToWindow/TranserFocusToWindow.javafail pass java/awt/xembed/server/RunTestXEmbed.javapass fail java/net/Authenticator/B4769350.javapass fail java/net/CookieHandler/TestHttpCookie.javafail pass java/rmi/transport/rapidExportUnexport/RapidExportUnexport.javapass fail java/util/ResourceBundle/Test4300693.java9 differencesGoing forward, the baseline regression test results for all OpenJDK 6 repositories will be reported with assertions and system assertions enabled.

Running with the usual jtreg flags, "-a -ignore:quiet" in all repositories, using generally accessible hosts for the network configuration file, and adding "-s -ea -esa" for langtools, the...

Java

Project Coin: JSR 334 Expert Group Update

Besides working to address issues identified in the EDR draft, such as refining the diamond specification, the JSR 334 expert group has been considering other matters as well. One change being contemplated is removing the ability to have multiple underscores between digits of a literal; under that possible change, no underscore or a single underscore would be allowed. The primary consideration here is to prevent abuses of the underscores in literal feature that would obscure program meaning; on the other hand, there may be reasonable uses of repeated underscores that are desirable to allow.The expert group has agreed to one significant change from the EDR draft: as called out as a possibility in the draft, support has been dropped for the general expression form of the try-with-resources statement. That is, support has been removed for passing a resource as a general expression without an accompanying explicit variable declaration.Several technical problems were identified with allowing a general expression: Syntactic ambiguity: In the parser, it was not always possibleto distinguish with one-token look-ahead between the start of anExpression and the start of a Type. Consider code like try(i < j // Ternary operator on variables i and j ? new Resource1() : new Resource2()) {...}compared to code like try(Box < Resource // Simple generic wrapper around a resource > resourceBox = Box<>(new Resource1())) {...}A natural grammatical fallback short of banning Expressionwould be to only allow a more restricted expression, such asIdentifier.However, that restricted grammar would require compiler changes toalert programmers to some surprising legal code, as given in thefollowing examples.Usability issues: Consider a try-with-resourcesstatement being used to manage an existing variable where the variableis mutated inside the try block:public class TwrExamples implements AutoCloseable { public static void main(String... args) { TwrExamples twrEg1 = new TwrExamples(); System.out.println(twrEg1.hashCode()); try(twrEg1) { twrEg1 = new TwrExamples(); // Mutating the variable! System.out.println(twrEg1.hashCode()); } } @Override public void close() { System.out.println(hashCode()); }}As try-with-resources was previously specified, this would cause close to be called on the original value, notthe value twrEg1 pointed to at the time thetry block finishes.In this case, the printed output of the program may be somethinglike:160757678710512962021607576787which indicates that while close was called on theoriginal value, close was not called on the newTwrExamples object created inside thetry-with-resources block.Either policy of calling code on the original value orthe value on exit of the block could be problematic.The compiler did not issue any warnings about this situation andwarnings should be added if this feature were to be kept.(Mutating a resource variable declared as part of the try-with-resourcesstatement is illegal since such variables are implicitly or explicitlyfinal).Other complications that stemmed from supporting a general expressionas a resource were making sure the specification and implementationaccepted both try(null) {...}and try(myGenericMethodThatInfersTheTypeOfItsResult()) {}as valid programs.The main rationale for supporting general expressions was to allownon-Closeable objects, such as locks, to be easilywrapped in a suitable type to enjoy the call-method-on-block-exitguarantees of try-with-resources.When this is desirable, the same effect can still be achieved with anexplicit resource declaration.As experience is gained with try-with-resources,extensions to support other usage patterns will be considered infuture releases.I'm working with the javac team to remove support for this feature in an upcoming JDK 7 build.

Besides working to address issues identified in the EDR draft, such as refining the diamond specification, the JSR 334 expert group has been considering other matters as well. One change...

Java

Project Coin: Minty Fresh Libraries

The JDK 7 build has been using -source 7 for some time, but to date use of new language features has been informal and incidental. Supporting Project Coin and JSR 334, Stuart Marks will be leading a "minting" exercise over the JDK code base to systematically update the JDK libraries to take advantage of the Project Coin language features. Efforts will be focused on the src and test portions of the jdk repository of the JDK 7 forest. The first features to be rolled into the code will be diamond and strings in switch.Review requests for different areas will be sent to the appropriate OpenJDK aliases for review. The proposed changes will consist solely of conversions of existing code to use a new language feature. While use of the new features is encouraged, in areas of the platform where code is kept synchronized with earlier release trains, such code cannot be updated to use the Project Coin features at this time.For several years, we've been collaborating with the NetBeans team to provide IDE support for the Project Coin features. NetBeans 7 Beta is the latest release to support Project Coin, as detailed in its release notes. We will continue to coordinate with the NetBeans team to update the Project Coin support in NetBeans as refinements are made to the Project Coin features. Additionally, to allow use of NetBeans for JDK development, we will defer updating the JDK to use a Coin feature until there is matching support in a NetBeans build, as there is now for diamond and strings in switch. (The NetBeans 7 Beta supports a slightly older version of multi-catch and try-with-resources.)

The JDK 7 build has been using -source 7 for some time, but to date use of new language features has been informal and incidental. Supporting Project Coin and JSR 334, Stuart Marks will be leading a...

Java

Project Coin: Safe Varargs

Following up on earlier work, the javac team has pushed a new implementation of Project Coin's simplified varargs method invocation feature (jdk, langtools). The changes are scheduled to appear in the promotion of JDK 7 b123.As envisioned previously, a new @Documented annotation type, java.lang.SafeVararags, can be used to suppress warnings related to unchecked warnings, both the new mandatory warnings at the declaration site of a varargs method/constructor with a non-reifiable element type and the existing unchecked warnings at the call sites of such methods. A systematic application of this annotation to appropriate declarations in the JDK libraries will follow as future work.Since new unchecked warnings are being introduced, those diligently compiling with options like "-Xlint:unchecked -Werror" will see a build error under JDK 7 if any of the suspicious varargs method declarations are found. To address this, the @SafeVarargs annotation can be applied to the declarations, if appropriate, or the @SuppressWarnings({"unchecked", "varargs"}) annotation can be applied. Unlike @SafeVarargs, the @SuppressWarnings annotation will not squelch unchecked warnings at the call site of the annotated method.The specification of the new SafeVarargs annotation type is below.Annotation Type SafeVarargs@Documented@Retention(value=RUNTIME)@Target(value={CONSTRUCTOR,METHOD})public @interface SafeVarargsA programmer assertion that the body of the annotated method or constructor does not perform potentially unsafe operations on its varargs parameter. Applying this annotation to a method or constructor suppresses unchecked warnings about anon-reifiable variable-arity (vararg) type and suppresses unchecked warnings about parameterized array creation at call sites. In addition to the usage restrictions imposed by its @Target meta-annotation, compilers are required to implement additional usage restrictions on this annotation type; it is a compile-time error if a method or constructor declaration is annotated with a @SafeVarargs annotation, and either: the declaration is a fixed-arity method or constructor the declaration is a variable-arity method that is neitherstatic nor final. Compilers are encouraged to issue warnings when this annotation type is applied to a method or constructor declaration where: The variable-arity parameter has a reifiable element type, which includes primitive types, Object, and String. (The unchecked warnings this annotation type suppresses already do not occur for a reifiable element type.) The body of the method or constructor declaration performs potentially unsafe operations, such as an assignment to an element of the variable-arity parameter's array that generates an unchecked warning.Future versions of the platform may mandate compiler errors for such unsafe operations.

Following up on earlier work, the javac team has pushed a new implementation of Project Coin's simplified varargs method invocation feature (jdk, langtools). The changes are scheduled to appear in...

Java

Project Coin Improving Multi-catch and More Precise Rethrow

We've been working on some improvements to the multi-catch and more precise rethrow feature and are planning to push the changes soon. First, as long as a catch parameter is effectively final (in other words not reassigned inside the catch block), the more precise analysis will be enabled if the exception is rethrown. An explicit final modifier will no longer be needed to enable the more precise analysis.As pointed out in the original proposal form for Improved Exception Handling for Java, the more precise exception analysis can cause programs that currently compile to stop compiling since more unreachable code is identified. While the general evolution policy of the JDK does not promise source compatibility across releases, gratuitously breaking compatibility should be avoided. Fortunately, after examining millions of lines of code in a diverse set of code bases, include the JDK, no instances where the more precise analysis would cause an actual source incompatibility were found. (Details of the analysis will be written up later.)Second, the catch parameter of a multi-catch clause (catch(Exception1 | Exception2 e) {...}) will be regarded as implicitly final; the compiler will reject code that writes to such a catch parameter. Consequently, an explicit final modifier will no longer be needed in this case, although it will remain legal. This provides a more concise syntax for multi-catch in JDK 7 while preserving flexibility to more fully support disjunctive types in later JDK releases.

We've been working on some improvements to the multi-catch and more precise rethrow feature and are planning to push the changes soon. First, as long as a catch parameter is effectively final (in...

Java

JVM Language Summit: Numbers big and fixed

Last week, I enjoyed attending the 2010 JVM Language Summit. Some of the requests from the "what the JVM needs" session could be addressed by a few additional numerical libraries in the platform.The default integer arithmetic in many languages conceptually doesn't overflow, analogous to operating on Java's java.math.BigInteger objects rather than 32-bit int or 64-bit long values. However, small integers that enjoy hardware support on commodity CPUs are much more commonly operated on than big numbers which require multi-word support. Ideally, conceptually unbounded integers would still run very fast when they were small enough without consuming either excess CPU cycles or excess memory.In the limit, fixnums would result, where the transitions between small ↔ big integers were managed and optimized by the JVM. Until that happy day, internally BigDecimal manages long ↔ BigInteger transitions and potential future library additions could ease independently coding up similar logic.Semantically a BigDecimal is a BigInteger significand/mantissa along with an int scale (negated exponent). If the scale/exponent is zero, then exact integer results can be computed. The BigDecimal implementation in the JDK internally often uses a long where possible to hold the significand value, failing over to allocating and operating on a BigInteger value when needed. The compact long representation is seamlessly supported in arithmetic and other operations.BigDecimal is not an ideal type for providing pure integer arithmetic since BigDecimal has many operations unneeded and inappropriate for that use and because each BigDecimal object has various fields other than the ones holding the integer value; however, the class comes with the JDK and may perform adequately out of the box.The algorithms used for the long overflow checking in BigDecimal are adapted from the indispensable bit-twiddling tome Hacker's Delight.A few conference attendees expressed interest in an API around integer overflow detection. Represented as a Java API, the functionality might look like:/\*\* \* Returns the sum of the arguments, throwing an ArithmeticException \* if the exact sum is out of {@code int} range. \* @return the sum of the arguments, throwing an ArithmeticException \* if the exact sum is out of {@code int} range. \* @throws ArithmeticException if the exact sum is out of {@code int} range \*/public static int addExact(int a, int b) throws ArithmeticExceptionThe source code of such a method could use the Hacker's Delight techniques while a JVM could intrinsify the functionality to a processor-optimized idiom.There are some design choices even in this simple method. For example, instead of ArithmeticException, a new subclass of that exception called, say, IntegerOverflow, could be thrown instead. Such a subclass could offer the ability to store the original operands to facilitate continuing the computation in a wider type. (An unfriendly API design for the purposes at hand would be for addExact to have int parameters but return a java.lang.Integer, with null being used to indicate overflow occurred!)While I don't recall it being explicitly mentioned at the conference, a piece of similar functionality is accessing the high-order 64 bits of a full 64 × 64 → 128 bit multiply (5100935).Adding these low-level library operations to the platform would be a fun project!

Last week, I enjoyed attending the 2010 JVM Language Summit. Some of the requests from the "what the JVM needs" session could be addressed by a few additional numerical libraries in the platform. The...

Java

Writing javac regression and unit tests for new language features

With Java language changes in progress for JDK 7, such as Project Coin'sstrings in switch, improved exception handling, and try-with-resources statement, writing effective regression and unit tests for javac is an integral component of developing the new language features.Unit and regression tests differ from conformance tests. Unit and regression tests focus on achieving code coverage on an implementation while conformance tests focus on specification coverage, having tests that probe a high percentage of the testable assertions in the specification.The underlying functionality probed by both styles of testing is shared (source code is accepted or rejected, compiled class files do or do not implement the required semantics), but the different test methodologies differently categorize the space of concerns to be spanned.For more information on the methodology of conformance testing, see these blog entries about finding assertions in the Java language specification and on direct and derived assertions.While there is overlap in the functionality testable by unit/regression tests and conformance tests, a key difference is that unit/regression tests can be written against implementation-specific functionality while conformance tests must be valid for any implementation (since all implementations are written against same specification). For example, a conformance test suite, like the JCK compiler test suite, can test that a particular source file is properly accepted or rejected by a compiler. Testing that the compiled class file(s) accurately implement the semantics of the source is also in-bounds for a conformance test. (The JCK test suite uses an interview process to configure the test suite to work with a particular compiler so that compiler-specific properties such as how acceptance/rejection of sources is indicated can be accommodated.)The JCK compiler test suite includes both positive tests (testing that programs that are in the language are properly accepted) and negative tests (testing that programs that are outside the language are properly rejected). Besides properties that can be verified in conformance-style testing, the regression and unit tests for a new language feature as implemented in javac also need to verify that various javac-specific properties hold. For both positive and negative aspects of a language feature, unit and regression tests can cover all properties of interest for a particular compiler. A subset of those properties are also in the domain of conformance tests:Negative TestsConformance and unit/regression: Invalid source files are rejected. This includes that sources only valid under, say, -source 7, are rejected when javac is run under -source 6 and earlier source settings.Unit/regression only: The expected error messages are provided that reference the right source locations.Positive TestsConformance and unit/regression: Valid source is compiled.Conformance and/or unit/regression: Proper modeling of the new language construct. Depending on the language feature, the feature may be surfaced in the standard language model API javax.lang.model.\*, which can be tested with a conformance test. However, aspects of a language feature reflected in the javactree API are only testable with regression or unit tests.Conformance and unit/regressoin: Resulting class files are structurally well-formed.This includes passing verification and other checks done by the JVM upon loading and linking.Unit/regression only: Resulting class files follow compiler-specific idioms.There are many ways a compiler can transform source code into valid class files which have the correct operational semantics.Conformance and unit/regression: Resulting class file(s) when run have correct operational semantics. (Being able to run a class file implies the class file is well-formed.) Tests of operational semantics should be structured so that the code in question must positively run for the test to pass. For example, if a piece of code, like a string switch, was erroneously compiled to no byte codes, the test should fail.An example of a negative test verifying both conformance and implementation-specific properties is a test included in the changeset for strings in switch:/* * @test /nodynamiccopyright/ * @bug 6827009 * @summary Check for case labels of different types. * @compile/fail -source 6 BadlyTypedLabel1.java * @compile/fail/ref=BadlyTypedLabel1.out -XDrawDiagnostics BadlyTypedLabel1.java */class BadlyTypedLabel1 { String m(String s) { switch(s) { case "Hello World": return(s); case 42: return ("Don't forget your towel!"); } }}Decoding the initial comments as jtreg directives, @test indicates the file is a jtreg test; jtreg is the test harness used for JDK regression and unit tests. By default, jtreg builds the source file and run its main method; however, for compiler tests that combination of actions is often inappropriate. The directive@compile/fail -source 6 BadlyTypedLabel1.javameans that jtreg should compile the indicated source and expect a failure, meaning the overall test will fail if the compile succeeds. In this case, the @compile/fail directive tests that a string switch is rejected under -source 6. The next directive@compile/fail/ref=BadlyTypedLabel1.out -XDrawDiagnostics BadlyTypedLabel1.javais more specific. Not only must the compilation fail, but as specified in the ref= option to @compile/fail, the reported error messages must match the expected output in file BadlyTypedLabel1.out:BadlyTypedLabel1.java:13:14: compiler.err.prob.found.req: (compiler.misc.incompatible.types), int, java.lang.String1 error The -XDrawDiagnostics option to javac turns on "raw diagnostics" where the source location and resource keys are output instead of the localized text of the error messages. (For more information about javac diagnostics see Improving javac diagnostics and Playing with formatters.) The effect of the second @compile/fail line is thus to verify the proper error message is generated at "case 42:" where an integer label erroneously occurs inside a string switch. Since this kind of test relies on checking messages reporting at particular code locations, no explicit copyright occurs in such test files so that the golden output files do not have to updated if the length of the copyright notice changes; "/nodynamiccopyright/" indicates the explicit copyright is omitted for this reason.For positive tests, a @compile directive without /fail declares a compile must succeed for the overall test to pass.Modeling tests can generally be run as annotation processors over selected source code. Since annotation processing is built into javac as of JDK 6, @compile directives are one option for running annotation processing tests.The tree API can also be tested via annotation processors by using the Trees class to bridge between javax.lang.model.element.Element objects and the corresponding abstract syntax trees, a technique also used in some regression tests for ordinary javac bug fixes.The regression tests for multi-catch include checks for generating idiomatic class files.There are a variety of ways the multi-catch aspect of improved exception handling could be implemented. One way to compile multi-catch would be to duplicate the code blocks for each exception, in source terms treatingtry {...}catch (A | B except) {Statements} as try {...}catch (A except) {Statements}catch (B except) {Statements}However, for javac we do not consider this compilation strategy to result in an acceptable class file. (There are many implicit requirements for generating class files from Java source code, but generally no explicit specification for the compiler's behavior.) Instead, for javac we require catching the multiple exceptions to be represented in the class file as repeated entries in the table of exception ranges stored in the class file to map exceptions to their handling catch blocks.This check is implemented by using javap APIs to introspect on the structure of the exception table.Testing operational semantics can be challenging due to the difficulty of computing a known-good result all code paths of interest. For strings in switch, testing the operational semantics of the generated code included comparing the control paths taken through a switch on an enum type with the control paths taken through an analogous switch on the names of the enum constants:private static int enumSwitch(MetaSynVar msv) { int result = 0; switch(msv) { case FOO: result |= (1

With Java language changes in progress for JDK 7, such as Project Coin's title="Project Coin: Anatomy of adding strings in switch to javac">strings in switch, title="Project Coin: multi-catch and final...

Java

Project Coin: Updated ARM Spec

Starting with Project Coin proposal for Automatic Resource Management (ARM) (Google Docs version), in consultation with Josh Bloch, Maurizio, Jon, and others, Alex and I have produced a specification for ARM blocks that is much closer to Java Language Specification (JLS) style and rigor.The specification involves changes to the existing JLS section §14.20 "The try statement," and will eventually introduce a new subsection §14.20.3 "Execution of try-with-resources," although the specification below is not partitioned as such.Non-normative comments about the specification text below appear inside "[]".Differences between the new specification and the earlier Project Coin proposal for ARM are discussed after the specification.SYNTAX: The existing set of grammar productions for TryStatement in JLS §14.20 is augmented with:TryStatement:try ResourceSpecification Block Catchesopt FinallyoptSupporting new grammar productions are added:ResourceSpecification:( Resources )Resources:ResourceResource ; ResourcesResource:VariableModifiers Type VariableDeclaratorId = ExpressionExpression[An implication of the combined grammar is that a try statement must have at least one of a catch clause, a finally block, and a resource specification. Furthermore, it is permissible for a try statement to have exactly one of these three components. Note that it is illegal to have a trailing semi-colon in the resource specification.] A try-with-resources statement has a resource specification that expresses resources to be automatically closed at the end of the Block. A resource specification declares one or more local variables and/or has one or more expressions, each of whose type must be a subtype of AutoCloseable or a compile-time error occurs.If a resource specification declares a variable, the variable must not have the same name as a variable declared earlier in the resource specification, a local variable, or parameter of the method or initializer block immediately enclosing the try statement, or a compile-time error occurs.The scope of a variable declared in a resource specification of a try-with-resources statement (§14.20) is from the declaration rightward over the remainder of the resource specification and the entire Block associated with the try. Within the Block of the try, the name of the variable may not be redeclared as a local variable of the directly enclosing method or initializer block, nor may it be redeclared as an exception parameter of a catch clause in a try statement of the directly enclosing method or initializer block, nor may it be redeclared as a variable in the resource specification, or a compile-time error occurs. However, a variable declared in a resource specification may be shadowed (§6.3.1) anywhere inside a class declaration nested within the Block of the try.The meaning of a try-with-resources statement with a Catches clause or Finally block is given by translation to a try-with-resources statement with no Catches clause or Finally block:try ResourceSpecification  BlockCatchesoptFinallyopt⇒try {   try ResourceSpecification   Block}CatchesoptFinallyoptIn a try-with-resources statement that manages a single resource:If the initialization of the resource completes abruptly because of a throw of a value V, or if the Block of the try-with-resources statement completes abruptly because of a throw of a value V and the automatic closing of the resource completes normally, then the try-with-resources statement completes abruptly because of the throw of value V. If the Block of the try-with-resources statement completes abruptly because of a throw of a value V1, and the automatic closing of the resource completes abruptly because of a throw of a value V2, then the try-with-resources statement completes abruptly because of the throw of value V1, provided that V2 is an Exception. In this case, V2 is added to the suppressed exception list of V1. If V2 is an error (i.e. a Throwable that is not an Exception), then the try-with-resources statement completes abruptly because of the throw of value V2. In this case, V1 is not suppressed by V2. If a try-with-resources statement that manages multiple resources: If the initialization of a resource completes abruptly because of a throw of a value V, or if the Block of the try-with-resources statement completes abruptly because of a throw of a value V (which implies that the initialization of all resources completed normally) and the automatic closings of all resources completes normally, then the try-with-resources statement completes abruptly because of the throw of value V.If the Block of the try-with-resources statement completes abruptly because of a throw of a value V1, and the automatic closings of one or more resources (that were previously successfully initialized) complete abruptly because of throws of values V2...Vn, then the try-with-resources statement completes abruptly because of the throw of a value Vi (1 ≤ i ≤ n) determined by the translation below.The exceptions that can be thrown by a try-with-resources statement are the exceptions that can thrown by the Block of the try-with-resources statement plus the union of the exceptions that can be thrown by the automatic closing of the resources themselves. Regardless of the number of resources managed by a try-with-resources statement, it is possible for a Catchesopt clause to catch an exception due to initialization or automatic closing of any resource.A try-with-resources statement with a ResourceSpecification clause that declares multiple Resources is treated as if it were multiple try-with-resources statements, each of which has a ResourceSpecification clause that declares a single Resource. When a try-with-resources statement with n Resources (n > 1) is translated, the result is a try-with-resources statement with n-1 Resources. After n such translations, there are n nested try-catch-finally statements, and the overall translation is complete.The meaning of a try-with-resources statement with a ResourceSpecification clause and no Catches clause or Finally block is given by translation to a local variable declaration and a try-catch-finally statement. During translation, if the ResourceSpecification clause declares one Resource, then the try-catch-finally statement is not a try-with-resources statement, and ResourceSpecificationtail is empty. If the ResourceSpecification clause declares n Resources, then the try-catch-finally statement is treated as if it were a try-with-resources-catch-finally statement, where ResourceSpecificationtail is a ResourceSpecification consisting of the 2nd, 3rd, ..., nth Resources in order. The translation is as follows, where the identifiers #primaryException, #t, and #suppressedException are fresh:try ResourceSpecification  Block⇒{final VariableModifiers_minus_final R #resource = Expression;Throwable #primaryException = null;try ResourceSpecificationtail  Blockcatch (final Throwable #t) {  #primaryException = t;  throw #t;} finally {  if (#primaryException != null) {    try {      #resource.close();    } catch(Exception #suppressedException) {      #primaryException.addSuppressedException(#suppressedException);    }  } else {    #resource.close();  }}If the Resource being translated declares a variable, then VariableModifiers_minus_final is the set of modifiers on the variable (except for final if present); R is the type of the variable declaration; and #resource is the name of the variable declared in the Resource.Discussion: Resource declarations in a resource specification are implicitly final. For consistency with existing declarations that have implicit modifiers, it is legal (though discouraged) for a programmer to provide an explicit "final" modifier. By allowing non-final modifiers, annotations such as @SuppressWarnings will be preserved on the translated code. It is unlikely that the Java programming language will ever ascribe a meaning to an explicit final modifier in this location other than the traditional meaning.[Unlike the new meaning ascribed to a final exception parameter.]Discussion: Unlike the fresh identifier in the translation of the enhanced-for statement, the #resource variable is in scope in the Block of a try-with-resources statement.If the Resource being translated is an Expression, then the translation includes an local variable declaration for which VariableModifiers_minus_final is empty; the type R is the type of the Expression (under the condition that the Expression is assigned to a variable of type AutoCloseable); and #resource is a fresh identifier.Discussion: The method Throwable.addSuppressedException has a parameter of type Throwable, but the translation is such that only an Exception from #resource.close() will be passed for suppression. In the judgment of the designers of the Java programming language, an Error due to automatic closing of a resource is sufficiently serious that it should not be automatically suppressed in favor of an exception from the Block or the initialization or automatic closing of lexically rightward resources.[However, perhaps such an Error should instead be recorded as suppressing an exception from the Block or other lexically rightward component.]Discussion: This translation exploits the improved precision of exception analysis now triggered by the rethrow of a final exception parameter.The reachability and definite assignment rules for the try statement with a resource specification are implicitly specified by the translations above.Compared to the earlier proposal, this draft specification:Assumes the revised supporting API with java.lang.AutoCloseable as the type indicating participation in the new language feature.Changes the official grammar for a declared resource fromLocalVariableDeclarationtoVariableModifiers Type VariableDeclaratorId = ExpressionThe former syntactically allowed code likeAutoCloseable a, b, cwhich would not be useful in this context.Preserves modifiers on explicitly declared resources, which implies @SuppressWarnings on a resource should have the intended effect.States how the exception behavior of close methods is accounted for in determining the set of exceptions a try-with-resource statement can throw.Gives a more precise determination of the type used for the local variable holding a resource given as an Expression. This precision is important to allow accurate exception information to be computed.Provides typing constraints so that type inference works as expected if the Expression given as a Resource in a ResourceSpecification is, say, a generic method or null.Compiler changes implementing this revised specification remain in progress. After experience is gained with the initial implementation, I expect various changes to the feature to be contemplated:Dropping support for a resource to be specified as a general Expression. Nontrivial specification and implementation complexities arise from allowing a general Expression to be used as resource. Allowing a restricted expression that was just a name may provide nearly all the additional flexibility at marginal additional implementation and specification impact.Adjustments to the suppressed exception logic: in the present specification, an incoming primary exception will suppress an Exception thrown by a close method; however, if the close method throws an error, that error is propagated out without suppressing an incoming primary exception.Possible alternatives include having a primary exception in a try-with-resource statement suppress all subsequent Throwables originating in the statement and having a non-Exception thrown by a close suppress any incoming primary exception. These alternatives could be implemented by replacing the translated code    try {      #resource.close();    } catch(Exception #suppressedException) {      #primaryException.addSuppressedException(#suppressedException);    }with    try {      #resource.close();    } catch(Throwable #suppressedException) {      #primaryException.addSuppressedException(#suppressedException);    }or    try {      #resource.close();    } catch(Exception #suppressedException) {      #primaryException.addSuppressedException(#suppressedException);    } catch(Throwable #throwable) {      #throwable.addSuppressedException(#primaryException);      throw #throwable;    }respectively.

Starting with Project Coin proposal for Automatic Resource Management (ARM) (Google Docs version), in consultation with Josh Bloch,Maurizio,Jon,and others, Alex and I have produced a specification...

JavaOne

JavaOne 2010 Talks Scheduled

My two JavaOne talks this year have now been scheduled:Monday, September 20, 11:30AM, Project Coin: Small Language Changes for JDK 7Abstract: Project Coin is an effort to select and implement a set of small language changes to enhance programmer productivity in JDK 7. Project Coin language changes include improved integer literals, strings in switch, and the diamond operator. This session will describe the language changes and demo IDE support. In addition, aspects of the selection process and criteria for general language evolution will be discussed.Tuesday, September 21, 8:00PM, Patents, Copyrights, and TMs: An Intellectual Property Primer for Engineers Abstract: Increasingly, software engineers interact with a complicated landscape of intellectual property (IP), from software patents, to various copyright licenses, to trademarks and trade secrets. Formulated in terms familiar to engineers, this session will summarize the different types of intellectual property, with a focus on U.S. law. Copyright terms, criteria for patentability, and freedom to operate will all be discussed with examples. The speaker is not a lawyer (he's an engineer) and this talk (and this abstract) does not constitute legal advice. However, the speaker has been issued several U.S. patents and has studied IP in a number of graduate courses.Lots to do between now and September; see you in San Francisco!

My two JavaOne talks this year have now been scheduled: Monday, September 20, 11:30AM, Project Coin: Small Language Changes for JDK 7 Abstract: Project Coin is an effort to select and implement a set of...

Java

Project Coin: Bringing it to a Close(able)

As a follow-up to the initial API changes to support automatic resource management (ARM) I wrote an annotation processor, CloseableFinder, to programmatically look for types that were candidates to be retrofitted as Closeable or AutoCloseable.The processor issues a note for a type that has a public no-args instance method returning void whose name is "close" where the type does not already implement/extend Closeable or AutoCloseable. Based on the exceptions a close method is declared to throw, the processor outputs whether the type is a candidate to be retrofitting to just AutoCloseable or to either of Closeable and AutoCloseable. Which of Closeable and AutoCloseable is more appropriate can depend on the semantics of the close method not captured in its signature. For example, Closeable.close is defined to be idempotent, repeated calls to close have no effect. If a close method is defined to not be idempotent, without changing the specification the type can only be correctly retrofitted to AutoCloseable.To use the processor, first compile it and then configure your compiler or IDE to run the processor.The processor can be compiled under JDK 6. Once compiled, it can be run either under JDK 6 or under a JDK 7 build that has the AutoCloseable interface; the processor will configure itself appropriately based on the JDK version it is running under.For javac, the command line to run the processor can look like: javac -proc:only \\ -processor CloseableFinder \\ -processorpath Path_to_processor \\List_of_filesA thread on build-dev discusses how to run an annotation processor over the JDK sources; a larger than default heap size may be needed to process all the files in one command.When run over the JDK 7 sources, the processor finds many candidate types to be retrofitted. After consulting with the teams in question, an additional nine types were retrofitted to work with ARM, two in java.beans, two in java.io, one in java.util, and four in javax.sound; these additional retrofittings have been pushed into JDK 7 and will appear in subsequent builds.Besides the potential updating of JDBC at some point in the future, other significant retrofitting of JDK classes in java.\* and javax.\* to AutoCloseable/Closeable should not be expected. Unofficial JDK APIs in other namespaces might be examined for retrofitting in the future.The compiler changes to support the ARM language feature remain in progress.

As a follow-up to the title="Project Coin: ARM API">initial API changes to support automatic resource management (ARM) I wrote an annotation processor, CloseableFinder, to programmatically look...

Java

Project Coin: ARM API

The initial API changes to support the Project Coin feature automatic resource management (ARM) blocks have been pushed into JDK 7 (langtools, jdk) and will appear in subsequent builds.The

The initial API changes to support the Project Coin feature automatic resource management (ARM) blocks have been pushed into JDK 7 (langtools, jdk) and will appear in subsequent builds. The title="Project Coin: Support Automatic Resource Management (ARM) blocks in the compiler">corresponding compiler changes to support the actual language feature remain in progress. The initial API work to support ARM was divided into two pieces, title="Project Coin: Add essential API support for Automatic Resource Management (ARM) blocks">essential API support and title="Project Coin: Retrofit Automatic Resource Management (ARM) support onto platform APIs">retrofitting platform classes. The essential support includes: A new interface java.lang.AutoCloseable which defines a single method void close() throws Exception A new enum constant in the language model: javax.lang.model.element.ElementKind.RESOURCE_VARIABLE Methods on java.lang.Throwable to add and retrieve information about suppressed exceptions, including printing out suppressed exceptions in stack traces. The retrofitting includes: Having java.io.Closeable extend java.lang.AutoCloseable. (From a typing perspective, a subtype of AutoCloseable can be declared to throw fewer exceptions than the supertype. Therefore is is fine for the close method in AutoCloseable to throw Exception and the close method in Closeable to throw the more specific IOException. It would even be fine for the close method in a subtype of AutoCloseable to be declared to throw no exceptions at all.) Adding a close method to java.nio.channels.FileLock and having FileLock implement AutoCloseable. Adding Closeable as an interface implemented by javax.imageio.stream.ImageInputStream. Other platform classes may be retrofitted to implement AutoCloseable or Closable in future builds. Compared to the API support in earlier versions of the ARM proposal, the top-level interface to mark participation in ARM is in package java.lang rather than its own package and, after consultation with the JDBC and graphics teams, neither java.sql.\* nor java.awt.Graphics were retrofitted for ARM.

OpenJDK

OpenJDK 6: b20 regression test results

Running with the usual jtreg flags, "-a -ignore:quiet" in all repositories and adding "-s -ea -esa" for langtools, the basic regression test results on Linux forOpenJDK 6 build 20 are:HotSpot, 85 tests passed.Langtools, 1,365 tests passed.JDK, 3,273 tests pass, 33 fail, and 2 have errors.All the HotSpot tests continue to pass and more tests were added:0: b19-hotspot/summary.txt pass: 621: b20-hotspot/summary.txt pass: 850 1 Test--- pass compiler/6663854/Test6663854.java--- pass compiler/6769124/TestArrayCopy6769124.java--- pass compiler/6769124/TestDeoptInt6769124.java--- pass compiler/6769124/TestUnalignedLoad6769124.java--- pass compiler/6792161/Test6792161.java--- pass compiler/6866651/Test.java--- pass compiler/6877254/Test.java--- pass compiler/6879902/Test6879902.java--- pass compiler/6880034/Test6880034.java--- pass compiler/6885584/Test6885584.java--- pass compiler/6891750/Test6891750.java--- pass compiler/6895383/Test.java--- pass compiler/6896727/Test.java--- pass compiler/6901572/Test.java--- pass compiler/6909839/Test6909839.java--- pass compiler/6910484/Test.java--- pass compiler/6910605/Test.java--- pass compiler/6910618/Test.java--- pass compiler/6912517/Test.java--- pass compiler/6916644/Test6916644.java--- pass compiler/6921969/TestMultiplyLongHiZero.java--- pass compiler/6930043/Test6930043.java--- pass compiler/6935535/Test.java23 differencesIn langtools all the tests continue to pass and a few tests were added:0: b19-langtools/summary.txt pass: 1,3591: b20-langtools/summary.txt pass: 1,3650 1 Test--- pass tools/javac/cast/6548436/T6548436a.java--- pass tools/javac/cast/6548436/T6548436b.java--- pass tools/javac/cast/6548436/T6548436c.java--- pass tools/javac/cast/6548436/T6548436d.java--- pass tools/javac/processing/6499119/ClassProcessor.java--- pass tools/javac/processing/T6920317.java6 differencesAnd in jdk a few tests were also added by virtue of the backports. Otherwise, the existing tests have generally consistent results.As done starting with build 18, the test run below was executed outside of Sun's and Oracle's wide-area network using generally accessible hosts for the network configuration file; to specify the networking configuratuion file, pass a "-e JTREG_TESTENV=Path_to_file" option to jtreg.0: b19-jdk/summary.txt pass: 3,261; fail: 28; error: 51: b20-jdk/summary.txt pass: 3,273; fail: 33; error: 20 1 Test--- pass com/sun/java/swing/plaf/nimbus/ColorCustomizationTest.java--- pass com/sun/java/swing/plaf/nimbus/Test6919629.javaerror pass java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowBlockingTest.javaerror pass java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowRetaining.java--- pass java/awt/Focus/FrameJumpingToMouse/FrameJumpingToMouse.java--- pass java/awt/Focus/NonFocusableWindowTest/NoEventsTest.javaerror fail java/awt/Focus/NonFocusableWindowTest/NonfocusableOwnerTest.javapass --- java/awt/Focus/NonFocusableWindowTest/Test.javafail pass java/awt/Focus/TypeAhead/TestFocusFreeze.java--- pass java/awt/Focus/WrongKeyTypedConsumedTest/WrongKeyTypedConsumedTest.javapass fail java/awt/Frame/MaximizedToIconified/MaximizedToIconified.java--- fail java/awt/Graphics2D/DrawString/RotTransText.javapass fail java/awt/TextArea/UsingWithMouse/SelectionAutoscrollTest.html--- fail java/awt/font/Rotate/TranslatedOutlineTest.javapass error java/nio/channels/SocketChannel/Connect.javafail pass java/nio/charset/Charset/Contains.javapass fail java/util/Locale/Bug4184873Test.java--- pass javax/swing/MultiUIDefaults/4300666/bug4300666.java--- pass javax/swing/MultiUIDefaults/4331767/bug4331767.java--- pass javax/swing/MultiUIDefaults/Test6860438.java--- fail javax/swing/plaf/synth/Test6933784.java--- pass sun/pisces/DashStrokeTest.javaerror pass sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java--- pass sun/security/tools/jarsigner/diffend.sh--- pass sun/security/validator/CertReplace.java--- pass sun/security/validator/SameDN.java26 differences

Running with the usual jtreg flags, "-a -ignore:quiet" in all repositories and adding "-s -ea -esa" for langtools, the basic regression test results on Linux forOpenJDK 6 build 20 are: HotSpot, 85...

Java

Syntax Sin Tax

In various forums, recent discussion about Project Lambda have commented on, and often noted in dismay, the current syntax for lambda expressions in the initial prototype."Don't panic!" is advice as valid for work on language evolution as on any other endeavor.Since syntax is the easiest aspect of a language change to form an opinion on, it is the aspect of language changes most susceptible to bikeshedding.While syntax is an important component of language changes, it is far from the only important component; the semantics matter too!Fixation on the syntax of a feature early in its development is premature and counterproductive.Having a prototype to gain actual experience with the feature is more valuable than continued informed analysis and commentary without working code.I believe this diagram included in a talk on the Project Coin language change process holds for language changes in Java more generally:While proposing and commenting can be helpful, the effort required to produce a prototype is disproportionally beneficial and the incremental effort using the prototype has even higher leverage. Experience trumps speculation.And not all efforts lead to positive results; complaining and obstructing alone are rarely helpful contributions.Just the engineering needed to fully deliver a language changes involves many coordinated deliverables even without including documentation, samples and user guides.A consequence of an open style of development is that changes are pushed early, even if not often, and early changes imply the full fit and finish of a final product will of necessity not be present from the beginning.Long digressions on small issues, syntactical or otherwise, are a distraction from the other work that needs to get done.True participation in a project means participating in the work of the project.The work of a language change involves much more than just discussing syntax.Once a prototype exists, the most helpful contribution is to use the prototype and report experiences using it.

In various forums, recent discussion about Project Lambda have commented on, and often noted in dismay, the current syntax for lambda expressions in the initial prototype."Don't panic!" is advice as...

Java

Project Coin: Inducing contributory heap pollution

US patent law defines various kinds of patent infringement, as do other jurisdictions. (I am not a lawyer! This is not legal advice! Check your local listings! Don't kill kittens! Example being used for analogy purposes only! ) One can infringe on a patent directly, say, by making, using, selling, offering to sell, or importing a patented widget without a suitable license. A computer scientist looking to infringe might (erroneously) believe the conditions for infringement can be circumvented by applying the familiar technique of adding a level of indirection. For example, one indirection would be selling 90% percent of the patented widget, leaving the end-user to complete the final 10% and thereby infringe. Such contributory infringement is also verboten. Likewise, providing step-by-step instructions on how to infringe the patent is outlawed as inducing infringement. Putting both techniques together, inducing contributory infringement is also disallowed.Starting in JDK 5, a compiler must issue mandatory unchecked warnings at sites of possible heap pollution:Java Language Specification, Third Edition — §4.12.2.1 Heap PollutionIt is possible that a variable of a parameterized type refers to an object that is not of that parameterized type. This situation is known as heap pollution. This situation can only occur if the program performed some operation that would give rise to an unchecked warning at compile-time.One case where unchecked warnings occur is a call to a varargs method where the type of the variable argument is not reifiable. That is, where the type information for the parameter is not fully expressible at runtime due to the erasure of generics. Varargs are implemented using arrays and arrays are reified; that is, the component type of an array is stored internally and used when needed for various type checks at runtime.However, the type information stored for an array's component type cannot store the information needed to represent a non-reifiable parameterized type.The mismatch between reified arrays being used to pass non-reified (and non-reifiable) parameterized types is the basis for the unchecked warnings when such conflicted methods are called. However in JDK 5, only calling one of conflicted methods causes a compile-time warning; declaring such a method doesn't lead to any similar warning.This is analogous to the compiler only warning of direct patent infringement, while ignoring or being oblivious too indirect infringement. While the mere existence of a conflicted varargs method does not cause heap pollution per se, its existence contributes to heap pollution by providing an easy way to cause heap pollution to occur and induces heap pollution by offering the method to be called.By this reasoning, if method calls that cause heap pollution deserve a compiler warning, so do method declarations which induce contributory heap pollution.Additionally, the warnings issued for some calls to varargs methods involving heap pollution are arguably spurious since nothing bad happens. For example, calling various useful helper varargs methods in the platform trigger unchecked warnings, including:public static <T> List<T> Arrays.asList(T... a)public static <T> boolean Collections.addAll(Collection<? super T> c, T... elements)public static <E extends Enum<E>> EnumSet<E> EnumSet.of(E first, E... rest)These three methods all iterate over the varargs array pulling out the elements in turn and processing them. If the varargs array is constructed by the compiler using proper type inference, the bodies of the methods won't experience any ClassCastExceptions due to handling of the array's elements.Currently, to eliminate the warnings associated with calling these methods, each call site needs a @SuppressWarnings("unchecked") annotation.To address these usability issues with varargs, Project Coin accepted simplifying varargs as one if the project's changes. The initial prototype version of this feature pushed by Maurizio, has several parts:A new mandatory compiler warning is generated on declaration sites of problematic varargs methods that are able to induce contributory heap pollution.The ability to suppress those mandatory warnings at a declaration site using an @SuppressWarnings("varargs") annotation. The warnings may also be suppressing using the -Xlint:-varargs option to the compiler.If the @SuppressWarnings("varargs") annotation is used on a problematic varargs method declaration, the unchecked warnings at call sites of that method are also suppressed.This prototype will allow experience to be gained with the algorithms to detect and suppress the new mandatory warnings. However, the annotation used to suppress the warnings should be part of the varargs method's contract, denoting that when a compiler-constructed array is passed to the method nothing bad will happen, for a suitable definition of nothing bad. Therefore, an @Documented annotation type needs to be used for this purpose and SuppressWarnings is not @Documented. Additionally, the suppressing annotation for varags should also be @Inherited so the method implementation restrictions are passed on to subclasses.Subsequent design discussions about the new annotation type with the properties in question to suppress the varargs warnings as well as criteria for the annotation to be correctly applied can occur on the Project Coin mailing list.

US patent law defines various kinds of patent infringement, as do other jurisdictions. (I am not a lawyer! This is not legal advice! Check your local listings! Don't kill kittens! Example being used...

OpenJDK

Draft of Restarted "OpenJDK Developers' Guide" available for discussion

I've been working on a restarted version of the "OpenJDK Developers' Guide" and I have a draft far enough along for general discussion. The content of the existing guide is primarily logistical and procedural in nature; in time, I plan to migrate this information to a JDK 7 specific page because many of the details are release-specific. The new guide is more conceptual and once completed is intended to be able to last for several releases without major updating.The table of contents of draft version 0.775 is:PrefaceOpenJDK Development MottoKinds of ReleasesGeneral Evolution PolicyKinds of CompatibilitySource CompatibilityBinary CompatibilityBehavioral CompatibilityAPI Compatibility Case StudyOther Kinds of CompatibilityManaging CompatibilityKinds of InterfacesWhat is an interface?Specification = Syntax + SemanticsOfficial and Unofficial InterfacesImporting and Exporting InterfacesDeveloping a ChangeCoding GuidelinesSource Code ManagementCode ReviewsRegression and Unit TestsDeprecationTODOThe full draft is available from here.The compatibility sections are currently more fully developed than the ones about developing a change.(Long-time readers of this blog will be familiar with earlier versions of some of the material.)All level of feedback is welcome, from correcting typos, to stylistic suggestions, to proposals for new sections.Significant feedback should be sent to the project alias for the guide.Initially, I plan to maintain the guide as an HTML file and publish new versions as needed. Over time, guide maintenance may transition to more formal version control, such as a small Mercurial repository or a wiki.

I've been working on a restarted version of the "OpenJDK Developers' Guide" and I have a draft far enough along for general discussion. The content of the existing guide is primarily logistical and...

OpenJDK

OpenJDK 6: b19 regression test results

Running with the usual jtreg flags, -a -ignore:quiet in all repositories and adding -s and now also -ea -esa for langtools, the basic regression test results on Linux forOpenJDK 6 build 19 are:HotSpot, 62 tests passed.Langtools, 1,359 tests passed.JDK, 3,261 tests pass, 28 fail, and 5 have errors.All the HotSpot tests continue to pass and more tests were added:0: b18-hotspot/summary.txt pass: 241: b19-hotspot/summary.txt pass: 620 1 Test--- pass compiler/5057225/Test5057225.java--- pass compiler/6378821/Test6378821.java--- pass compiler/6539464/Test.java--- pass compiler/6589834/Test_ia32.java--- pass compiler/6603011/Test.java--- pass compiler/6636138/Test1.java--- pass compiler/6636138/Test2.java--- pass compiler/6711117/Test.java--- pass compiler/6772683/InterruptedTest.java--- pass compiler/6778657/Test.java--- pass compiler/6795161/Test.java--- pass compiler/6795465/Test6795465.java--- pass compiler/6797305/Test6797305.java--- pass compiler/6799693/Test.java--- pass compiler/6800154/Test6800154.java--- pass compiler/6814842/Test6814842.java--- pass compiler/6823354/Test6823354.java--- pass compiler/6823453/Test.java--- pass compiler/6826736/Test.java--- pass compiler/6832293/Test.java--- pass compiler/6833129/Test.java--- pass compiler/6837011/Test6837011.java--- pass compiler/6837094/Test.java--- pass compiler/6843752/Test.java--- pass compiler/6849574/Test.java--- pass compiler/6851282/Test.java--- pass compiler/6852078/Test6852078.java--- pass compiler/6855164/Test.java--- pass compiler/6855215/Test6855215.java--- pass compiler/6857159/Test6857159.java--- pass compiler/6859338/Test6859338.java--- pass compiler/6860469/Test.java--- pass compiler/6863155/Test6863155.java--- pass compiler/6863420/Test.java--- pass compiler/6865031/Test.java--- pass compiler/6875866/Test.java--- pass compiler/6892265/Test.java--- pass gc/6845368/bigobj.java38 differencesIn langtools all the tests continue to pass and a few tests were added:0: b18-langtools/summary.txt pass: 1,3551: b19-langtools/summary.txt pass: 1,3590 1 Test--- pass tools/javac/enum/T6724345.java--- pass tools/javac/processing/6511613/clss41701.java--- pass tools/javac/processing/6634138/T6634138.java--- pass tools/javac/processing/model/util/elements/VacuousEnum.java4 differencesAnd in jdk, many tests were backported form JDK 7 in addition to some new test being added. Otherwise, the existing tests have generally consistent results.As done started with build 18, the test run below was executed outside of Sun's and Oracle's wide-area network using the following contents for the testing network configuration file:host=icedtea.classpath.orgrefusing_host=ns1.gnu.orgfar_host=developer.classpath.orgThe file location to use for the networking configuration can be set by passing a -e JTREG_TESTENV=Path to file option to jtreg.0: b18-jdk/summary.txt pass: 3,148; fail: 19; error: 21: b19-jdk/summary.txt pass: 3,261; fail: 28; error: 50 1 Test--- error java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowBlockingTest.java--- error java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowRetaining.java--- error java/awt/Focus/NonFocusableWindowTest/NonfocusableOwnerTest.java--- pass java/awt/Focus/NonFocusableWindowTest/Test.java--- fail java/awt/Focus/TypeAhead/TestFocusFreeze.java--- fail java/awt/Insets/WindowWithWarningTest/WindowWithWarningTest.htmlfail pass java/awt/event/KeyEvent/CorrectTime/CorrectTime.java--- fail java/awt/xembed/server/RunTestXEmbed.java--- pass java/nio/charset/Charset/AvailableCharsetNames.java--- pass java/nio/charset/Charset/CharsetContainmentTest.java--- fail java/nio/charset/Charset/Contains.java--- pass java/nio/charset/Charset/EmptyCharsetName.java--- pass java/nio/charset/Charset/EncDec.java--- pass java/nio/charset/Charset/IllegalCharsetName.java--- fail java/nio/charset/Charset/NIOCharsetAvailabilityTest.java--- pass java/nio/charset/Charset/NullCharsetName.java--- pass java/nio/charset/Charset/RegisteredCharsets.java--- pass java/nio/charset/Charset/default.sh--- pass java/nio/charset/CharsetDecoder/AverageMax.java--- pass java/nio/charset/CharsetDecoder/EmptyInput.java--- pass java/nio/charset/CharsetEncoder/CanEncode.java--- pass java/nio/charset/CharsetEncoder/Flush.java--- pass java/nio/charset/RemovingSunIO/SunioAlias.java--- pass java/nio/charset/RemovingSunIO/TestCOMP.java--- pass java/nio/charset/RemovingSunIO/TestUnmappableForLength.java--- pass java/nio/charset/coders/BashCache.java--- pass java/nio/charset/coders/BashStreams.java--- pass java/nio/charset/coders/Check.java--- pass java/nio/charset/coders/CheckSJISMappingProp.sh--- pass java/nio/charset/coders/Errors.java--- pass java/nio/charset/coders/FullRead.java--- pass java/nio/charset/coders/IOCoders.java--- pass java/nio/charset/coders/IsLegalReplacement.java--- pass java/nio/charset/coders/ResetISO2022JP.java--- pass java/nio/charset/coders/StreamTimeout.java--- pass java/nio/charset/coders/Surrogates.java--- pass java/nio/charset/spi/basic.shfail pass java/rmi/transport/pinLastArguments/PinLastArguments.java--- pass java/text/Bidi/BidiBug.java--- pass java/text/Bidi/BidiEmbeddingTest.java--- pass java/text/Bidi/BidiSurrogateTest.java--- pass java/util/prefs/CommentsInXml.java--- pass java/util/prefs/ConflictInFlush.java--- pass java/util/prefs/ExportNode.java--- pass java/util/prefs/ExportSubtree.java--- pass java/util/prefs/PrefsSpi.sh--- pass java/util/prefs/RemoveReadOnlyNode.java--- pass java/util/prefs/RemoveUnregedListener.java--- pass java/util/prefs/SerializeExceptions.java--- pass javax/sound/midi/Gervill/AudioFloatFormatConverter/SkipTest.java--- pass javax/sound/midi/Gervill/ModelByteBufferWavetable/OpenStream.java--- pass javax/sound/midi/Gervill/ModelStandardIndexedDirector/ModelStandardIndexedDirectorTest.java--- pass javax/sound/midi/Gervill/SoftChannel/ProgramAndBankChange.java--- pass javax/sound/midi/Gervill/SoftSynthesizer/GetAvailableInstruments2.java--- pass javax/sound/midi/Gervill/SoftSynthesizer/GetLoadedInstruments2.java--- pass javax/sound/midi/Gervill/SoftSynthesizer/GetPropertyInfo.java--- pass javax/sound/midi/Gervill/SoftSynthesizer/TestDisableLoadDefaultSoundbank.java--- pass javax/sound/midi/Gervill/SoftTuning/RealTimeTuning.java--- pass javax/swing/JColorChooser/Test4165217.java--- pass javax/swing/JColorChooser/Test4177735.java--- pass javax/swing/JColorChooser/Test4193384.java--- pass javax/swing/JColorChooser/Test4234761.java--- pass javax/swing/JColorChooser/Test4461329.java--- pass javax/swing/JColorChooser/Test4711996.java--- pass javax/swing/border/Test4120351.java--- pass javax/swing/border/Test4124729.java--- pass javax/swing/border/Test6461042.java--- pass sun/nio/cs/BufferUnderflowEUCTWTest.java--- pass sun/nio/cs/CheckCaseInsensitiveEncAliases.java--- pass sun/nio/cs/CheckHistoricalNames.java--- pass sun/nio/cs/ConvertSingle.java--- pass sun/nio/cs/DecoderOverflow.java--- pass sun/nio/cs/EUCJPUnderflowDecodeTest.java--- pass sun/nio/cs/EucJpLinux0212.java--- pass sun/nio/cs/EucJpLinuxDecoderRecoveryTest.java--- pass sun/nio/cs/EuroConverter.java--- pass sun/nio/cs/FindASCIICodingBugs.java--- pass sun/nio/cs/FindASCIIRangeCodingBugs.java--- pass sun/nio/cs/FindCanEncodeBugs.java--- pass sun/nio/cs/FindDecoderBugs.java--- pass sun/nio/cs/FindEncoderBugs.java--- pass sun/nio/cs/FindOneCharEncoderBugs.java--- pass sun/nio/cs/HWKatakanaMS932EncodeTest.java--- pass sun/nio/cs/ISCIITest.java--- pass sun/nio/cs/ISO8859x.java--- pass sun/nio/cs/JISAutoDetectTest.java--- pass sun/nio/cs/LatinCharReplacementTWTest.java--- pass sun/nio/cs/LeftOverSurrogate.java--- pass sun/nio/cs/MalformedSurrogates.java--- pass sun/nio/cs/NIOJISAutoDetectTest.java--- pass sun/nio/cs/ReadZero.java--- pass sun/nio/cs/SJISCanEncode.java--- pass sun/nio/cs/StreamEncoderClose.java--- pass sun/nio/cs/SurrogateGB18030Test.java--- pass sun/nio/cs/SurrogateTestEUCTW.java--- pass sun/nio/cs/SurrogateTestHKSCS.java--- fail sun/nio/cs/Test4200310.sh--- pass sun/nio/cs/Test4206507.java--- pass sun/nio/cs/Test6254467.java--- pass sun/nio/cs/Test6275027.java--- pass sun/nio/cs/TestCompoundTest.java--- pass sun/nio/cs/TestConverterDroppedCharacters.java--- pass sun/nio/cs/TestCp834_SBCS.java--- pass sun/nio/cs/TestCp93xSISO.java--- pass sun/nio/cs/TestIBMBugs.java--- pass sun/nio/cs/TestISCII91.java--- pass sun/nio/cs/TestISO2022CNDecoder.java--- pass sun/nio/cs/TestISO2022JP.java--- pass sun/nio/cs/TestISO2022JPEncoder.java--- pass sun/nio/cs/TestISO2022JPSubBytes.java--- pass sun/nio/cs/TestIllegalISO2022Esc.java--- pass sun/nio/cs/TestIllegalSJIS.java--- pass sun/nio/cs/TestJIS0208Decoder.java--- pass sun/nio/cs/TestJIS0212Decoder.java--- pass sun/nio/cs/TestMS5022X.java--- pass sun/nio/cs/TestMiscEUC_JP.java--- fail sun/nio/cs/TestSJIS0213.java--- pass sun/nio/cs/TestTrailingEscapesISO2022JP.java--- pass sun/nio/cs/TestUTF8BOM.java--- pass sun/nio/cs/TestUTF_16.java--- pass sun/nio/cs/TestUni2HKSCS.java--- pass sun/nio/cs/TestX11JIS0201.java--- pass sun/nio/cs/UkrainianIsNotRussian.java--- pass sun/nio/cs/ZeroedByteArrayEUCTWTest.javapass --- sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/InvalidateServerSessionRenegotiate.javapass --- sun/security/ssl/javax/net/ssl/NewAPIs/JSSERenegotiate.javapass --- sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/CheckStatus.javapass --- sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/ConnectionTest.javapass --- sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/NoAuthClientAuth.java--- fail sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/DNSIdentities.java--- pass sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsCreateSockTest.java--- pass sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsSocketFacTest.java--- pass sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressDNSIdentities.java--- fail sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressIPIdentities.java--- fail sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPIdentities.java--- fail sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/Identities.java--- pass sun/security/util/Oid/BerOid.java137 differences

Running with the usual jtreg flags, -a -ignore:quiet in all repositories and adding -s and now also -ea -esa for langtools, the basic regression test results on Linux forOpenJDK 6 build 19 are: HotSpot...

OpenJDK

OpenJDK 6 Processes

[The entry below is a lightly edited version of a message previously sent to the OpenJDK 6 development alias jdk6-dev@openjdk.java.net.]Since questions about OpenJDK 6 processes come up from time to time, in my role as release manager I thought it would be helpful to more fully document the current engineering practices and receive comments about them.OpenJDK 6 is an implementation of the Java SE 6 specification valuing stability, compatibility, and security. As an implementation of the Java SE 6 specification, all changes to OpenJDK 6 must be allowable within that specification. This requirement precludes many API changes. Acceptable API changes include those permitted by the endorsed standards mechanism, such as upgrading to a newer version of a standalone technology, like a component JSR. One example of such an API change was the upgrade of JAX-WS from 2.0 to 2.1 in OpenJDK 6 build b06.Changes allowable within the Java SE 6 specification may still be rejected for inclusion in OpenJDK 6 if the behavioral compatibility risk is judged as too large. (See previous write-ups of kinds of compatibility and compatibly regions in JDK releases.)Behavioral compatibility concerns implementation properties of the JDK. Clients of the JDK can knowingly or unknowingly come to rely upon implementation-specification behaviors not guaranteed by the specification and care should be taken to not break such applications needlessly. In contrast, if a change is appropriate for every other JDK release train, it is generally appropriate for OpenJDK 6 too. Examples of such universal changes include security fixes and time zone information updates.With the above caveats, bug fixes in JDK 7 that do not involve specification changes have presumptive validity for OpenJDK 6. That is, by default such fixes are assumed to be applicable to OpenJDK 6, especially if having "soaked" in JDK 7 for a time without incident. On a related point, the fixes from the stabilized HotSpot forests (forexample HotSpot Express 14 or HotSpot Express 16) are suitable for bulk porting to the OpenJDK 6 HotSpot repository without review of individual bugs.As a general guideline, if a change is applicable to both JDK 7 and OpenJDK 6, the change should be made in JDK 7 no later than the change is made in OpenJDK 6.With the exception of security fixes, all OpenJDK 6 code review traffic should be sent to jdk6-dev@openjdk.java.net for consideration before a commit occurs. (For subscription instructions and to browse the archives see http://mail.openjdk.java.net/mailman/listinfo/jdk6-dev)All fixes require the approval of the release manager and may require additional technical review and approval at the discretion of the release manager. Security fixes are first kept confidential and applied to a private forest before being pushed to the public forest as part of the general synchronized publication of the fix to effected JDK release trains.The master Mercurial forest of OpenJDK 6 repositories resides at:http://hg.openjdk.java.net/jdk6/jdk6Since there is only a single master OpenJDK 6 forest, near the end of a build period the release manager may defer otherwise acceptable changes to the start of the next build.†The schedule to tag builds of OpenJDK 6 is on an as-needed basis. The timing and feature list of a build is coordinated on the jdk6-dev alias with the IcedTea 6 project, a downstream client of OpenJDK 6. Before a build is tagged, regression and other testing is performed to verify the quality of the build.After feedback is collected from jdk6-dev and this blog entry, the OpenJDK 6 project page will be updated with the current process information.† Alternatively, in JDK 7 there are a hierarchy of staging integration forests under the master to manage a higher rate of change, see OpenJDK Mercurial Wheel). As the rate of change in OpenJDK 6 is comparatively small, as long as the end of build quiet periods continue to be acceptably short, having a single master forest should be simpler than starting and managing an intermediate staging forest kept open to accepting changes at all times.

[The entry below is a lightly edited version of a message previously sent to the OpenJDK 6 development alias jdk6-dev@openjdk.java.net.] Since questions about OpenJDK 6 processes come up from time...

Java

Beware of Covariant Overriding in Interface Hierarchies

One of the changes to the Java programming language made back in JDK 5 was the introduction of covariant returns, that is, the ability in a subtype to override a method in a supertype and return a more specific type. For example,public class A { public Object method() {return null;}}public class B extends A { @Override public String method() {return "";}}Covariant returns can be a very handy facility to more accurately convey the type of object returned by a method. However, the feature should be used judiciously, especially in interface hierarchies. In interface hierarchies, covariant returns force constraints on the implementation classes. Such a constraint was included the in the apt API modeling the Java language and was subsequently removed from the analogous portion of the standardized JSR 269 API in javax.lang.model.\*.In apt, the TypeDeclaration interface defines a method Collection<? extends MethodDeclaration> getMethods().In the sub-interface ClassDeclaration, the method is overriden with Collection<MethodDeclaration> getMethods() and in another sub-interface, AnnotationTypeDeclaration, the method is overriden withCollection<AnnotationTypeElementDeclaration> getMethods().Consequently, it is not possible for a single class to implement both the ClassDeclaration and AnnotationTypeDeclaration interfaces since the language specification forbids having two methods with the same name and argument types but different return types (JLSv3 §8.4.2).(This restriction does not exist at the class file level and a compiler will generate synthetic bridge methods with this property when implementing covariant returns.)If a compiler chose to use a single type to model all kinds of types (classes, enums, interfaces, annotation types), it would not be able to be directly retrofitted to implement the entirely of this apt API; wrapper objects would need to be created just to allow the interfaces to be implemented at a source level.In contrast, in JSR 269 the root modeling interface Element defines a List<? extends Element> getEnclosedElements() method which returns all kinds of enclosed elements, from fields, to constructors, to methods. Elements of a particular type can than be extracted using a filter. This approach provides more flexibility in retrofitting the interfaces onto an existing implementation; a spectrum of implementations are possible, from a single type to represent all sorts of elements to a one-to-one correspondence of implementation types to interface types.Note that in cases where an implementation type collapses several interface types, instanceof checks for an interface type are not necessarily useful since implementing one interface does not imply no other related interface is implemented. The Element specification warns of this possibility:To implement operations based on the class of an Element object, either use a visitor or use the result of the getKind() method. Using instanceof is not necessarily a reliable idiom for determining the effective class of an object in this modeling hierarchy since an implementation may choose to have a single object implement multiple Element subinterfaces.

One of the changes to the Java programming language made back in JDK 5 was the introduction ofcovariant returns, that is, the ability in a subtype to override a method in a supertype and return a more...

Annotation Processing

Annotation Processor SourceVersion

In annotation processing there are three distinct roles, the author of the annotation types, the author of the annotation processor, and the client of the annotations. The third role includes the responsibility to configure the compiler correctly, such as setting the source, target, and encoding options and setting the source and class file destination for annotation processing.The author of the annotation processor shares a related responsibility: property returning the source version supported by the processor.Most processors can be written against a particular source version and always return that source version, such as by including a @SupportedSourceVersion annotation on the processor class. In principle, the annotation processing infrastructure could tailor the view of newer-than-supported language constructs to be more compatible with existing processors. Conversely, processors have the flexibility to implementtheir own policies when encountering objects representing newer-than-supported structures.In brief, by extending version-specific abstract visitor classes, such as AbstractElementVisitor6 andAbstractTypeVisitor6, the visitUnknown method will be called on entities newer than the version in question. Just as regression tests inside the JDK itself should by default follow a dual policy of accepting the default source and target settings rather than setting them explicitly like other programs, annotation processors used for testing with the JDK should generally support the latest source version and not be constrained to a particular version. This allows any issues or unexpected interactions of new features to be found more quickly and keeps the regression tests exercising the most recent code paths in the compiler.This dual policy is now consistently implemented in the langtools regression tests as of build 85 of JDK 7 (6926699).

In annotation processing there are three distinct roles,title="JavaOne 2005: Annotation Processing for the Java™ Programming Language">the author of the annotation types, the author of the annotation...

Oracle

Integrated Cloud Applications & Platform Services