Replying to both this and the previous email in one: > I guess I prefer C and D over A and B because of the reflection magic problem, > and also because of Dan H’s issue (IIUC) about “where do we look for the > metadata, if not in somebody’s constant pool?”
+1 I prefer C or D as well for similar reasons. > Since D and C have about equal practical effect, and D is both simpler to > specify and less ceremony, I prefer D best of all. > > I agree that ACC_VALUE is useful to prevent “action at a distance”. > > There is the converse problem that comes from the redundancy: > What happens if the class directly implements or inherits ValueObject > and ACC_VALUE is not set? I guess that is an error also. That's the unfortunate part of having two ways to say things and why I really liked Brian's suggestion to only have the interface. The VM can infer the bit from the presence of the interface, especially if we went with option C as the interface would always be directly present in the value classfiles. It's a little different than the normal path of "as long as it's in the hierarchy" but it does mean there's only 1 piece of info. > I hit send too soon: That’s probably true for concrete classes. > For abstracts, ACC_VALUE must not be set (yes?) and ValueObject > “just flows” along with all the other super types, with no particular > notice. It all comes together when ACC_VALUE appears, and that > must be on a final, concrete class. That's a reasonable restriction if we keep the bit - ACC_VALUE is only for concrete classes and must be met by either a direct or inherited VO interface. > I keep wondering what ACC_VALUE “should mean” for an abstract. > Maybe it “should mean” that the abstract is thereby also forced to > implement VO, so that all subtypes will be VO’s. Isn't that the role of the VO interface though? I think it makes more sense to keep ACC_VALUE for final concrete classes. > > The slightly different meaning of ACC_PERMITS_VALUE is “hold > off on injecting IdentityObject at this point”. Because the type > might allow subtypes that implement VO (whether abstract or > concrete). At this point it also allows IdentityObject to be > introduced in subtypes. Mmm… It could also have been > spelled ACC_NOT_NECESSARILY_IDENTITY. Or ACC_UNDECIDED. If we see bucket 2 classes becoming popular enough that the ACC_PERMITS_VALUE is a common flag on abstract classes, we may want to pick a name that indicates "both allowed". It's our current code base's bias towards identity that makes us want to spell it "PERMITS_VALUE" when, as John says, flipping the meaning is equally valid. > > As we said in the meeting, it seems to need magic injection of > IdObj, even if we can require non-magic explicit presence of VO. > Dan H., will the metadata pointer of IdObj be a problem to access, > if it is magically injected? I'm not concerned about the metadata pointer - injecting an extra interface is doable and required for legacy identity classes. My worry is consistency flowing through the system - primarily with determining whether an interface is injected or not. At least in our implementation, the easiest way to inject the interface is to add it when converting the .class file into our internal forms (ROM & RAM class). Once injected, it looks like any other interface. When converting back from our internal form to a classfile for the JVMTI RetransformClasses agents, I need to either filter the interface out if we injected it or not if it was already there. JVMTI's GetImplementedInterfaces call has a similar issue with being consistent - and that's really the same issue as reflection. There's a lot of small places that can easily become inconsistent - and therefore a lot of places that need to be checked - to hide injected interfaces. The easiest solution to that is to avoid injecting interfaces in cases where javac can do it for us so the VM has a consistent view. None of this is impossible - or even that hard - but it's really easy to get wrong and only discover after it's been in the wild for a while. When the bug reports come in, we'll have to decide which set of users to break - those who wanted it returned like a normal interface or those who expected it to be hidden. My vote is for javac to inject the VO interface as before we ship is the only time we can by design avoid a long tail of (minor) bugs. --Dan