<AWT Dev> RFR: 8211267 StackOverflowError happened by TextField.setFont(...)

Sergey Bylokhov Sergey.Bylokhov at oracle.com
Thu Oct 4 21:21:49 UTC 2018


Looks fine.

On 02/10/2018 03:44, Ichiroh Takiguchi wrote:
> Hello Sergey.
> 
> I appreciate your suggestion.
> Yeah, I should care about StateLock...
> 
> So if xtext.setFont(font) is not called,
> also xtext.validate() is not called.
> 
> Could you review fix and testcase again ?
> 
> Bug:    https://bugs.openjdk.java.net/browse/JDK-8211267
> Change: https://cr.openjdk.java.net/~itakiguchi/8211267/webrev.01/
> 
> 
> On 2018-10-02 04:43, Sergey Bylokhov wrote:
>> Hi, Ichiroh.
>> I guess you need to remove the old call xtext.validate() and the new
>> validate should be called after xtext.setFont(font);
>> But I am not sure that this call is necessary, possibly setFont()
>> itself will call validate? It is also necessary to check that the call
>> to validate(which use TreeLock) under StateLock will not cause a
>> deadlock.
>>
>> On 01/10/2018 04:52, Ichiroh Takiguchi wrote:
>>> Hello.
>>> Could you review fix and testcase ?
>>>
>>> Bug:    https://bugs.openjdk.java.net/browse/JDK-8211267
>>> Change: https://cr.openjdk.java.net/~itakiguchi/8211267/webrev.00/
>>>
>>> I'd like to obtain a sponsor for this issue.
>>>
>>> Thanks,
>>> Ichiroh Takiguchi
>>> IBM Japan, Ltd.
>>>
>>> On 2018-09-05 23:08, Ichiroh Takiguchi wrote:
>>>> Hello Krishna.
>>>>
>>>> Thank you for your testing.
>>>>
>>>> As you suggested, I tried to check peer side.
>>>> I think, to avoid recursive call. Java may call validate() against 
>>>> XAWT peer.
>>>>
>>>> =====================
>>>> diff -r 499b873761d8
>>>> src/java.desktop/unix/classes/sun/awt/X11/XTextFieldPeer.java
>>>> ---
>>>> a/src/java.desktop/unix/classes/sun/awt/X11/XTextFieldPeer.java Wed
>>>> Jul 25 11:03:07 2018 +0800
>>>> +++
>>>> b/src/java.desktop/unix/classes/sun/awt/X11/XTextFieldPeer.java Wed
>>>> Sep 05 23:03:57 2018 +0900
>>>> @@ -284,6 +284,8 @@
>>>>          synchronized (getStateLock()) {
>>>>              font = f;
>>>>              if (xtext != null && xtext.getFont() != f) {
>>>> +                if (!xtext.isValid())
>>>> +                    xtext.validate();
>>>>                  xtext.setFont(font);
>>>>              }
>>>>          }
>>>> =====================
>>>>
>>>> How about this fix ?
>>>>
>>>> On 2018-09-05 00:20, Krishna Addepalli wrote:
>>>>> Hi Ichiroh,
>>>>>
>>>>> Yes I'm able to see this issue in jdk12 repo on Ubuntu. But this issue
>>>>> is not reproducible on Windows.
>>>>> So, I guess the fix has to be specific to Linux.
>>>>>
>>>>> Thanks,
>>>>> Krishna
>>>>>
>>>>> -----Original Message-----
>>>>> From: Ichiroh Takiguchi <takiguc at linux.vnet.ibm.com>
>>>>> Sent: Monday, September 3, 2018 4:26 PM
>>>>> To: Krishna Addepalli <krishna.addepalli at oracle.com>
>>>>> Subject: Re: <AWT Dev> StackOverflowError happened by 
>>>>> TextField.setFont(...)
>>>>>
>>>>> Hello Krishna.
>>>>>
>>>>> Sorry for bothering you.
>>>>> I'd like to know you could recreate this issue or not.
>>>>>
>>>>> Thanks,
>>>>> Ichiroh Takiguchi
>>>>> IBM Japan, Ltd.
>>>>>
>>>>> On 2018-08-27 15:14, Ichiroh Takiguchi wrote:
>>>>>> Hello Krishna.
>>>>>>
>>>>>> Thank you for your testing.
>>>>>>
>>>>>> I'm sorry, I could not put information about tested platform.
>>>>>> I just tested this issue with jdk-12+8 on RHEL6/7 x86_64 and Ubuntu
>>>>>> 14.04.5 x86_64.
>>>>>> Still I could recreate this issue.
>>>>>>
>>>>>> Test instruction is as follows:
>>>>>> 1. Compile and run FontChangeTest
>>>>>> 2. Press "Shuffle" button to top
>>>>>> 3. Change Font size (TextField) "12" to "24" on right-buttom, then
>>>>>> press Enter/Return key
>>>>>>    Then above exception will be happened
>>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> On 2018-08-27 12:55, Krishna Addepalli wrote:
>>>>>>> Hi Ichiroh,
>>>>>>>
>>>>>>> I have tried the steps you outlined, but I'm not able to reproduce
>>>>>>> the issue you are seeing. Could you try with the latest jdk12 repo?
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Krishna
>>>>>>>
>>>>>>> -----Original Message-----
>>>>>>> From: Ichiroh Takiguchi <takiguc at linux.vnet.ibm.com>
>>>>>>> Sent: Friday, August 24, 2018 1:42 PM
>>>>>>> To: awt-dev at openjdk.java.net
>>>>>>> Subject: <AWT Dev> StackOverflowError happened by
>>>>>>> TextField.setFont(...)
>>>>>>>
>>>>>>> Hello.
>>>>>>>
>>>>>>> I could see following exception by TextField.setFont(...) by 
>>>>>>> jdk-12+6
>>>>>>>
>>>>>>> =====================
>>>>>>> Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
>>>>>>>          at
>>>>>>> java.desktop/javax.swing.plaf.basic.BasicTextUI$UpdateHandler.layoutContainer(BasicTextUI.java:2061) 
>>>>>>>          at
>>>>>>> java.desktop/java.awt.Container.layout(Container.java:1537)
>>>>>>>          at
>>>>>>> java.desktop/java.awt.Container.doLayout(Container.java:1526)
>>>>>>>          at
>>>>>>> java.desktop/java.awt.Container.validateTree(Container.java:1722)
>>>>>>>          at
>>>>>>> java.desktop/java.awt.Container.validate(Container.java:1657)
>>>>>>>          at
>>>>>>> java.desktop/sun.awt.X11.XTextFieldPeer.setFont(XTextFieldPeer.java:290) 
>>>>>>>          at
>>>>>>> java.desktop/java.awt.Component.validate(Component.java:2976)
>>>>>>>          at
>>>>>>> java.desktop/java.awt.Container.validateTree(Container.java:1740)
>>>>>>>          at
>>>>>>> java.desktop/java.awt.Container.validate(Container.java:1657)
>>>>>>>          at
>>>>>>> java.desktop/sun.awt.X11.XTextFieldPeer.setFont(XTextFieldPeer.java:290) 
>>>>>>>          at
>>>>>>> java.desktop/java.awt.Component.validate(Component.java:2976)
>>>>>>>          at
>>>>>>> java.desktop/java.awt.Container.validateTree(Container.java:1740)
>>>>>>> ...
>>>>>>> =====================
>>>>>>>
>>>>>>> It seemed that sun.awt.X11.XTextFieldPeer.setFont(...) was called
>>>>>>> recursively.
>>>>>>>
>>>>>>> I used following test program to recreate this issue.
>>>>>>> =====================
>>>>>>> import java.awt.*;
>>>>>>> import java.awt.event.*;
>>>>>>> import java.awt.font.*;
>>>>>>> import java.util.*;
>>>>>>>
>>>>>>> public class FontChangeTest extends Frame
>>>>>>>    implements ActionListener, ItemListener {
>>>>>>>    Panel p;
>>>>>>>    java.util.List list = Arrays.asList(
>>>>>>>      "1","2","3","4","5","6","7","8","9");
>>>>>>>    TextField[] textfs = new TextField[list.size()];;
>>>>>>>    Choice fontName, fontStyle;
>>>>>>>    TextField fontSize;
>>>>>>>    final static String[] fontStyles = new String[]{
>>>>>>>      "Plain","Bold","Italic","ItalicBold"};
>>>>>>>    final static int[] fontStylesId = new int[]{
>>>>>>>      Font.PLAIN,Font.BOLD,Font.ITALIC,Font.BOLD+Font.ITALIC};
>>>>>>>    Button btn;
>>>>>>>    final int fSize = 12;
>>>>>>>    void shuffle() {
>>>>>>>      Collections.shuffle(list);
>>>>>>>      for(int i=0; i<list.size(); i++) {
>>>>>>>        textfs[i].setText(list.get(i).toString());
>>>>>>>      }
>>>>>>>    }
>>>>>>>    void init() {
>>>>>>>      setLayout(new BorderLayout());
>>>>>>>      Panel p0 = new Panel();
>>>>>>>      p0.setLayout(new FlowLayout());
>>>>>>>      add(p0, BorderLayout.NORTH);
>>>>>>>      btn = new Button("Shuffle");
>>>>>>>      btn.addActionListener(this);
>>>>>>>      p0.add(btn);
>>>>>>>      Panel p1 = new Panel();
>>>>>>>      p1.setLayout(new FlowLayout());
>>>>>>>      add(p1, BorderLayout.SOUTH);
>>>>>>>      fontName = new Choice();
>>>>>>>      fontName.addItemListener(this);
>>>>>>>      for(String s : Toolkit.getDefaultToolkit().getFontList()) {
>>>>>>>        fontName.add(s);
>>>>>>>      }
>>>>>>>      p1.add(fontName);
>>>>>>>      fontStyle = new Choice();
>>>>>>>      fontStyle.addItemListener(this);
>>>>>>>      for(String s : fontStyles) {
>>>>>>>        fontStyle.add(s);
>>>>>>>      }
>>>>>>>      p1.add(fontStyle);
>>>>>>>      fontSize = new TextField(String.valueOf(fSize),2);
>>>>>>>      fontSize.addActionListener(this);
>>>>>>>      p1.add(fontSize);
>>>>>>>      p = new Panel();
>>>>>>>      add(p, BorderLayout.CENTER);
>>>>>>>      p.setLayout(new GridLayout(0,3,3,3));
>>>>>>>      for(int i=0; i<list.size(); i++) {
>>>>>>>        textfs[i] = new TextField(1);
>>>>>>>        textfs[i].setFont(new Font(fontName.getSelectedItem(),
>>>>>>> fontStylesId[fontStyle.getSelectedIndex()],
>>>>>>>                          fSize));
>>>>>>>        p.add(textfs[i]);
>>>>>>>      }
>>>>>>>      shuffle();
>>>>>>>    }
>>>>>>>    public void changeFont() {
>>>>>>>      int size;
>>>>>>>      try {
>>>>>>>        size = Integer.parseInt(fontSize.getText());
>>>>>>>        for(int i=0; i<textfs.length; i++) {
>>>>>>>          textfs[i].setFont(new Font(fontName.getSelectedItem(),
>>>>>>> fontStylesId[fontStyle.getSelectedIndex()],
>>>>>>>                            size));
>>>>>>>        }
>>>>>>>      } catch (java.lang.NumberFormatException nfe) {
>>>>>>>      }
>>>>>>>    }
>>>>>>>    FontChangeTest() {
>>>>>>>      super("FontChangeTest");
>>>>>>>      init();
>>>>>>>      addWindowListener(new WindowAdapter() {
>>>>>>>        public void windowClosing(WindowEvent we) { System.exit(0); }
>>>>>>>      });
>>>>>>>      pack();
>>>>>>>      setVisible(true);
>>>>>>>    }
>>>>>>>    public void actionPerformed(ActionEvent ae) {
>>>>>>>      if (ae.getSource().equals(btn)) {
>>>>>>>        p.setVisible(false);
>>>>>>>        shuffle();
>>>>>>>        p.setVisible(true);
>>>>>>>      } else if (ae.getSource().equals(fontSize)) {
>>>>>>>        changeFont();
>>>>>>>        pack();
>>>>>>>      }
>>>>>>>    }
>>>>>>>    public void itemStateChanged(ItemEvent ie) {
>>>>>>>      changeFont();
>>>>>>>      pack();
>>>>>>>    }
>>>>>>>    public static void main(String[] args) {
>>>>>>>      new FontChangeTest();
>>>>>>>    }
>>>>>>> }
>>>>>>> =====================
>>>>>>>
>>>>>>> Test instruction is as follows:
>>>>>>> 1. Compile and run FontChangeTest
>>>>>>> 2. Press "Shuffle" button to top
>>>>>>> 3. Click left buttom's Choice button, then change "Dialog" to
>>>>>>> "SansSerif"
>>>>>>>     Then above exception will be happened
>>>>>>>
>>>>>>> It worked fine with JDK8
>>>>>>> java version "1.8.0_181"
>>>>>>> Java(TM) SE Runtime Environment (build 1.8.0_181-b13) Java
>>>>>>> HotSpot(TM) 64-Bit Server VM (build 25.181-b13, mixed mode)
>>>>>>>
>>>>>>> Failed by
>>>>>>> openjdk version "12-ea" 2019-03-19
>>>>>>> OpenJDK Runtime Environment 19.3 (build 12-ea+6) OpenJDK 64-Bit
>>>>>>> Server VM 19.3 (build 12-ea+6, mixed mode)
>>>>>>>
>>>>>>> One of fix candidate is:
>>>>>>> =====================
>>>>>>> diff -r 945ba9278a27
>>>>>>> src/java.desktop/share/classes/java/awt/Component.java
>>>>>>> --- a/src/java.desktop/share/classes/java/awt/Component.java Tue
>>>>>>> Aug
>>>>>>> 07 00:06:52 2018 -0700
>>>>>>> +++ b/src/java.desktop/share/classes/java/awt/Component.java Fri
>>>>>>> Aug
>>>>>>> 24 16:59:19 2018 +0900
>>>>>>> @@ -1936,8 +1936,8 @@
>>>>>>>               if (peer != null) {
>>>>>>>                   f = getFont();
>>>>>>>                   if (f != null) {
>>>>>>> +                    peerFont = f;
>>>>>>>                       peer.setFont(f);
>>>>>>> -                    peerFont = f;
>>>>>>>                   }
>>>>>>>               }
>>>>>>>           }
>>>>>>> =====================
>>>>>>>
>>>>>>> I'm not sure, it's good or not...
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Ichiroh Takiguchi
>>>>>>> IBM Japan, Ltd.
>>>
> 


-- 
Best regards, Sergey.


More information about the awt-dev mailing list