It looks like you are manipulating a property that is bound to a UI control on an external thread.

Property manipulations that are tied to controls that are part of an active (visible) Scene **must** be done on the FX thread.

Try:

    StreamingResponseHandler<AiMessage> streamingResponseHandler = new StreamingResponseHandler<>() {
                @Override
                public void onNext(String token) {
                    Platform.runLater(() -> searchAction.appendAnswer(token));
                }
    }

--John

On 19/12/2023 09:14, Frank Delporte wrote:

    Hi, while experimenting with a ChatGPT-like user interface, I
    found a crashing JVM with different types of errors when streaming
    the response towards a TextArea. This is probably caused by too
    fast refreshes of the text as pieces of content are received
    within the same milliseconds:

    19/12/2023 08:51:57.874 | DocsAnswerService                   |
    onNext               | INFO     | Appending ' better'
    19/12/2023 08:51:57.874 | DocsAnswerService                   |
    onNext               | INFO     | Appending ' performance'
    19/12/2023 08:51:57.875 | DocsAnswerService                   |
    onNext               | INFO     | Appending ' after'
    19/12/2023 08:51:57.978 | DocsAnswerService                   |
    onNext               | INFO     | Appending ' the'
    19/12/2023 08:51:57.979 | DocsAnswerService                   |
    onNext               | INFO     | Appending ' first'
    19/12/2023 08:51:57.979 | DocsAnswerService                   |
    onNext               | INFO     | Appending ' and'

    But even when collecting this pieces of text to e.g. minimum 255
    characters to reduce the number of TextArea changes, errors
    happen. So it's not clear how to prevent this as I can't define
    the threshold to be used...

    Dummy code causing the crash:

    public class SearchAction {
        private final StringProperty answer;
        ...
        public StringProperty getAnswerProperty() {
            return answer;
        }

        public void appendAnswer(String token) {
            this.answer.set(this.answer.getValue() + token);
        }
    }

    TextArea lastAnswer = new TextArea();
    lastAnswer.textProperty().bind(searchAction.getAnswerProperty());

    StreamingResponseHandler<AiMessage> streamingResponseHandler = new
    StreamingResponseHandler<>() {
                @Override
                public void onNext(String token) {
                    searchAction.appendAnswer(token);
                }
    }

    *Fatal Error *

    #
    # A fatal error has been detected by the Java Runtime Environment:
    #
    #  SIGBUS (0xa) at pc=0x000000013f53b630, pid=13013, tid=80715
    #
    # JRE version: OpenJDK Runtime Environment Zulu21.30+15-CA
    (21.0.1+12) (build 21.0.1+12-LTS)
    # Java VM: OpenJDK 64-Bit Server VM Zulu21.30+15-CA
    (21.0.1+12-LTS, mixed mode, sharing, tiered, compressed oops,
    compressed class ptrs, g1 gc, bsd-aarch64)
    # Problematic frame:
    # j
    
javafx.scene.text.Text.queryAccessibleAttribute(Ljavafx/scene/AccessibleAttribute;[Ljava/lang/Object;)Ljava/lang/Object;+576
    javafx.graphics@21.0.1
    #
    # No core dump will be written. Core dumps have been disabled. To
    enable core dumping, try "ulimit -c unlimited" before starting
    Java again
    #
    # An error report file with more information is saved as:
    # /Users/frankdelporte/GitLab/docs-langchain4j/hs_err_pid13013.log
    Exception in thread "JavaFX Application Thread"
    java.lang.StackOverflowError: Delayed StackOverflowError due to
    ReservedStackAccess annotated method
    at
    
javafx.graphics/com.sun.glass.ui.mac.MacAccessible.NSAccessibilityPostNotification(Native
    Method)
    at
    
javafx.graphics/com.sun.glass.ui.mac.MacAccessible.sendNotification(MacAccessible.java:816)
    at
    
javafx.graphics/javafx.scene.Node.notifyAccessibleAttributeChanged(Node.java:10004)
    at
    
javafx.graphics/javafx.scene.text.Text$TextAttribute$12.invalidated(Text.java:1847)
    at
    
javafx.base/javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:113)
    at
    
javafx.base/javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:148)
    at
    javafx.graphics/javafx.scene.text.Text.setCaretPosition(Text.java:961)
    at javafx.graphics/javafx.scene.text.Text$3.invalidated(Text.java:466)
    at
    
javafx.base/javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:110)
    at
    
javafx.base/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:145)
    at
    
javafx.base/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:50)
    at javafx.graphics/javafx.scene.text.Text.setText(Text.java:444)
    at
    
javafx.controls/javafx.scene.control.skin.TextAreaSkin.lambda$new$16(TextAreaSkin.java:347)
    at
    
javafx.controls/com.sun.javafx.scene.control.LambdaMultiplePropertyChangeListenerHandler.lambda$new$2(LambdaMultiplePropertyChangeListenerHandler.java:95)
    at
    
javafx.base/javafx.beans.WeakInvalidationListener.invalidated(WeakInvalidationListener.java:82)
    at
    
javafx.base/com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:360)
    at
    
javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:91)
    at
    
javafx.controls/javafx.scene.control.TextInputControl$TextProperty.fireValueChangedEvent(TextInputControl.java:1496)
    at
    
javafx.controls/javafx.scene.control.TextInputControl$TextProperty.markInvalid(TextInputControl.java:1500)
    at
    
javafx.controls/javafx.scene.control.TextInputControl$TextProperty.controlContentHasChanged(TextInputControl.java:1439)
    at
    
javafx.controls/javafx.scene.control.TextInputControl.lambda$new$0(TextInputControl.java:176)
    at
    
javafx.base/com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:147)
    at
    
javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:91)
    at
    
javafx.controls/javafx.scene.control.TextInputControl$ContentBase.fireValueChangedEvent(TextInputControl.java:149)
    at
    
javafx.controls/javafx.scene.control.TextArea$TextAreaContent.insert(TextArea.java:214)
    at
    
javafx.controls/javafx.scene.control.TextInputControl.replaceText(TextInputControl.java:1301)
    at
    
javafx.controls/javafx.scene.control.TextInputControl.filterAndSet(TextInputControl.java:1266)
    at
    
javafx.controls/javafx.scene.control.TextInputControl$TextProperty.doSet(TextInputControl.java:1517)
    at
    
javafx.controls/javafx.scene.control.TextInputControl$TextProperty$Listener.invalidated(TextInputControl.java:1540)
    at
    
javafx.base/com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:360)
    at
    
javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:91)
    at
    
javafx.base/javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:104)
    at
    
javafx.base/javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:111)
    at
    
javafx.base/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:145)
    at
    
javafx.base/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:50)
    at
    com.azul.docs.langchain4j.SearchAction.appendAnswer(SearchAction.java:45)
    at
    
com.azul.docs.langchain4j.DocsAnswerService$2.onNext(DocsAnswerService.java:172)
    at
    
dev.langchain4j.model.openai.OpenAiStreamingChatModel.handle(OpenAiStreamingChatModel.java:152)
    at
    
dev.langchain4j.model.openai.OpenAiStreamingChatModel.lambda$generate$0(OpenAiStreamingChatModel.java:133)
    at
    
dev.ai4j.openai4j.StreamingRequestExecutor$2.onEvent(StreamingRequestExecutor.java:178)
    at
    okhttp3.internal.sse.RealEventSource.onEvent(RealEventSource.kt:101)
    at
    
okhttp3.internal.sse.ServerSentEventReader.completeEvent(ServerSentEventReader.kt:108)
    at
    
okhttp3.internal.sse.ServerSentEventReader.processNextEvent(ServerSentEventReader.kt:52)
    at
    okhttp3.internal.sse.RealEventSource.processResponse(RealEventSource.kt:75)
    at
    okhttp3.internal.sse.RealEventSource.onResponse(RealEventSource.kt:46)
    at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)
    at
    
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
    at
    
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
    at java.base/java.lang.Thread.run(Thread.java:1583)
    [93.499s][warning][os] Loading hsdis library failed
    #
    # If you would like to submit a bug report, please visit:
    # http://www.azul.com/support/
    # The crash happened outside the Java Virtual Machine in native code.
    # See problematic frame for where to report the bug.
    #

    Process finished with exit code 134 (interrupted by signal 6:SIGABRT)

    *Error #1*

    Exception in thread "JavaFX Application Thread"
    java.lang.NullPointerException: Cannot read field "advances"
    because "this.layoutCache" is null
    at
    
