Remove public fields in public API in a binary compatible way.

Sebastian Sickelmann sebastian.sickelmann at gmx.de
Sat Jul 21 09:34:53 UTC 2012


Hi all,

sometime ago (in oct 2011[0]) I suggested a way how we can 
change(restrict) the visibility of fields in a binary compatible way.

I had worked on the concepts some time and created some documentation[1] 
and an small demo[2].
The documentation uses some parts of the JEP-Template. But it is not 
intented to be a JEP yet.
I think it is in an much to early state for a real JEP (isn't it, you 
can answer it after you had read it).

The main parts I want to discuss is how to handle Reflection (should it 
be supported?), ExceptionHandling and the pros and cons
of the two solutions I tried to describe.

Some words to the demo. It uses ByteCodeTransformation at load time to 
change the access of fields to an invokedynamic call.
The invokedynamic bootstrap method figures out which Method to call 
instead of the field access.

The demo(AllInOneTest) uses the classes TestOld, TestNewSolution2, 
TestNew2Solution12, TestNew3Solution12 which got all
the same exact implementation(byte-code), just that TestOld is testing 
the class OLD, TestNewSolution2 is testing NEWSol2, ... and 
TestNew3Solution12 is testing NEW3Sol12
The testclasses are generated using the class GEN.  The GEN class 
generates two static testmethods:

genStaticTest:
     which produces the following testsequence:
         System.out.println(testAgainst.staticField);
         testAgainst.staticField = new Object;
         System.out.println(testAgainst.staticField);

genNonStaticTest:
     which produces the following testsequence:
         testAgainst tObject = new testAgainst();
         System.out.println(tObject.cause);
         tObject.cause = new RuntimeException("NEW");
         System.out.println(tObject.cause);

Some words to the Implementation classes OLD, NEWSol2, ... , NEW3Sol12.

OLD is the original form which we want to change.
NEWSol2 is an complete compatible version of OLD, just the annotations 
are missing. It is compatible to Solution 2 only because it uses the old 
fieldnames (cause,staticField)

NEW2Sol12 is an binary compatible version of OLD, just the annotations 
are missing. It is compatible to Solution 1 and 2 because it uses the 
old fieldnames (cause,staticField)
NEW2Sol12 throws an runtime exception on every PUT of field "cause" and 
every PUTSTATIC of field "staticField"

NEW3Sol12 is an binary and reflection compatible version of OLD. It is 
compatible to Solution 1 and 2 because it uses the old fieldnames 
(cause,staticField)
NEW2Sol12 throws an checked exception on every PUT of field "cause" and 
every PUTSTATIC of field "staticField"

Q0: What is this the right mailing-list to discuss this?
Q1: What do you think about the main idea of this?
Q2: So what do you think about Solution 1 and 2. Where are your pros and 
cons?
Q3: Do you think we need to support reflection compabibility?
Q4: What should we do if the accessor-method throws an CheckedException? 
Wrap it inside another RuntimeException(ex 
.WrappedCheckedCompatiblityException)?
Q5: Should we also wrap RuntimeExceptions or should we let those 
"fly-through"?

Hope to get some good discussion.

-- Sebastian

[0] 
http://mail.openjdk.java.net/pipermail/jdk8-dev/2011-October/000199.html
[1] 
https://github.com/picpromusic/incubator/blob/master/jdk/compatibleFieldAccess/JEP.markdown 

[2] 
https://github.com/picpromusic/incubator/tree/master/jdk/compatibleFieldAccess 




More information about the discuss mailing list