• Java 21 and [this-escape] warnings?

    From Knute Johnson@21:1/5 to All on Fri Jun 9 20:32:25 2023
    I've been playing with Java21ea getting ready for its release this fall
    and have found some warnings that I don't really know how to deal with.
    I understand why you don't want 'this' escaping the constructor but I
    don't understand how Java21 think that a lot of the methods we have
    always used are going to cause that to happen. Please see the code
    below and the script to compile it. I've commented out several lines
    but you can un-comment them and see the warnings from the compiler. The
    first one that I really don't understand is Frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE). I would appreciate
    any comments or maybe I just don't know what I'm doing and there is a
    better way. If so please feel free to critique. It compiles and will
    run but not work correctly with the lines commented out. Put them back
    in and compile them to see the warnings.


    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.border.*;

    public class test extends JFrame {
    private static final long serialVersionUID = 1L;

    public test() {
    super("test");
    //setLayout(new GridBagLayout()); // [this-escape]
    //setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); //
    [this-escape]

    GridBagConstraints c = new GridBagConstraints();

    JLabel l = new JLabel("this is a JLabel");
    l.setBorder(new EmptyBorder(20,20,20,20)); // [this-escape]
    sometimes
    //add(l,c); // [this-escape]
    //add(l); // [this-escape]
    }

    public static void main(String[] args) {
    EventQueue.invokeLater(() -> {
    test t = new test();
    t.addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent we) {
    t.dispose();
    }
    });
    t.pack();
    t.setVisible(true);
    });
    }
    }

    A script to compile the program above:

    #!/bin/bash

    if javac21 -Xlint:all -Xdiags:verbose -Xmaxerrs 10 -Xmaxwarns 10 test.java
    then
    jar cvfe test.jar test *.class
    rm *.class
    fi


    javac21 is a link to the javac program from OpenJDK 21ea26. You can get
    it here: https://jdk.java.net/21/

    Thanks!


    --

    Knute Johnson

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Daniele Futtorovic@21:1/5 to Knute Johnson on Sat Jun 10 13:46:44 2023
    On 10/06/2023 03:32, Knute Johnson wrote:
    I've been playing with Java21ea getting ready for its release this fall
    and have found some warnings that I don't really know how to deal with.
    I understand why you don't want 'this' escaping the constructor but I
    don't understand how Java21 think that a lot of the methods we have
    always used are going to cause that to happen.  Please see the code
    below and the script to compile it.  I've commented out several lines
    but you can un-comment them and see the warnings from the compiler.  The first one that I really don't understand is Frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE).  I would appreciate
    any comments or maybe I just don't know what I'm doing and there is a
    better way.  If so please feel free to critique.  It compiles and will
    run but not work correctly with the lines commented out.  Put them back
    in and compile them to see the warnings.


    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.border.*;

    public class test extends JFrame {
        private static final long serialVersionUID = 1L;

        public test() {
            super("test");
            //setLayout(new GridBagLayout());  // [this-escape]
            //setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);  // [this-escape]

            GridBagConstraints c = new GridBagConstraints();

            JLabel l = new JLabel("this is a JLabel");
            l.setBorder(new EmptyBorder(20,20,20,20));  // [this-escape] sometimes
            //add(l,c);  // [this-escape]
            //add(l);  // [this-escape]
        }

        public static void main(String[] args) {
            EventQueue.invokeLater(() -> {
                test t = new test();
                t.addWindowListener(new WindowAdapter() {
                    public void windowClosing(WindowEvent we) {
                        t.dispose();
                    }
                });
                t.pack();
                t.setVisible(true);
            });
        }
    }

    Hi Knute,

    Still Swing-ing? :-)

    These errors/warning make perfect sense to me (bar one): you're
    manipulating the object tree before the constructor's end.

    I reckon the reason #setDefaultCloseOperation gets flagged is that it potentially fires a PropertyChangeEvent, the source of which is your
    Frame. It wouldn't fire if there are no listeners attached, but the
    compiler probably can't (or can't be arsed to) infer that.

    The one I don't get (and haven't been able to reproduce) is the
    #setBorder call.

    Is [this-escape] a warning/error that's been specifically added in
    JDK21? I reckon the problem itself isn't new or changed, and that it's
    always been there.

    As such, you would have two choices, as before: ignore the warning or
    change your habits.

    For illustration, with Swing I'd made it a habit to construct my UI in #addNotify, for self-constructing components. That wouldn't be
    applicable to the frame, which you could for instance construct
    externally (I mean in a factory) with a self-constructing content pane.

    Regards,

    --
    DF.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Eric Sosman@21:1/5 to Knute Johnson on Sat Jun 10 06:58:47 2023
    On Friday, June 9, 2023 at 9:32:41 PM UTC-4, Knute Johnson wrote:
    [...] I've commented out several lines
    but you can un-comment them and see the warnings from the compiler. The first one that I really don't understand is Frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE). [...]

    I've not tried Java21 and am just guessing wildly, so take
    my observations with a grain -- nay, a tonne -- of salt:

    public class test extends JFrame {

    Have you tried making the class final? Alternatively, ...

    public test() {
    super("test");
    //setLayout(new GridBagLayout()); // [this-escape] //setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); //
    [this-escape]

    ... have you tried super.setXXX instead of bare setXXX?

    GridBagConstraints c = new GridBagConstraints();

    JLabel l = new JLabel("this is a JLabel");
    l.setBorder(new EmptyBorder(20,20,20,20)); // [this-escape]
    sometimes

    I don't understand (or even guess at) this one, not at all.

    //add(l,c); // [this-escape]
    //add(l); // [this-escape]

    ... but again: try using super.add (or a final class).

    --
    esosman@comcast-dot-net.invalid
    Look on my code, ye Hackers, and guffaw!

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Knute Johnson@21:1/5 to Daniele Futtorovic on Sat Jun 10 13:23:58 2023
    On 6/10/23 06:46, Daniele Futtorovic wrote:

    Hi Knute,

    Still Swing-ing? :-)


    Nice to hear from you Daniele. Yes, they keep paying me and I keep
    writing Swing code. Works well and it is quick to write.


    The one I don't get (and haven't been able to reproduce) is the
    #setBorder call.

    I saw it once and couldn't make the combination right to get it to show
    up again.

    Is [this-escape] a warning/error that's been specifically added in
    JDK21? I reckon the problem itself isn't new or changed, and that it's
    always been there.

    It's a feature of the Java 21 compiler. Things keep getting
    better/tighter all the time.

    As such, you would have two choices, as before: ignore the warning or
    change your habits.

    See Eric Sosman's post.

    For illustration, with Swing I'd made it a habit to construct my UI in #addNotify, for self-constructing components. That wouldn't be
    applicable to the frame, which you could for instance construct
    externally (I mean in a factory) with a self-constructing content pane.

    I'll have to try that. It is just so different from the way I've been
    writing Swing code for the last 20 years:-).

    Thanks for the post.


    --

    Knute Johnson

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Knute Johnson@21:1/5 to Eric Sosman on Sat Jun 10 13:26:56 2023
    On 6/10/23 08:58, Eric Sosman wrote:
    On Friday, June 9, 2023 at 9:32:41 PM UTC-4, Knute Johnson wrote:
    [...] I've commented out several lines
    but you can un-comment them and see the warnings from the compiler. The
    first one that I really don't understand is
    Frame.setDefaultCloseOperation(DISPOSE_ON_CLOSE). [...]

    I've not tried Java21 and am just guessing wildly, so take
    my observations with a grain -- nay, a tonne -- of salt:

    public class test extends JFrame {

    Have you tried making the class final? Alternatively, ...

    At your suggestion I did and all the errors go away. You get the prize
    Eric!

    public test() {
    super("test");
    //setLayout(new GridBagLayout()); // [this-escape]
    //setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); //
    [this-escape]

    ... have you tried super.setXXX instead of bare setXXX?

    super doesn't seem to help.

    l.setBorder(new EmptyBorder(20,20,20,20)); // [this-escape]
    sometimes

    I don't understand (or even guess at) this one, not at all.

    I think that one was me somewhere mixing things up.

    final is the answer!

    Thanks!

    --

    Knute Johnson

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=c3=b8j?=@21:1/5 to Knute Johnson on Sat Jun 10 18:57:14 2023
    On 6/9/2023 9:32 PM, Knute Johnson wrote:
    I've been playing with Java21ea getting ready for its release this fall
    and have found some warnings that I don't really know how to deal with.
    I understand why you don't want 'this' escaping the constructor but I
    don't understand how Java21 think that a lot of the methods we have
    always used are going to cause that to happen.

    I think the following example illustrates the problem
    they are trying to solve.

    public class ThisLeak {
    public static class A {
    protected boolean a;
    public A() {
    a = true;
    }
    public void m() {
    System.out.printf("a=%b\n", a);
    }
    }
    public static class B extends A {
    protected boolean b1;
    protected boolean b2;
    public B() {
    super();
    b1 = true;
    m();
    b2 = true;
    }
    }
    public static class C extends B {
    private boolean c;
    public C() {
    c = true;
    }
    public void m() {
    System.out.printf("a=%b b1=%b b2=%b c=%b\n", a, b1, b2, c);
    }
    }
    public static void main(String[] args) {
    new C();
    }
    }

    And it also explains why final solve the problem.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Daniele Futtorovic@21:1/5 to Knute Johnson on Sun Jun 11 14:45:18 2023
    On 10/06/2023 20:23, Knute Johnson wrote:
    On 6/10/23 06:46, Daniele Futtorovic wrote:
    As such, you would have two choices, as before: ignore the warning or
    change your habits.

    See Eric Sosman's post.

    A swing and a miss! :-D

    Thanks to Eric and Arne for clarifying the behaviour.

    --
    DF.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)