javafx.graphics/com.sun.javafx.text.PrismTextLayout.shape(PrismTextLayout.java:919)
    at
    
javafx.graphics/com.sun.javafx.text.PrismTextLayout.layout(PrismTextLayout.java:1113)
    at
    
javafx.graphics/com.sun.javafx.text.PrismTextLayout.ensureLayout(PrismTextLayout.java:230)
    at
    
javafx.graphics/com.sun.javafx.text.PrismTextLayout.getBounds(PrismTextLayout.java:256)
    at
    javafx.graphics/javafx.scene.text.Text.getLogicalBounds(Text.java:432)
    at
    javafx.graphics/javafx.scene.text.Text.doComputeGeomBounds(Text.java:1186)
    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:117)
    at javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3812)
    at javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3774)
    at javafx.graphics/javafx.scene.Node.getLocalBounds(Node.java:3722)
    at
    
javafx.graphics/javafx.scene.Node$MiscProperties$3.computeBounds(Node.java:6812)
    at
    javafx.graphics/javafx.scene.Node$LazyBoundsProperty.get(Node.java:9749)
    at
    javafx.graphics/javafx.scene.Node$LazyBoundsProperty.get(Node.java:9740)
    at javafx.graphics/javafx.scene.Node.getBoundsInLocal(Node.java:3402)
    at
    
javafx.controls/javafx.scene.control.skin.TextAreaSkin$ContentView.layoutChildren(TextAreaSkin.java:1325)
    at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1208)
    at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215)
    at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215)
    at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215)
    at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215)
    at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215)
    at javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215)
    at javafx.graphics/javafx.scene.Scene.doLayoutPass(Scene.java:594)
    at
    javafx.graphics/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2600)
    at
    
javafx.graphics/com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:401)
    at
    
java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
    at
    javafx.graphics/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:400)
    at
    javafx.graphics/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:430)
    at
    
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:592)
    at
    
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:572)
    at
    
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:565)
    at
    
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:352)
    at
    
javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)

    *Error #2*

    Exception in thread "JavaFX Application Thread"
    java.lang.NullPointerException: Cannot read the array length
    because "this.lines" is null
    at
    
javafx.graphics/com.sun.javafx.text.PrismTextLayout.layout(PrismTextLayout.java:1316)
    at
    
javafx.graphics/com.sun.javafx.text.PrismTextLayout.ensureLayout(PrismTextLayout.java:230)
    at
    
javafx.graphics/com.sun.javafx.text.PrismTextLayout.getBounds(PrismTextLayout.java:256)
    at
    javafx.graphics/javafx.scene.text.Text.getLogicalBounds(Text.java:432)
    at
    javafx.graphics/javafx.scene.text.Text.doComputeGeomBounds(Text.java:1186)
    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:117)
    at javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3812)
    at javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3774)
    at javafx.graphics/javafx.scene.Node.getLocalBounds(Node.java:3722)
    at javafx.graphics/javafx.scene.Node.updateTxBounds(Node.java:3876)
    at
    javafx.graphics/javafx.scene.Node.getTransformedBounds(Node.java:3668)
    at javafx.graphics/javafx.scene.Node.updateBounds(Node.java:776)
    at javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1834)
    at javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1834)
    at javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1834)
    at javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1834)
    at javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1834)
    at javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1834)
    at javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1834)
    at javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1834)
    at
    javafx.graphics/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2615)
    at
    
javafx.graphics/com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:401)
    at
    
java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
    at
    javafx.graphics/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:400)
    at
    javafx.graphics/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:430)
    at
    
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:592)
    at
    
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:572)
    at
    
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:565)
    at
    
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:352)
    at
    
javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)

    Best regards
    Frank Delporte

    /Want to have coding-fun? /
    /Check my blog //https://webtechie.be//
    <https://webtechie.be/>/and book "Getting started with Java on
    Raspberry Pi" on //https://webtechie.be/books//
    <https://webtechie.be/books/>





Reply via email to