Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8303819

Exceptions after repetitive appends+deletes to TextArea

XMLWordPrintable

    • x86_64
    • windows_10
    • Verified

      ADDITIONAL SYSTEM INFORMATION :
      Intel i-6700K PC, 32 GB RAM, Windows 10 Pro, OpenJDK 17.0.2, IntelliJ IDEA Gradle project

      A DESCRIPTION OF THE PROBLEM :
      The application utilizes javafx.scene.control.TextArea as a limited lines console. The code repeatedly calls TextArea.this.appendText( text ), followed by line count checks and optional text head truncation TextArea.this.deleteText( 0, size ). On occasion the code may call TextArea.positionCaret( TextArea.this.getLength() );
      At some unidentified time (a minute or more after start), entire application GUI stalls. Application log shows series of exceptions:

      Exception in thread "JavaFX Application Thread" java.lang.IndexOutOfBoundsException: Index -1 out of bounds for length 3
      at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
      at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
      at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266)
      at java.base/java.util.Objects.checkIndex(Objects.java:359)
      at java.base/java.util.ArrayList.get(ArrayList.java:427)
      at javafx.base/com.sun.javafx.collections.ObservableListWrapper.get(ObservableListWrapper.java:89)
      at javafx.base/com.sun.javafx.collections.VetoableListDecorator.get(VetoableListDecorator.java:305)
      at javafx.graphics/javafx.scene.Parent.updateCachedBounds(Parent.java:1704)

      This series is prefaced with exception:

      Exception in thread "JavaFX Application Thread" java.lang.NullPointerException: Cannot load from object array because "this.runs" is null
      at javafx.graphics/com.sun.javafx.text.PrismTextLayout.layout(PrismTextLayout.java:1078)
      at javafx.graphics/com.sun.javafx.text.PrismTextLayout.ensureLayout(PrismTextLayout.java:223)
      at javafx.graphics/com.sun.javafx.text.PrismTextLayout.getBounds(PrismTextLayout.java:246)
      at javafx.graphics/javafx.scene.text.Text.getLogicalBounds(Text.java:432)
      at javafx.graphics/javafx.scene.text.Text.doComputeGeomBounds(Text.java:1187)
      at javafx.graphics/javafx.scene.text.Text$1.doComputeGeomBounds(Text.java:149)
      at javafx.graphics/com.sun.javafx.scene.shape.TextHelper.computeGeomBoundsImpl(TextHelper.java:90)
      at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:116)
      at javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3813)
      at javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3775)
      at javafx.graphics/javafx.scene.Node.getLocalBounds(Node.java:3723)
      at javafx.graphics/javafx.scene.Node.updateTxBounds(Node.java:3877)
      at javafx.graphics/javafx.scene.Node.getTransformedBounds(Node.java:3669)
      at javafx.graphics/javafx.scene.Parent.getChildTransformedBounds(Parent.java:1848)
      at javafx.graphics/javafx.scene.Parent.recomputeBounds(Parent.java:1637)
      at javafx.graphics/javafx.scene.Parent.doComputeGeomBounds(Parent.java:1501)
      at javafx.graphics/javafx.scene.Parent$1.doComputeGeomBounds(Parent.java:115)
      at javafx.graphics/com.sun.javafx.scene.ParentHelper.computeGeomBoundsImpl(ParentHelper.java:84)
      at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:116)
      at javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3813)
      at javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3775)
      at javafx.graphics/javafx.scene.Node.getLocalBounds(Node.java:3723)
      at javafx.graphics/javafx.scene.Node.updateTxBounds(Node.java:3877)
      at javafx.graphics/javafx.scene.Node.getTransformedBounds(Node.java:3669)
      at javafx.graphics/javafx.scene.Parent.getChildTransformedBounds(Parent.java:1848)
      at javafx.graphics/javafx.scene.Parent.updateCachedBounds(Parent.java:1709)
      at javafx.graphics/javafx.scene.Parent.recomputeBounds(Parent.java:1648)
      at javafx.graphics/javafx.scene.Parent.doComputeGeomBounds(Parent.java:1501)
      at javafx.graphics/javafx.scene.Parent$1.doComputeGeomBounds(Parent.java:115)
      at javafx.graphics/com.sun.javafx.scene.ParentHelper.computeGeomBoundsImpl(ParentHelper.java:84)
      at javafx.graphics/com.sun.javafx.scene.layout.RegionHelper.superComputeGeomBoundsImpl(RegionHelper.java:78)
      at javafx.graphics/com.sun.javafx.scene.layout.RegionHelper.superComputeGeomBounds(RegionHelper.java:62)
      at javafx.graphics/javafx.scene.layout.Region.doComputeGeomBounds(Region.java:3355)
      at javafx.graphics/javafx.scene.layout.Region$1.doComputeGeomBounds(Region.java:168)
      at javafx.graphics/com.sun.javafx.scene.layout.RegionHelper.computeGeomBoundsImpl(RegionHelper.java:89)
      at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:116)
      at javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3813)
      at javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3775)
      at javafx.graphics/javafx.scene.Node.getLocalBounds(Node.java:3723)
      at javafx.graphics/javafx.scene.Node.updateTxBounds(Node.java:3877)
      at javafx.graphics/javafx.scene.Node.getTransformedBounds(Node.java:3669)
      at javafx.graphics/javafx.scene.Parent.getChildTransformedBounds(Parent.java:1848)
      at javafx.graphics/javafx.scene.Parent.recomputeBounds(Parent.java:1637)
      at javafx.graphics/javafx.scene.Parent.doComputeGeomBounds(Parent.java:1501)
      at javafx.graphics/javafx.scene.Parent$1.doComputeGeomBounds(Parent.java:115)
      at javafx.graphics/com.sun.javafx.scene.ParentHelper.computeGeomBoundsImpl(ParentHelper.java:84)
      at javafx.graphics/com.sun.javafx.scene.layout.RegionHelper.superComputeGeomBoundsImpl(RegionHelper.java:78)
      at javafx.graphics/com.sun.javafx.scene.layout.RegionHelper.superComputeGeomBounds(RegionHelper.java:62)
      at javafx.graphics/javafx.scene.layout.Region.doComputeGeomBounds(Region.java:3355)
      at javafx.graphics/javafx.scene.layout.Region$1.doComputeGeomBounds(Region.java:168)
      at javafx.graphics/com.sun.javafx.scene.layout.RegionHelper.computeGeomBoundsImpl(RegionHelper.java:89)
      at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:116)
      at javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3813)
      at javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3775)
      at javafx.graphics/javafx.scene.Node.getLocalBounds(Node.java:3723)
      at javafx.graphics/javafx.scene.Node.updateTxBounds(Node.java:3877)
      at javafx.graphics/javafx.scene.Node.getTransformedBounds(Node.java:3669)
      at javafx.graphics/javafx.scene.Parent.getChildTransformedBounds(Parent.java:1848)
      at javafx.graphics/javafx.scene.Parent.recomputeBounds(Parent.java:1637)
      at javafx.graphics/javafx.scene.Parent.doComputeGeomBounds(Parent.java:1501)
      at javafx.graphics/javafx.scene.Parent$1.doComputeGeomBounds(Parent.java:115)
      at javafx.graphics/com.sun.javafx.scene.ParentHelper.computeGeomBoundsImpl(ParentHelper.java:84)
      at javafx.graphics/com.sun.javafx.scene.layout.RegionHelper.superComputeGeomBoundsImpl(RegionHelper.java:78)
      at javafx.graphics/com.sun.javafx.scene.layout.RegionHelper.superComputeGeomBounds(RegionHelper.java:62)
      at javafx.graphics/javafx.scene.layout.Region.doComputeGeomBounds(Region.java:3355)
      at javafx.graphics/javafx.scene.layout.Region$1.doComputeGeomBounds(Region.java:168)
      at javafx.graphics/com.sun.javafx.scene.layout.RegionHelper.computeGeomBoundsImpl(RegionHelper.java:89)
      at javafx.graphics/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:116)
      at javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3813)
      at javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3775)
      at javafx.graphics/javafx.scene.Node.updateBounds(Node.java:776)
      at javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1835)
      at javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1833)
      at javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1833)
      at javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1833)
      at javafx.graphics/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2530)
      at javafx.graphics/com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:421)
      at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
      at javafx.graphics/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:420)
      at javafx.graphics/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:450)
      at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:575)
      at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:555)
      at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:548)
      at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:353)
      at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
      at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
      at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
      at java.base/java.lang.Thread.run(Thread.java:833)

      It could be important. The application attempts to grab almost all memory in the PC at start, some amount could be returned back. Below is log of calls to Runtime.getRuntime().***Memory().
      Total, MB: 10000
      Max, MB : 24000
      Free, MB : 9920
      Total, MB: 24000
      Max, MB : 24000
      Free, MB : 301
      Total, MB: 24000
      Max, MB : 24000
      Free, MB : 206


      ---------- BEGIN SOURCE ----------
      public final class Console
      {
          TextInputControl control; // TextArea gets assigned here

          public void append( CharSequence text )
          {
              if( control != null )
              {
                  if( buffer != null )
                  {
                      control.setText( buffer );
                      buffer = null;
                  }
                  boolean atTheEnd = control.getCaretPosition() == control.getLength();
                  control.appendText( text.toString() );
                  String[] lines = control.getText().split( "\\n" );
                  int size = 0;
                  for( int l = 0; l < lines.length - lineCountMax; l++ )
                      size += lines[l].length() + 1;
                  if( size > 0 )
                      control.deleteText( 0, size );
                  if( atTheEnd )
                      control.positionCaret( control.getLength() );
              }
              else
              {
                  buffer = buffer + text;
              }
          }
          public void append( CharSequence text )
          {
              if( control != null )
              {
                  if( buffer != null )
                  {
                      control.setText( buffer );
                      buffer = null;
                  }
                  boolean atTheEnd = control.getCaretPosition() == control.getLength();
                  control.appendText( text.toString() );
                  String[] lines = control.getText().split( "\\n" );
                  int size = 0;
                  for( int l = 0; l < lines.length - lineCountMax; l++ )
                      size += lines[l].length() + 1;
                  if( size > 0 )
                      control.deleteText( 0, size );
                  if( atTheEnd )
                      control.positionCaret( control.getLength() );
              }
              else
              {
                  buffer = buffer + text;
              }
          }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      javafx.scene.Parent.java:1703
      current:
              for (int i = dirtyNodes.size() - 1; remainingDirtyNodes > 0; --i) {
                  final Node node = dirtyNodes.get(i);
      suggested:
              for (int i = dirtyNodes.size() - 1; i >=0 && remainingDirtyNodes > 0; --i) {
                  final Node node = dirtyNodes.get(i);


      FREQUENCY : often


            pnarayanaswa Praveen Narayanaswamy
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: