Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8340476

Warnings for Identity-Sensitive Libraries

XMLWordPrintable

    • Icon: JEP JEP
    • Resolution: Unresolved
    • Icon: P4 P4
    • None
    • core-libs
    • None
    • Feature
    • Open
    • SE
    • valhalla dash dev at openjdk dot org
    • XS
    • XS

      Summary

      Identify libraries in the Java Platform that rely on object identity. Provide javac warnings about improper usages of these libraries, when inputs are instances of certain value-based Java Platform classes.

      Motivation

      Some Java Platform classes have been designated value-based classes in the API specifications. These classes discourage developers from relying on the unique identities of instances—if two instances are equals, whether or not they are == should be irrelevant. Instances are always created via factory methods, which deliberately avoid making commitments about whether results will be == to previously-returned results.

      In the future, we anticipate that these classes will evolve into value classes whose instances, under an enhanced Java programming model, simply do not have unique identities. Certain key Java Platform libraries are expected to throw an exception when asked to operate on an instance of a value class.

      Many value-based classes are widely used, and, despite the disclaimers in their documentation, may occasionally have instances be used as inputs to these identity-sensitive standard libraries. In anticipation of the future behavioral change, developers would benefit from diagnostics that identify misuse of value-based classes and encourage refactoring beforehand.

      This JEP can build on the work of Warnings for Value-Based Classes, which warned about synchronized statements being applied to the same set of class instances.

      Description

      Value-based classes

      The following classes are value-based, and have been marked (since JEP 390) with the @jdk.internal.ValueBased annotation:

      • The primitive wrapper classes in java.lang;

      • The class java.lang.Runtime.Version;

      • The "optional" classes in java.util: Optional, OptionalInt, OptionalLong, and OptionalDouble;

      • Many classes in the java.time API: Instant, LocalDate, LocalTime, LocalDateTime, ZonedDateTime, ZoneId, OffsetTime, OffsetDateTime, ZoneOffset, Duration, Period, Year, YearMonth, and MonthDay, and, in java.time.chrono: MinguoDate, HijrahDate, JapaneseDate, and ThaiBuddhistDate;

      • The implementation classes of the interface java.lang.ProcessHandle;

      • The implementation classes of the collection factories in java.util: List.of, List.copyOf, Set.of, Set.copyOf, Map.of, Map.copyOf, Map.ofEntries, and Map.entry.

      The design of value classes has evolved in some ways since JEP 390. To better align with future plans, the following changes should be made:

      • It is no longer anticipated that an abstract class or interface will be able to require all subclasses to be value classes. Thus, the interface java.lang.ProcessHandle should no longer be marked @ValueBased.

      • Constructor invocations are expected to be binary compatible across a value class migration. While value-based classes will still discourage use of their constructors, it is no longer necessary to deprecate for removal the constructors of the primitive wrapper classes. Those constructors can be rolled back to simply being designated @Deprecated.

      Identity-sensitive operations

      A new JDK-internal annotation interface, @jdk.internal.RequiresIdentity, is declared with target types PARAMETER and TYPE_PARAMETER. The @RequiresIdentity annotation expresses the expectation that an argument to a given method or constructor parameter will be an object with a unique identity, not an instance of a value-based class; or that the type argument to a given type parameter will not be a value-based class type.

      An appropriate application of the @RequiresIdentity annotation is the set of APIs related to object lifespan and garbage collection. Because instances of value-based classes have unpredictable identity, they should not be used with these garbage-collection APIs.

      The following parameters and type parameters in standard libraries related to garbage collection are marked with @RequiresIdentity:

      • The referent parameter of all constructors in classes PhantomReference, SoftReference, and WeakReference
      • The obj parameter of Cleaner.register
      • The type parameter T of Reference, PhantomReference, SoftReference, WeakReference, and ReferenceQueue
      • The key parameter of WeakHashMap.put
      • The type parameter K of WeakHashMap

      Work on this JEP may identify a few other candidate identity-sensitive APIs that should be marked with @RequiresIdentity.

      Compile-time warnings

      The javac warning category synchronization is intended to diagnose misuse of value-based classes, but has an overly-specific name. It should be renamed identity, perhaps with alias support for the old name.

      Whenever javac encounters an expression of a value-based class type being passed to a parameter marked @RequiresIdentity, or a value-based class type argument instantiating a type parameter marked RequiresIdentity, it produces an identity warning.

      Developers can request to print these warnings with -Xlint:identity, and suppress them in the source code with @SuppressWarnings("identity").

      Scope of changes

      Java SE: This JEP modifies Java SE by rolling back the "for removal" deprecation of the primitive wrapper class constructors.

      JDK: The diagnostics produced by javac are quality-of-implementation features, and are not part of the Java Language Specifications.

      Implementation: New annotations and methods are JDK-internal, not part of any publicly-accessible API.

      Alternatives

      The Value Classes and Objects JEP will migrate many value-based classes to be value classes. At that point, when preview features are enabled, attempts to use these classes' instances with identity-sensitive APIs will trigger run-time failures. This may be a "good enough" migration experience. But this JEP hopes to smooth the migration curve by warning about conflicts in an earlier release, catching problems at compile time rather than run time, and producing warnings even when preview features are disabled.

      We considered supplementary warnings at run time, but existing run-time diagnostics tend to support only JVM features, not library features. It's also not clear there would be much incremental benefit to run-time warnings beyond what will already be caught by javac.

      We have considered strategies for generalizing the garbage collection APIs to work with identityless objects, but it is hard to define intuitive, reasonable behavior for these operations.

      Behavioral changes are always going to be difficult for some users, and we could decide to prioritize compatibility over evolution. We believe, however, that the future benefits of value classes will far outweigh the costs of migration.

      It is possible that third parties will want to express their own value-based classes or identity-sensitive operations, and get the same javac warnings. This could be achieved by making the relevant annotations part of a public API. But we've decided we need more evidence of third-party use cases before defining such an API.

      Dependencies

      Warnings for Value-Based Classes, delivered in Java 16, introduced the @ValueBased annotation on JDK classes and introduced the javac warnings about misuse of synchronization. This JEP builds on this earlier work.

      Value Classes and Objects (Preview) will implement the behavioral changes that this JEP warns about. It may be an opportunity to standardize the @RequiresIdentity anotation for use with libraries outside the JDK. javac can be expected to produce warnings whenever a concrete value class type is used with a @RequiresIdentity parameter or type parameter.

            dlsmith Dan Smith
            dlsmith Dan Smith
            Dan Smith Dan Smith
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: