<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>It looks like you are manipulating a property that is bound to a
UI control on an external thread.</p>
<p>Property manipulations that are tied to controls that are part of
an active (visible) Scene **must** be done on the FX thread.</p>
<p>Try:</p>
<div> StreamingResponseHandler<AiMessage>
streamingResponseHandler = new StreamingResponseHandler<>()
{<br>
</div>
<div> @Override<br>
</div>
<div> public void onNext(String token) {<br>
Platform.runLater(() ->
searchAction.appendAnswer(token));<br>
</div>
<div> }<br>
</div>
}<br>
<br>
--John<br>
<br>
<div class="moz-cite-prefix">On 19/12/2023 09:14, Frank Delporte
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:18c81245644.d1c3bcab152400.4552689918614942273@webtechie.be">
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type">
<div style="font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 10pt;">
<div class="zmail_extra" data-zbluepencil-ignore="true">
<blockquote style="margin: 0px;" id="blockquote_zmail">
<div>
<div style="font-family : Verdana, Arial, Helvetica,
sans-serif; font-size : 10pt;">
<div>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:<br>
</div>
<div><br>
</div>
<div>19/12/2023 08:51:57.874 |
DocsAnswerService |
onNext | INFO | Appending ' better'<br>
</div>
<div>19/12/2023 08:51:57.874 |
DocsAnswerService |
onNext | INFO | Appending '
performance'<br>
</div>
<div>19/12/2023 08:51:57.875 |
DocsAnswerService |
onNext | INFO | Appending ' after'<br>
</div>
<div>19/12/2023 08:51:57.978 |
DocsAnswerService |
onNext | INFO | Appending ' the'<br>
</div>
<div>19/12/2023 08:51:57.979 |
DocsAnswerService |
onNext | INFO | Appending ' first'<br>
</div>
<div>19/12/2023 08:51:57.979 |
DocsAnswerService |
onNext | INFO | Appending ' and'<br>
</div>
<div><br>
</div>
<div>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...<br>
</div>
<div><br>
</div>
<div>Dummy code causing the crash:<br>
</div>
<div><br>
</div>
<div>public class SearchAction {<br>
</div>
<div> private final StringProperty answer;<br>
</div>
<div> ...<br>
</div>
<div> public StringProperty getAnswerProperty() {<br>
</div>
<div> return answer;<br>
</div>
<div> }<br>
</div>
<div><br>
</div>
<div> public void appendAnswer(String token) {<br>
</div>
<div> this.answer.set(this.answer.getValue() +
token);<br>
</div>
<div> }<br>
</div>
<div>}<br>
</div>
<div><br>
</div>
<div>TextArea lastAnswer = new TextArea();<br>
</div>
<div>lastAnswer.textProperty().bind(searchAction.getAnswerProperty());<br>
</div>
<div><br>
</div>
<div>StreamingResponseHandler<AiMessage>
streamingResponseHandler = new
StreamingResponseHandler<>() {<br>
</div>
<div> @Override<br>
</div>
<div> public void onNext(String token) {<br>
</div>
<div> searchAction.appendAnswer(token);<br>
</div>
<div> }<br>
</div>
<div>}<br>
</div>
<div><br>
</div>
<div><b>Fatal Error </b><br>
</div>
<div><br>
</div>
<div>#<br>
</div>
<div># A fatal error has been detected by the Java
Runtime Environment:<br>
</div>
<div>#<br>
</div>
<div># SIGBUS (0xa) at pc=0x000000013f53b630,
pid=13013, tid=80715<br>
</div>
<div>#<br>
</div>
<div># JRE version: OpenJDK Runtime Environment
Zulu21.30+15-CA (21.0.1+12) (build 21.0.1+12-LTS)<br>
</div>
<div># 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)<br>
</div>
<div># Problematic frame:<br>
</div>
<div># j
javafx.scene.text.Text.queryAccessibleAttribute(Ljavafx/scene/AccessibleAttribute;[Ljava/lang/Object;)Ljava/lang/Object;+576
<a class="moz-txt-link-abbreviated" href="mailto:javafx.graphics@21.0.1">javafx.graphics@21.0.1</a><br>
</div>
<div>#<br>
</div>
<div># No core dump will be written. Core dumps have
been disabled. To enable core dumping, try "ulimit -c
unlimited" before starting Java again<br>
</div>
<div>#<br>
</div>
<div># An error report file with more information is
saved as:<br>
</div>
<div>#
/Users/frankdelporte/GitLab/docs-langchain4j/hs_err_pid13013.log<br>
</div>
<div>Exception in thread "JavaFX Application Thread"
java.lang.StackOverflowError: Delayed
StackOverflowError due to ReservedStackAccess
annotated method<br>
</div>
<div>at
javafx.graphics/com.sun.glass.ui.mac.MacAccessible.NSAccessibilityPostNotification(Native
Method)<br>
</div>
<div>at
javafx.graphics/com.sun.glass.ui.mac.MacAccessible.sendNotification(MacAccessible.java:816)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Node.notifyAccessibleAttributeChanged(Node.java:10004)<br>
</div>
<div>at
javafx.graphics/javafx.scene.text.Text$TextAttribute$12.invalidated(Text.java:1847)<br>
</div>
<div>at
javafx.base/javafx.beans.property.IntegerPropertyBase.markInvalid(IntegerPropertyBase.java:113)<br>
</div>
<div>at
javafx.base/javafx.beans.property.IntegerPropertyBase.set(IntegerPropertyBase.java:148)<br>
</div>
<div>at
javafx.graphics/javafx.scene.text.Text.setCaretPosition(Text.java:961)<br>
</div>
<div>at
javafx.graphics/javafx.scene.text.Text$3.invalidated(Text.java:466)<br>
</div>
<div>at
javafx.base/javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:110)<br>
</div>
<div>at
javafx.base/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:145)<br>
</div>
<div>at
javafx.base/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:50)<br>
</div>
<div>at
javafx.graphics/javafx.scene.text.Text.setText(Text.java:444)<br>
</div>
<div>at
javafx.controls/javafx.scene.control.skin.TextAreaSkin.lambda$new$16(TextAreaSkin.java:347)<br>
</div>
<div>at
javafx.controls/com.sun.javafx.scene.control.LambdaMultiplePropertyChangeListenerHandler.lambda$new$2(LambdaMultiplePropertyChangeListenerHandler.java:95)<br>
</div>
<div>at
javafx.base/javafx.beans.WeakInvalidationListener.invalidated(WeakInvalidationListener.java:82)<br>
</div>
<div>at
javafx.base/com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:360)<br>
</div>
<div>at
javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:91)<br>
</div>
<div>at
javafx.controls/javafx.scene.control.TextInputControl$TextProperty.fireValueChangedEvent(TextInputControl.java:1496)<br>
</div>
<div>at
javafx.controls/javafx.scene.control.TextInputControl$TextProperty.markInvalid(TextInputControl.java:1500)<br>
</div>
<div>at
javafx.controls/javafx.scene.control.TextInputControl$TextProperty.controlContentHasChanged(TextInputControl.java:1439)<br>
</div>
<div>at
javafx.controls/javafx.scene.control.TextInputControl.lambda$new$0(TextInputControl.java:176)<br>
</div>
<div>at
javafx.base/com.sun.javafx.binding.ExpressionHelper$SingleInvalidation.fireValueChangedEvent(ExpressionHelper.java:147)<br>
</div>
<div>at
javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:91)<br>
</div>
<div>at
javafx.controls/javafx.scene.control.TextInputControl$ContentBase.fireValueChangedEvent(TextInputControl.java:149)<br>
</div>
<div>at
javafx.controls/javafx.scene.control.TextArea$TextAreaContent.insert(TextArea.java:214)<br>
</div>
<div>at
javafx.controls/javafx.scene.control.TextInputControl.replaceText(TextInputControl.java:1301)<br>
</div>
<div>at
javafx.controls/javafx.scene.control.TextInputControl.filterAndSet(TextInputControl.java:1266)<br>
</div>
<div>at
javafx.controls/javafx.scene.control.TextInputControl$TextProperty.doSet(TextInputControl.java:1517)<br>
</div>
<div>at
javafx.controls/javafx.scene.control.TextInputControl$TextProperty$Listener.invalidated(TextInputControl.java:1540)<br>
</div>
<div>at
javafx.base/com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:360)<br>
</div>
<div>at
javafx.base/com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:91)<br>
</div>
<div>at
javafx.base/javafx.beans.property.StringPropertyBase.fireValueChangedEvent(StringPropertyBase.java:104)<br>
</div>
<div>at
javafx.base/javafx.beans.property.StringPropertyBase.markInvalid(StringPropertyBase.java:111)<br>
</div>
<div>at
javafx.base/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:145)<br>
</div>
<div>at
javafx.base/javafx.beans.property.StringPropertyBase.set(StringPropertyBase.java:50)<br>
</div>
<div>at
com.azul.docs.langchain4j.SearchAction.appendAnswer(SearchAction.java:45)<br>
</div>
<div>at
com.azul.docs.langchain4j.DocsAnswerService$2.onNext(DocsAnswerService.java:172)<br>
</div>
<div>at
dev.langchain4j.model.openai.OpenAiStreamingChatModel.handle(OpenAiStreamingChatModel.java:152)<br>
</div>
<div>at
dev.langchain4j.model.openai.OpenAiStreamingChatModel.lambda$generate$0(OpenAiStreamingChatModel.java:133)<br>
</div>
<div>at
dev.ai4j.openai4j.StreamingRequestExecutor$2.onEvent(StreamingRequestExecutor.java:178)<br>
</div>
<div>at
okhttp3.internal.sse.RealEventSource.onEvent(RealEventSource.kt:101)<br>
</div>
<div>at
okhttp3.internal.sse.ServerSentEventReader.completeEvent(ServerSentEventReader.kt:108)<br>
</div>
<div>at
okhttp3.internal.sse.ServerSentEventReader.processNextEvent(ServerSentEventReader.kt:52)<br>
</div>
<div>at
okhttp3.internal.sse.RealEventSource.processResponse(RealEventSource.kt:75)<br>
</div>
<div>at
okhttp3.internal.sse.RealEventSource.onResponse(RealEventSource.kt:46)<br>
</div>
<div>at
okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:519)<br>
</div>
<div>at
java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)<br>
</div>
<div>at
java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)<br>
</div>
<div>at java.base/java.lang.Thread.run(Thread.java:1583)<br>
</div>
<div>[93.499s][warning][os] Loading hsdis library failed<br>
</div>
<div>#<br>
</div>
<div># If you would like to submit a bug report, please
visit:<br>
</div>
<div># <a target="_blank"
href="http://www.azul.com/support/"
moz-do-not-send="true" class="moz-txt-link-freetext">http://www.azul.com/support/</a><br>
</div>
<div># The crash happened outside the Java Virtual
Machine in native code.<br>
</div>
<div># See problematic frame for where to report the
bug.<br>
</div>
<div>#<br>
</div>
<div><br>
</div>
<div>Process finished with exit code 134 (interrupted by
signal 6:SIGABRT)<br>
</div>
<div><br>
</div>
<div><b>Error #1</b><br>
</div>
<div><br>
</div>
<div>Exception in thread "JavaFX Application Thread"
java.lang.NullPointerException: Cannot read field
"advances" because "this.layoutCache" is null<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.text.PrismTextLayout.shape(PrismTextLayout.java:919)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.text.PrismTextLayout.layout(PrismTextLayout.java:1113)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.text.PrismTextLayout.ensureLayout(PrismTextLayout.java:230)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.text.PrismTextLayout.getBounds(PrismTextLayout.java:256)<br>
</div>
<div>at
javafx.graphics/javafx.scene.text.Text.getLogicalBounds(Text.java:432)<br>
</div>
<div>at
javafx.graphics/javafx.scene.text.Text.doComputeGeomBounds(Text.java:1186)<br>
</div>
<div>at
javafx.graphics/javafx.scene.text.Text$1.doComputeGeomBounds(Text.java:149)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.scene.shape.TextHelper.computeGeomBoundsImpl(TextHelper.java:90)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:117)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3812)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3774)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Node.getLocalBounds(Node.java:3722)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Node$MiscProperties$3.computeBounds(Node.java:6812)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Node$LazyBoundsProperty.get(Node.java:9749)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Node$LazyBoundsProperty.get(Node.java:9740)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Node.getBoundsInLocal(Node.java:3402)<br>
</div>
<div>at
javafx.controls/javafx.scene.control.skin.TextAreaSkin$ContentView.layoutChildren(TextAreaSkin.java:1325)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Parent.layout(Parent.java:1208)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Parent.layout(Parent.java:1215)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Scene.doLayoutPass(Scene.java:594)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2600)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:401)<br>
</div>
<div>at
java.base/java.security.AccessController.doPrivileged(AccessController.java:400)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:400)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:430)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:592)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:572)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:565)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:352)<br>
</div>
<div>at
javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)<br>
</div>
<div><br>
</div>
<div><b>Error #2</b><br>
</div>
<div><br>
</div>
<div>Exception in thread "JavaFX Application Thread"
java.lang.NullPointerException: Cannot read the array
length because "this.lines" is null<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.text.PrismTextLayout.layout(PrismTextLayout.java:1316)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.text.PrismTextLayout.ensureLayout(PrismTextLayout.java:230)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.text.PrismTextLayout.getBounds(PrismTextLayout.java:256)<br>
</div>
<div>at
javafx.graphics/javafx.scene.text.Text.getLogicalBounds(Text.java:432)<br>
</div>
<div>at
javafx.graphics/javafx.scene.text.Text.doComputeGeomBounds(Text.java:1186)<br>
</div>
<div>at
javafx.graphics/javafx.scene.text.Text$1.doComputeGeomBounds(Text.java:149)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.scene.shape.TextHelper.computeGeomBoundsImpl(TextHelper.java:90)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.scene.NodeHelper.computeGeomBounds(NodeHelper.java:117)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Node.updateGeomBounds(Node.java:3812)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Node.getGeomBounds(Node.java:3774)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Node.getLocalBounds(Node.java:3722)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Node.updateTxBounds(Node.java:3876)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Node.getTransformedBounds(Node.java:3668)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Node.updateBounds(Node.java:776)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1834)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1834)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1834)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1834)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1834)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1834)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1834)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Parent.updateBounds(Parent.java:1834)<br>
</div>
<div>at
javafx.graphics/javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2615)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.tk.Toolkit.lambda$runPulse$2(Toolkit.java:401)<br>
</div>
<div>at
java.base/java.security.AccessController.doPrivileged(AccessController.java:400)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:400)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:430)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:592)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:572)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:565)<br>
</div>
<div>at
javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:352)<br>
</div>
<div>at
javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)<br>
</div>
<div><br>
</div>
<div class="x_1879826395zmail_signature_below">
<div id="">
<div>Best regards<br>
</div>
<div>Frank Delporte<br>
</div>
<div>
<div><br>
</div>
</div>
<div><i>Want to have coding-fun? </i><br>
</div>
<div><i>Check my blog </i><a target="_blank"
href="https://webtechie.be/"
moz-do-not-send="true"><i>https://webtechie.be/</i></a><i>
and book "Getting started with Java on Raspberry
Pi" on </i><a target="_blank"
href="https://webtechie.be/books/"
moz-do-not-send="true"><i>https://webtechie.be/books/</i></a><br>
</div>
<div>
<div><br>
</div>
</div>
<div><br>
</div>
</div>
</div>
<div><br>
</div>
</div>
<br>
</div>
</blockquote>
</div>
<div><br>
</div>
</div>
<br>
</blockquote>
</body>
</html>