Hi again,

Am Donnerstag, dem 27.10.2022 um 20:51 +0100 schrieb Neil C Smith:
> On Thu, 27 Oct 2022 at 20:14, Matthias Bläsing
> <[email protected]> wrote:
> > Am Donnerstag, dem 27.10.2022 um 20:32 +0200 schrieb Michael Bien:
> > > I am still a bit surprised that this causes issues. Since the class is
> > > final which removes an entire can of worms of potential override issues.
> > > I would have expected the JVM to find the right method in unambiguous
> > > cases like this.
> > 
> >  [wrong reasoning]
> 
> I'm not sure that's correct from the JVM perspective.  The Object
> method should still be generated as a bridge?
> 
> It should be backwards compatible but it's not forwards compatible?
> Anything compiled against 15 should run on 16, but anything compiled
> against 16 won't run on 15?
> 
> I still think it's probably a good idea to revert in this particular
> case though.

you are right and my reasoning was wrong. I looked at the generated
code with javap and there I see:

  public int compareTo(org.openide.modules.SpecificationVersion);
    descriptor: (Lorg/openide/modules/SpecificationVersion;)I
    flags: (0x0001) ACC_PUBLIC

  public int compareTo(java.lang.Object);
    descriptor: (Ljava/lang/Object;)I
    flags: (0x1041) ACC_PUBLIC, ACC_BRIDGE, ACC_SYNTHETIC

The second method is the bridge method you talked about.

So when you build against NB16 the compiler will link against the first
method, when build against NB15 the compiler will link against the
second variant.

So this is a binary compatible change as code linked against the old
version will continue to work (via the bridge). The opposite is not
true.

The solution is "simple": Build against NB15 and execute on NB15 or
newer.

Similar problems can be observed, when you use ByteBuffer#flip.
Compiled against JDK 11 code will not run on JDK 8. although in theory
the method exists, but it has a different return signature:

   import java.nio.ByteBuffer;
   
   class test {
        public static void main(String[] argv){
                ByteBuffer bb = ByteBuffer.allocate(10);
                bb.flip();
        }
   }

Build this with a JDK 11+ once as

javac -source 8 -target 8 test.java

and once as

javac --release 8 test.java

Try to run both:

$PATH_JDK8/bin/java -cp . test

It first fails, the second works. The difference can be seen with
javap:

javap -c -cp . test


So this is already a reality for java developers and indeed it will
continue to happen. The variant you compile against is your lowest
baseline.


Greetings

Matthias

PS: Sorry for the confusion I caused.

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

For further information about the NetBeans mailing lists, visit:
https://cwiki.apache.org/confluence/display/NETBEANS/Mailing+lists



Reply via email to