<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Interesting, that exception does not happen on my macOS 15.3
system. The reproducer somehow also doesn't seem to trigger the
IndexOutOfBoundsExceptions on macOS for me, only on Windows so
far. On Windows, the large alert is shown as a broken stage with
no content and controls for me, which I guess is slightly better
than an exception, but also not ideal. So it seems like the
reproducer behavior depends a lot on the specific system.<br>
</p>
<div class="moz-cite-prefix">On 26/03/2025 19:35, Martin Fox wrote:<br>
</div>
<blockquote type="cite"
cite="mid:6532F614-D25B-4C55-9519-4DE1CD8629E0@gmail.com">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
Christopher,
<div><br>
</div>
<div>Yes, there might be more than one issue here. On the Mac the
call to Stage.showAndWait is making its way into the Mac glass
code where an exception is being thrown leading to another call
to Stage.showAndWait. I’ve attached the repeating block below. I
don’t see that pattern in the Windows stack trace you provided.</div>
<div><br>
</div>
<div>Martin</div>
<div><br>
</div>
<div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
ParentBoundsBug.lambda$start$0(ParentBoundsBug.java:25)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
java.base/java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:663)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
java.base/java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:658)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.graphics@25-internal/com.sun.glass.ui.Application.reportException">javafx.graphics@25-internal/com.sun.glass.ui.Application.reportException</a>(Application.java:452)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.graphics@25-internal/com.sun.glass.ui.mac.MacWindow._setBounds2">javafx.graphics@25-internal/com.sun.glass.ui.mac.MacWindow._setBounds2</a>(Native
Method)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.graphics@25-internal/com.sun.glass.ui.mac.MacWindow._setBounds">javafx.graphics@25-internal/com.sun.glass.ui.mac.MacWindow._setBounds</a>(MacWindow.java:70)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.graphics@25-internal/com.sun.glass.ui.Window.setBounds">javafx.graphics@25-internal/com.sun.glass.ui.Window.setBounds</a>(Window.java:589)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.graphics@25-internal/com.sun.javafx.tk.quantum.WindowStage.setBounds">javafx.graphics@25-internal/com.sun.javafx.tk.quantum.WindowStage.setBounds</a>(WindowStage.java:304)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.graphics@25-internal/javafx.stage.Window$TKBoundsConfigurator.apply">javafx.graphics@25-internal/javafx.stage.Window$TKBoundsConfigurator.apply</a>(Window.java:1566)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.graphics@25-internal/javafx.stage.Window.applyBounds">javafx.graphics@25-internal/javafx.stage.Window.applyBounds</a>(Window.java:1424)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.graphics@25-internal/javafx.stage.Window.adjustSize">javafx.graphics@25-internal/javafx.stage.Window.adjustSize</a>(Window.java:327)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.graphics@25-internal/javafx.stage.Window.sizeToScene">javafx.graphics@25-internal/javafx.stage.Window.sizeToScene</a>(Window.java:284)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.graphics@25-internal/javafx.stage.Window$12.invalidated">javafx.graphics@25-internal/javafx.stage.Window$12.invalidated</a>(Window.java:1215)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.base@25-internal/javafx.beans.property.BooleanPropertyBase.markInvalid">javafx.base@25-internal/javafx.beans.property.BooleanPropertyBase.markInvalid</a>(BooleanPropertyBase.java:110)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.base@25-internal/javafx.beans.property.BooleanPropertyBase.set">javafx.base@25-internal/javafx.beans.property.BooleanPropertyBase.set</a>(BooleanPropertyBase.java:145)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.graphics@25-internal/javafx.stage.Window.setShowing">javafx.graphics@25-internal/javafx.stage.Window.setShowing</a>(Window.java:1235)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.graphics@25-internal/javafx.stage.Window.show">javafx.graphics@25-internal/javafx.stage.Window.show</a>(Window.java:1250)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.graphics@25-internal/javafx.stage.Stage.show">javafx.graphics@25-internal/javafx.stage.Stage.show</a>(Stage.java:272)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.graphics@25-internal/javafx.stage.Stage.showAndWait">javafx.graphics@25-internal/javafx.stage.Stage.showAndWait</a>(Stage.java:427)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.controls@25-internal/javafx.scene.control.HeavyweightDialog.showAndWait">javafx.controls@25-internal/javafx.scene.control.HeavyweightDialog.showAndWait</a>(HeavyweightDialog.java:162)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
<a class="moz-txt-link-abbreviated" href="mailto:javafx.controls@25-internal/javafx.scene.control.Dialog.showAndWait">javafx.controls@25-internal/javafx.scene.control.Dialog.showAndWait</a>(Dialog.java:347)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
ParentBoundsBug.lambda$start$0(ParentBoundsBug.java:25)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
java.base/java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:663)</div>
<div><span class="Apple-tab-span" style="white-space:pre"> </span>at
java.base/java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:658)</div>
</div>
<div><br>
</div>
<div>
<div>
<blockquote type="cite">
<div>On Mar 26, 2025, at 10:49 AM, Christopher Schnick
<a class="moz-txt-link-rfc2396E" href="mailto:crschnick@xpipe.io"><crschnick@xpipe.io></a> wrote:</div>
<br class="Apple-interchange-newline">
<div>
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8">
<div>
<p>Hey Martin,<br>
<br>
thank you for looking into this. The initial
StackOverflow is a result of me forcing to reproduce
the bounds IndexOutOfBoundsException. The
StackOverflow can be ignored, it was merely the best
method I found to transition the scene graph into a
state where the IndexOutOfBoundsExceptions are thrown.
The OOBs are not thrown in every run though, it
sometimes takes a few tries. In our production
application, the same IndexOutOfBoundsExceptions also
occur randomly without a previous exception. You can
probably also reproduce the IndexOutOfBoundsExceptions
without the StackOverflow, but reproducing it was very
fragile, so I didn't look into it more.<br>
<br>
I don't think it has necessarily something to do with
the alert bounds as the IndexOutOfBoundsException is
also thrown if you don't show an alert at all. The
constant IndexOutOfBoundsExceptions in combination
with the alert showAndWait was how our application
entered the original crashing state. So the reproducer
is more like a two-in-one.<br>
<br>
Best<br>
Christopher Schnick<br>
</p>
<div class="moz-cite-prefix">On 26/03/2025 18:33, Martin
Fox wrote:<br>
</div>
<blockquote type="cite"
cite="mid:9560C9BE-BC2F-4F0D-B914-425969699179@gmail.com">
<meta http-equiv="content-type"
content="text/html; charset=UTF-8">
Yes, thank you Christopher for providing a
reproducible test case!
<div><br>
</div>
<div>I was able to trigger the problem on my Mac on
the first try. Since I’m using a modified version of
JavaFX the system didn’t crash but instead hit a
Java stack overflow error and produced a very long
stack trace.</div>
<div><br>
</div>
<div>At least on the Mac the problem seems to be that
you’re trying to pop an Alert containing a long
stack trace. While trying to adjust the Alert’s
bounds JavaFX is throwing another exception but I’m
not sure why. I’ll continue to look into it.</div>
<div><br>
</div>
<div>Thanks again,</div>
<div>Martin</div>
<div>
<div>
<div><br>
<blockquote type="cite">
<div>On Mar 25, 2025, at 12:16 PM, Andy
Goryachev <a class="moz-txt-link-rfc2396E"
href="mailto:andy.goryachev@oracle.com"
moz-do-not-send="true"><andy.goryachev@oracle.com></a>
wrote:</div>
<br class="Apple-interchange-newline">
<div>
<meta charset="UTF-8">
<div class="WordSection1"
style="page: WordSection1; caret-color: rgb(0, 0, 0); font-family: Optima-Regular; font-size: 14px; font-style: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration: none;">
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";">Thank
you, Christopher, for clarification!<o:p></o:p></span></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"><o:p> </o:p></span></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";">Personally,
I would consider this to be a problem
with the application design: the code
should limit the number of alerts
shown to the user. Do you really want
the user to click through hundreds of
alerts?<o:p></o:p></span></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"><o:p> </o:p></span></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";">Nevertheless,
you are right about the need for the
platform to gracefully handle the case
of too many nested event loops - by
throwing an exception with a
meaningful message, as Martin proposed
in<span class="Apple-converted-space"> </span><a
href="https://github.com/openjdk/jfx/pull/1741"
style="color: blue; text-decoration: underline;" moz-do-not-send="true"
class="moz-txt-link-freetext">https://github.com/openjdk/jfx/pull/1741</a><o:p></o:p></span></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"><o:p> </o:p></span></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";">Cheers,<o:p></o:p></span></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";">-andy<o:p></o:p></span></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"><o:p> </o:p></span></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"><o:p> </o:p></span></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"><o:p> </o:p></span></div>
<div
id="mail-editor-reference-message-container">
<div>
<div>
<div
style="border-width: 1pt medium medium; border-style: solid none none; border-color: rgb(181, 196, 223) currentcolor currentcolor; border-image: none; padding: 3pt 0in 0in;">
<p class="MsoNormal"
style="margin: 0in 0in 12pt; font-size: 10pt; font-family: Aptos, sans-serif;"><b><span
style="font-size: 12pt;">From:<span
class="Apple-converted-space"> </span></span></b><span
style="font-size: 12pt;">Christopher
Schnick <a
class="moz-txt-link-rfc2396E" href="mailto:crschnick@xpipe.io"
moz-do-not-send="true"><crschnick@xpipe.io></a><br>
<b>Date:<span
class="Apple-converted-space"> </span></b>Tuesday, March 25, 2025 at
11:52<br>
<b>To:<span
class="Apple-converted-space"> </span></b>Andy Goryachev <a
class="moz-txt-link-rfc2396E" href="mailto:andy.goryachev@oracle.com"
moz-do-not-send="true"><andy.goryachev@oracle.com></a><br>
<b>Cc:<span
class="Apple-converted-space"> </span></b>OpenJFX <a
class="moz-txt-link-rfc2396E" href="mailto:openjfx-dev@openjdk.org"
moz-do-not-send="true"><openjfx-dev@openjdk.org></a><br>
<b>Subject:<span
class="Apple-converted-space"> </span></b>Re: [External] : Re: JVM
crashes on macOS when entering
too many nested event loops<o:p></o:p></span></p>
</div>
<p>Hey Andy,<br>
<br>
so I think I was able to reproduce
this issue for our application.<br>
<br>
There are two main factors how
this can happen:<br>
- We use an alert-based error
reporter, meaning that we have a
default uncaught exception handler
set for all threads which will
showAndWait an Alert with the
exception message<br>
- As I reported yesterday with<span
class="Apple-converted-space"> </span><a
href="https://mail.openjdk.org/pipermail/openjfx-dev/2025-March/052963.html"
style="color: blue; text-decoration: underline;" moz-do-not-send="true"
class="moz-txt-link-freetext">https://mail.openjdk.org/pipermail/openjfx-dev/2025-March/052963.html</a>,
there are some rare exceptions
that can occur in a normal event
loop without interference of the
application, probably because of a
small bug in the bounds
calculation code<br>
<br>
If you combine these two factors,
you will end up with an infinite
loop of the showAndWait entering a
nested event loop, the event loop
throwing an internal exception,
and the uncaught exception handler
starting the same loop with
another alert. I don't think this
is a bad implementation from our
side, the only thing that we can
improve is to maybe check how deep
the uncaught exception loop is in
to prevent this from occurring
indefinitely. But I would argue
this can happen to any
application. Here is a sample
code, based on the reproducer from
the OutOfBounds report from
yesterday:<o:p></o:p></p>
<div>
<pre
style="margin: 0in; font-size: 8pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(207, 142, 109);">import </span><span
style="color: rgb(188, 190, 196);">javafx.application.Application;<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(207, 142, 109);">import </span><span
style="color: rgb(188, 190, 196);">javafx.application.Platform;<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(207, 142, 109);">import </span><span
style="color: rgb(188, 190, 196);">javafx.scene.Scene;<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(207, 142, 109);">import </span><span
style="color: rgb(188, 190, 196);">javafx.scene.control.Alert;<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(207, 142, 109);">import </span><span
style="color: rgb(188, 190, 196);">javafx.scene.control.Button;<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(207, 142, 109);">import </span><span
style="color: rgb(188, 190, 196);">javafx.scene.layout.Region;<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(207, 142, 109);">import </span><span
style="color: rgb(188, 190, 196);">javafx.scene.layout.StackPane;<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(207, 142, 109);">import </span><span
style="color: rgb(188, 190, 196);">javafx.scene.layout.VBox;<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(207, 142, 109);">import </span><span
style="color: rgb(188, 190, 196);">javafx.stage.Stage;<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"><o:p> </o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(207, 142, 109);">import </span><span
style="color: rgb(188, 190, 196);">java.io.IOException;<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(207, 142, 109);">import </span><span
style="color: rgb(188, 190, 196);">java.util.Arrays;<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"><o:p> </o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(207, 142, 109);">public class </span><span
style="color: rgb(188, 190, 196);">ParentBoundsBug </span><span
style="color: rgb(207, 142, 109);">extends </span><span
style="color: rgb(188, 190, 196);">Application {<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"><o:p> </o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(179, 174, 96);">@Override<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(179, 174, 96);"> </span><span
style="color: rgb(207, 142, 109);">public void </span><span
style="color: rgb(86, 168, 245);">start</span><span
style="color: rgb(188, 190, 196);">(Stage stage) </span><span
style="color: rgb(207, 142, 109);">throws </span><span
style="color: rgb(188, 190, 196);">IOException {<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> Thread.<i>setDefaultUncaughtExceptionHandler</i>((thread, throwable) -> {<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> throwable.printStackTrace();<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"><o:p> </o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(207, 142, 109);">if </span><span
style="color: rgb(188, 190, 196);">(Platform.<i>isFxApplicationThread</i>()) {<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(207, 142, 109);">var </span><span
style="color: rgb(188, 190, 196);">alert = </span><span
style="color: rgb(207, 142, 109);">new </span><span
style="color: rgb(188, 190, 196);">Alert(Alert.AlertType.</span><i><span
style="color: rgb(199, 125, 187);">ERROR</span></i><span
style="color: rgb(188, 190, 196);">);<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> alert.setHeaderText(throwable.getMessage());<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> alert.setContentText(Arrays.<i>toString</i>(throwable.getStackTrace()));<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> alert.showAndWait();<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> } </span><span
style="color: rgb(207, 142, 109);">else </span><span
style="color: rgb(188, 190, 196);">{<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(122, 126, 133);">// Do some other error handling for non-platform threads<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(122, 126, 133);"> // Probably just show the alert with a runLater()<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(122, 126, 133);"><o:p> </o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(122, 126, 133);"> // For this example, there are no exceptions outside the platform thread<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(122, 126, 133);"> </span><span
style="color: rgb(188, 190, 196);">}<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> });<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"><o:p> </o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(122, 126, 133);">// Run delayed as Application::reportException will only be called for exceptions<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(122, 126, 133);"> // after the application has started<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(122, 126, 133);"> </span><span
style="color: rgb(188, 190, 196);">Platform.<i>runLater</i>(() -> {<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> Scene scene = </span><span
style="color: rgb(207, 142, 109);">new </span><span
style="color: rgb(188, 190, 196);">Scene(createContent(), </span><span
style="color: rgb(42, 172, 184);">640</span><span
style="color: rgb(188, 190, 196);">, </span><span
style="color: rgb(42, 172, 184);">480</span><span
style="color: rgb(188, 190, 196);">);<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(199, 125, 187);">stage</span><span
style="color: rgb(188, 190, 196);">.setScene(scene);<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(199, 125, 187);">stage</span><span
style="color: rgb(188, 190, 196);">.show();<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(199, 125, 187);">stage</span><span
style="color: rgb(188, 190, 196);">.centerOnScreen();<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> });<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> }<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"><o:p> </o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(207, 142, 109);">private </span><span
style="color: rgb(188, 190, 196);">Region </span><span
style="color: rgb(86, 168, 245);">createContent</span><span
style="color: rgb(188, 190, 196);">() {<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(207, 142, 109);">var </span><span
style="color: rgb(188, 190, 196);">b1 = </span><span
style="color: rgb(207, 142, 109);">new </span><span
style="color: rgb(188, 190, 196);">Button(</span><span
style="color: rgb(106, 171, 115);">"Click me!"</span><span
style="color: rgb(188, 190, 196);">);<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(207, 142, 109);">var </span><span
style="color: rgb(188, 190, 196);">b2 = </span><span
style="color: rgb(207, 142, 109);">new </span><span
style="color: rgb(188, 190, 196);">Button(</span><span
style="color: rgb(106, 171, 115);">"Click me!"</span><span
style="color: rgb(188, 190, 196);">);<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(207, 142, 109);">var </span><span
style="color: rgb(188, 190, 196);">vbox = </span><span
style="color: rgb(207, 142, 109);">new </span><span
style="color: rgb(188, 190, 196);">VBox(b1, b2);<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> b1.boundsInParentProperty().addListener((observable, oldValue, newValue) -> {<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(199, 125, 187);">vbox</span><span
style="color: rgb(188, 190, 196);">.setVisible(!</span><span
style="color: rgb(199, 125, 187);">vbox</span><span
style="color: rgb(188, 190, 196);">.isVisible());<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> });<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> b2.boundsInParentProperty().addListener((observable, oldValue, newValue) -> {<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(199, 125, 187);">vbox</span><span
style="color: rgb(188, 190, 196);">.setVisible(!</span><span
style="color: rgb(199, 125, 187);">vbox</span><span
style="color: rgb(188, 190, 196);">.isVisible());<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> });<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> vbox.boundsInParentProperty().addListener((observable, oldValue, newValue) -> {<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(199, 125, 187);">vbox</span><span
style="color: rgb(188, 190, 196);">.setVisible(!</span><span
style="color: rgb(199, 125, 187);">vbox</span><span
style="color: rgb(188, 190, 196);">.isVisible());<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> });<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"><o:p> </o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(207, 142, 109);">var </span><span
style="color: rgb(188, 190, 196);">stack = </span><span
style="color: rgb(207, 142, 109);">new </span><span
style="color: rgb(188, 190, 196);">StackPane(vbox, </span><span
style="color: rgb(207, 142, 109);">new </span><span
style="color: rgb(188, 190, 196);">StackPane());<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> stack.boundsInParentProperty().addListener((observable, oldValue, newValue) -> {<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(199, 125, 187);">vbox</span><span
style="color: rgb(188, 190, 196);">.setVisible(!</span><span
style="color: rgb(199, 125, 187);">vbox</span><span
style="color: rgb(188, 190, 196);">.isVisible());<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> });<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(207, 142, 109);">return </span><span
style="color: rgb(188, 190, 196);">stack;<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> }<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"><o:p> </o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> </span><span
style="color: rgb(207, 142, 109);">public static void </span><span
style="color: rgb(86, 168, 245);">main</span><span
style="color: rgb(188, 190, 196);">(String[] args) {<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> <i>launch</i>();<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);"> }<o:p></o:p></span></pre>
<pre
style="margin: 0in; font-size: 10pt; font-family: "Courier New"; background: rgb(30, 31, 34);"><span
style="color: rgb(188, 190, 196);">}<o:p></o:p></span></pre>
</div>
<p><br>
If the same OutOfBounds exception
from the reported I linked happens
in the bounds calculation, which
happens approximately 1/5 runs for
me, this application will enter
new event loops until it crashes.
If the OutOfBounds doesn't
trigger, it will just throw a
StackOverflow but won't continue
the infinite loop of nested event
loops. So for the reproducer it is
important to try a few times until
you get the described OutOfBounds.<o:p></o:p></p>
<p>I attached the stacktrace of how
this fails. The initial
StackOverflow causes infinitely
many following exceptions in the
nested event loop.<o:p></o:p></p>
<p>Best<br>
Christopher Schnick<o:p></o:p></p>
<div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 12pt;">On
25/03/2025 18:28, Andy
Goryachev wrote:<o:p></o:p></span></div>
</div>
<blockquote
style="margin-top: 5pt; margin-bottom: 5pt;">
<div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";">Dear
Christopher:</span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"> </span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";">Were
you able to root cause why
your application enters that
many nested event loops?</span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"> </span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";">I
believe a well-behaved
application should never
experience that, unless
there is some design flaw or
a bug.</span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"> </span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";">-andy</span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"> </span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"> </span><o:p></o:p></div>
<div
id="mail-editor-reference-message-container">
<div>
<div>
<div
style="border-width: 1pt medium medium; border-style: solid none none; border-color: rgb(181, 196, 223) currentcolor currentcolor; border-image: none; padding: 3pt 0in 0in;">
<p class="MsoNormal"
style="margin: 0in 0in 12pt; font-size: 10pt; font-family: Aptos, sans-serif;"><b><span
style="font-size: 12pt;">From:<span class="Apple-converted-space"> </span></span></b><span
style="font-size: 12pt;">Christopher Schnick<span
class="Apple-converted-space"> </span><a
href="mailto:crschnick@xpipe.io"
style="color: blue; text-decoration: underline;" moz-do-not-send="true"><crschnick@xpipe.io></a><br>
<b>Date:<span
class="Apple-converted-space"> </span></b>Monday, March 10, 2025 at
19:45<br>
<b>To:<span
class="Apple-converted-space"> </span></b>Andy Goryachev<span
class="Apple-converted-space"> </span><a
href="mailto:andy.goryachev@oracle.com"
style="color: blue; text-decoration: underline;" moz-do-not-send="true"><andy.goryachev@oracle.com></a><br>
<b>Subject:<span
class="Apple-converted-space"> </span></b>[External] : Re: JVM crashes
on macOS when
entering too many
nested event loops</span><o:p></o:p></p>
</div>
<p>Our code and some
libraries do enter some
nested event loops at a
few places when it makes
sense, but we didn't do
anything to explicitly
provoke this, this
occurred naturally in
our application. So it
would be nice if JavaFX
could somehow guard
against this, especially
since crashing the JVM
is probably the worst
thing that can happen.<br>
<br>
I looked at the
documentation, but it
seems like the public
API at
Platform::enterNestedEventLoop
does not mention this.<br>
From my understanding,
the method
Platform::canStartNestedEventLoop
is potentially the right
method to indicate to
the caller that the
limit is close by
returning false.<br>
And even if something
like an exception is
thrown when a nested
event loop is started
while it is close to the
limit, that would still
be much better than a
direct crash.<br>
<br>
Best<br>
Christopher Schnick<o:p></o:p></p>
<div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 12pt;">On 10/03/2025 18:51, Andy Goryachev wrote:</span><o:p></o:p></div>
</div>
<blockquote
style="margin-top: 5pt; margin-bottom: 5pt;">
<div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";">This
looks to me like
it might be
hitting the
(native) thread
stack size limit.</span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"> </span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";">c.s.glass.ui.Application::enterNestedEventLoop()
even warns about
it:</span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"> </span><o:p></o:p></div>
<div
style="margin: 0in; background: white;"><span
style="font-family: "Iosevka Fixed SS16"; color: rgb(255, 38, 0);">
* An application
may enter several
nested loops
recursively.
There's no</span><o:p></o:p></div>
<div
style="margin: 0in; background: white;"><span
style="font-family: "Iosevka Fixed SS16"; color: rgb(255, 38, 0);">
* limit of
recursion other
than that imposed
by the native
stack size.</span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"> </span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"> </span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";">-andy</span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"> </span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"> </span><o:p></o:p></div>
<div
style="margin: 0in; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt; font-family: "Iosevka Fixed SS16";"> </span><o:p></o:p></div>
<div
id="mail-editor-reference-message-container">
<div>
<div>
<div
style="border-width: 1pt medium medium; border-style: solid none none; border-color: rgb(181, 196, 223) currentcolor currentcolor; border-image: none; padding: 3pt 0in 0in;">
<p
class="MsoNormal"
style="margin: 0in 0in 12pt; font-size: 10pt; font-family: Aptos, sans-serif;"><b><span
style="font-size: 12pt;">From:<span class="Apple-converted-space"> </span></span></b><span
style="font-size: 12pt;">openjfx-dev<span class="Apple-converted-space"> </span><a
href="mailto:openjfx-dev-retn@openjdk.org"
style="color: blue; text-decoration: underline;" moz-do-not-send="true"><openjfx-dev-retn@openjdk.org></a><span
class="Apple-converted-space"> </span>on behalf of Martin Fox<span
class="Apple-converted-space"> </span><a
href="mailto:martinfox656@gmail.com"
style="color: blue; text-decoration: underline;" moz-do-not-send="true"><martinfox656@gmail.com></a><br>
<b>Date:<span
class="Apple-converted-space"> </span></b>Monday, March 10, 2025 at
10:10<br>
<b>To:<span
class="Apple-converted-space"> </span></b>Christopher Schnick<span
class="Apple-converted-space"> </span><a
href="mailto:crschnick@xpipe.io"
style="color: blue; text-decoration: underline;" moz-do-not-send="true"><crschnick@xpipe.io></a><br>
<b>Cc:<span
class="Apple-converted-space"> </span></b>OpenJFX<span
class="Apple-converted-space"> </span><a
href="mailto:openjfx-dev@openjdk.org"
style="color: blue; text-decoration: underline;" moz-do-not-send="true"><openjfx-dev@openjdk.org></a><br>
<b>Subject:<span
class="Apple-converted-space"> </span></b>Re: JVM crashes on macOS when
entering too
many nested
event loops</span><o:p></o:p></p>
</div>
<div>
<p
class="MsoNormal"
style="margin: 0in 0in 12pt; font-size: 10pt; font-family: Aptos, sans-serif;"><span
style="font-size: 11pt;">Hi Christopher,<br>
<br>
I was able to
reproduce this
crash. I wrote
a small
routine that
recursively
calls itself
in a runLater
block and then
enters a
nested event
loop. The
program
crashes when
creating loop
254. I’m not
sure where
that limit
comes from so
it’s possible
that consuming
some other
system
resource could
lower it. I
couldn’t see
any good way
to determine
how many loops
are active by
looking at the
crash report
since it
doesn’t show
the entire
call stack.<br>
I did a quick
trial on Linux
and was able
to create a
lot more loops
(over 600) but
then started
seeing erratic
behavior and
errors coming
from the Java
VM. The
behavior was
variable
unlike on the
Mac which
always crashes
when creating
loop 254.<br>
<br>
Martin<br>
<br>
> On Mar 7,
2025, at 6:24</span><span
style="font-size: 11pt; font-family: Arial, sans-serif;"> </span><span
style="font-size: 11pt;">AM, Christopher Schnick<span
class="Apple-converted-space"> </span><a
href="mailto:crschnick@xpipe.io"
style="color: blue; text-decoration: underline;" moz-do-not-send="true"><crschnick@xpipe.io></a><span
class="Apple-converted-space"> </span>wrote:<br>
><span
class="Apple-converted-space"> </span><br>
> Hello,<br>
><span
class="Apple-converted-space"> </span><br>
> I have
attached a JVM
fatal error
log that
seemingly was
caused by our
JavaFX
application
entering too
many nested
event loops,
which macOS
apparently
doesn't like.<br>
><span
class="Apple-converted-space"> </span><br>
> As far as
I know, there
is no upper
limit defined
on how often
an event loop
can be nested,
so I think
this is a bug
that can occur
in rare
situations.<br>
><span
class="Apple-converted-space"> </span><br>
> Best<br>
>
Christopher
Schnick<hs_err_pid.txt></span></p>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</blockquote>
</div>
</div>
</div>
</div>
</div>
</blockquote>
</div>
<br>
</div>
</div>
</blockquote>
</div>
</div>
</blockquote>
</div>
<br>
</div>
</blockquote>
</body>
</html>