Retrofitting classes as records in the JDK
Nir Lisker
nlisker at gmail.com
Tue Feb 18 16:05:32 UTC 2020
I took a quick look at sun.util.logging.PlatformLogger to start with. The
class does not declare an accessor for its field 'PlatformLogger.Bridge
loggerProxy', so it seems like records are not suitable here.
However, this brings up a question: can the visibility of an accessor
method be changed or the method removed? Looking at the specs I found [1],
it seems that the answer is no, but it's not that clear to me:
8.10.3 Record Members
> A record type R has the following members:
> An implicitly declared public accessor method with the same name as the
> record component, whose return type is the declared type of the record
> component, unless a public method with the same signature is explicitly
> declared in the body of the declaration of R.
So if a non-public method with the same signature is explicitly declared,
is it a compile time error? Compile time error is only mentioned in:
It is a compile-time error if an explicitly declared accessor method has a
> throws clause.
[1]
http://cr.openjdk.java.net/~gbierman/jep359/jep359-20191031/specs/records-jls.html#jls-8.10.3
On Tue, Feb 18, 2020 at 5:33 PM Nir Lisker <nlisker at gmail.com> wrote:
> Given that record is a preview feature, there is no point to try to
>> convert those classes now, but in the future why not, it will make those
>> classes more readable.
>
>
> Yeah, OpenJFX N maintains backwards compatibility with JDK N-1, so we have
> some time until we do the conversion. I want to get a head start on this
> large task and test preview records while at it.
>
> The script is a nice idea, I'll try it. Thanks!
>
> On Tue, Feb 18, 2020 at 4:57 PM Remi Forax <forax at univ-mlv.fr> wrote:
>
>> Here is a small script [0] using ASM that tries to find classes that can
>> be retrofitted to be records.
>> A potential record is a non-visible class (non public or public but non
>> in an exported package) that have only final fields and have methods that
>> looks like accessors (the logic is fuzzy, it looks for variation of "return
>> this.foo" with possible operations in between).
>>
>> Given that record is a preview feature, there is no point to try to
>> convert those classes now, but in the future why not, it will make those
>> classes more readable.
>>
>> One fun thing (at least for me) is that the class "ConstantDynamic",
>> "Handle" and "TypeReference" of ASM (that are vendorized/shaded in the
>> package jdk/internal/org/objectweb/asm) can be converted to record.
>> But again, it will take time given that the source code of ASM is
>> compatible with Java 8.
>>
>> cheers,
>> Rémi
>>
>> [0]
>> https://github.com/forax/amber-record/blob/master/src/main/java/fr.umlv.record.recordfinder/fr/umlv/record/recordfinder/RecordFinder.java
>>
>> On java.base, you get
>> sun/util/logging/PlatformLogger
>> sun/util/locale/LocaleExtensions
>> sun/security/x509/AVA
>> sun/security/x509/CertificatePolicySet
>> sun/security/x509/GeneralNames
>> sun/security/x509/GeneralSubtrees
>> sun/security/util/ConstraintsParameters
>> sun/security/ssl/SecureKey
>> sun/security/ssl/SessionId
>> sun/security/internal/spec/TlsKeyMaterialSpec
>> sun/security/internal/spec/TlsMasterSecretParameterSpec
>> sun/security/internal/spec/TlsPrfParameterSpec
>> sun/reflect/generics/tree/ArrayTypeSignature
>> sun/reflect/generics/tree/ClassSignature
>> sun/reflect/generics/tree/ClassTypeSignature
>> sun/reflect/generics/tree/FormalTypeParameter
>> sun/reflect/generics/tree/MethodTypeSignature
>> sun/reflect/generics/tree/SimpleClassTypeSignature
>> sun/reflect/generics/tree/TypeVariableSignature
>> sun/reflect/generics/reflectiveObjects/GenericArrayTypeImpl
>> sun/reflect/generics/reflectiveObjects/ParameterizedTypeImpl
>> sun/reflect/generics/factory/CoreReflectionFactory
>> sun/reflect/annotation/AnnotationType
>> sun/reflect/annotation/TypeAnnotation
>> sun/nio/ch/NativeSocketAddress
>> sun/nio/ch/ThreadPool
>> jdk/internal/org/objectweb/asm/ConstantDynamic
>> jdk/internal/org/objectweb/asm/Handle
>> jdk/internal/org/objectweb/asm/TypeReference
>> jdk/internal/org/objectweb/asm/tree/analysis/BasicValue
>> jdk/internal/org/objectweb/asm/tree/analysis/SourceValue
>> jdk/internal/org/objectweb/asm/commons/Method
>> jdk/internal/module/IllegalAccessMaps
>> jdk/internal/module/ModuleHashes
>> jdk/internal/module/ModulePatcher
>> jdk/internal/module/ModuleResolution
>> jdk/internal/module/ModuleTarget
>> jdk/internal/loader/LoaderPool
>> jdk/internal/jrtfs/JrtFileAttributes
>> jdk/internal/jimage/ImageHeader
>> jdk/internal/jimage/decompressor/CompressedResourceHeader
>> java/util/KeyValueHolder
>> java/time/chrono/ChronoLocalDateTimeImpl
>> java/time/chrono/ChronoZonedDateTimeImpl
>> java/net/UrlDeserializedState
>> java/lang/NamedPackage
>> java/lang/invoke/InfoFromMemberName
>> java/lang/invoke/LambdaFormEditor
>> java/lang/constant/DirectMethodHandleDescImpl
>> java/lang/constant/MethodTypeDescImpl
>> java/lang/constant/ReferenceClassDescImpl
>>
>>
>> ----- Mail original -----
>> > De: "Nir Lisker" <nlisker at gmail.com>
>> > À: "Brian Goetz" <brian.goetz at oracle.com>
>> > Cc: "amber-dev" <amber-dev at openjdk.java.net>
>> > Envoyé: Mardi 18 Février 2020 00:17:48
>> > Objet: Re: Retrofitting classes as records in the JDK
>>
>> >>
>> >> Bear in mind that the JDK is surely the only library in the world that
>> has
>> >> this high a bar for compatibility expectations
>> >
>> >
>> > From my past work on OpenJFX, we have the same backwards compatibility
>> > obligations (or at least very close).
>> >
>> > Where we've landed with records makes them more suitable for _internal_
>> > abstractions and implementation details than public API abstractions if
>> the
>> > API has to meet a high compatibility bar.
>> >
>> >
>> > I agree. This is mostly what I would be looking at.
>> >
>> > Where we expect to use records in the JDK is in streamlining
>> >> implementations, and maybe as far as private implementations of public
>> >> interfaces (e.g., Map.Entry).
>> >
>> >
>> > I take it that these migrations are only at the abstract discussion
>> level
>> > then? I'm interested in a more concrete list of places where migration
>> > would happen. What list/issue should I be monitoring?
>> >
>> > On Mon, Feb 17, 2020 at 8:20 PM Brian Goetz <brian.goetz at oracle.com>
>> wrote:
>> >
>> >> So, it will be very easy to get the wrong idea from what the JDK will
>> >> eventually do here. It is pretty likely that the JDK will not expose
>> very
>> >> many records at all, but instead is more likely to use them in
>> >> implementations.
>> >>
>> >> Where we've landed with records makes them more suitable for _internal_
>> >> abstractions and implementation details than public API abstractions
>> if the
>> >> API has to meet a high compatibility bar. The reason is that evolving
>> them
>> >> in significant ways -- such as adding, removing, changing, or
>> reordering
>> >> components, or migrating them from a record to an ordinary class -- has
>> >> compatibility consequences that are probably more than the JDK would be
>> >> willing to take (though other libraries will surely feel differently.)
>> >>
>> >> (Bear in mind that the JDK is surely the only library in the world that
>> >> has this high a bar for compatibility expectations, so what is a
>> problem
>> >> for us is not a problem for the rest of the ecosystem. For example,
>> it is
>> >> impossible to refactor an enum or record to a class with 100%
>> compatibility
>> >> -- because of the restricted Enum and Record superclasses. This is a
>> >> blocker for the JDK, but for just about the entire rest of the
>> ecosystem,
>> >> is often not a problem in practice, because the 99% you can get is
>> >> generally good enough for them.)
>> >>
>> >> Where we expect to use records in the JDK is in streamlining
>> >> implementations, and maybe as far as private implementations of public
>> >> interfaces (e.g., Map.Entry). But I wouldn't expect a lot of public
>> >> records.
>> >>
>> >>
>> >>
>> >> On 2/17/2020 10:03 AM, Nir Lisker wrote:
>> >>
>> >> Hi,
>> >>
>> >> Is there a discussion somewhere about which existing classes in the
>> JDK are
>> >> planned to become records? As an OpenJFX contributor, I'd like to get a
>> >> head start and see how we can utilize records correctly. Seeing how
>> the JDK
>> >> does it is the best approach in my opinion.
>> >>
>> >> - Nir
>> >>
>> >>
>>
>
More information about the amber-dev
mailing list