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

Ichiroh Takiguchi takiguc at linux.vnet.ibm.com
Wed Sep 5 14:08:14 UTC 2018


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