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

Ichiroh Takiguchi takiguc at linux.vnet.ibm.com
Tue Oct 30 17:39:21 UTC 2018


Hello.
Additional reviewer is required.

Please let me know if you have question and suggestion.

Thanks,
Ichiroh Takiguchi
IBM Japan, Ltd.

On 2018-10-05 06:21, Sergey Bylokhov wrote:
> 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.
>>>> 
>> 



More information about the awt-dev mailing list