Posting this here first as I’m not sure it’s a Vaadin bug or application bug. As we upgraded from 24.7.8 to 24.8 we are seeing below stacktrace. It’s easily reproducible by just clicking any (anchor) link in the application homepage. So, suspecting something fundamental is going on. The homepage itself loads fine, which is perhaps odd. Rolling back to 24.7.8 makes the issue go away. It’s a rather large application and we cannot reproduce it on a smaller test application here. I have seen some work being done on removing the elemental json lib, could it be related? The stacktrace has appeared before in the Vaadin github: missing notification when the setMaxFileSize value exceeded? · Issue #107 · vaadin/vaadin-upload-flow · GitHub but this seems unrelated.
System exception:java.lang.ClassCastException: class elemental.json.impl.JreJsonString cannot be cast to class elemental.json.JsonObject (elemental.json.impl.JreJsonString and elemental.json.JsonObject are in unnamed module of loader org.springframework.boot.loader.launch.LaunchedClassLoader @47547132)
at elemental.json.Json.parse(Json.java:53)
at com.vaadin.flow.component.UI.browserNavigate(UI.java:1891)
at com.vaadin.flow.component.ComponentEventBus.fireEventForListener(ComponentEventBus.java:244)
at com.vaadin.flow.component.ComponentEventBus.handleDomEvent(ComponentEventBus.java:501)
at com.vaadin.flow.component.ComponentEventBus.lambda$addDomTrigger$dd1b7957$1(ComponentEventBus.java:303)
at com.vaadin.flow.internal.nodefeature.ElementListenerMap.lambda$fireEvent$2(ElementListenerMap.java:475)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at com.vaadin.flow.internal.nodefeature.ElementListenerMap.fireEvent(ElementListenerMap.java:475)
at com.vaadin.flow.server.communication.rpc.EventRpcHandler.handleNode(EventRpcHandler.java:62)
at com.vaadin.flow.server.communication.rpc.AbstractRpcInvocationHandler.handle(AbstractRpcInvocationHandler.java:79)
at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocationData(ServerRpcHandler.java:568)
at com.vaadin.flow.server.communication.ServerRpcHandler.lambda$handleInvocations$6(ServerRpcHandler.java:549)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:549)
at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:376)
at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:136)
at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:63)
at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1852)
at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:398)
at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:106)
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:195)
If you set DEBUG level for com.vaadin.flow.server.frontend.FrontendUtils category, at some point you should see something like Auto-detected client-side router to use: ....
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<version>${vaadin.version}</version>
<configuration>
<!--
don't set this to true as it exposes us to possible npm related build issues that we don't care about
-->
<ciBuild>false</ciBuild>
<!-- this forces generation of prod.bundle when doing a normal maven build -->
<forceProductionBuild>true</forceProductionBuild>
<!-- to preserve fast startup times -->
**<reactEnable>false</reactEnable>**
</configuration>
<executions>
<execution>
<goals>
<goal>prepare-frontend</goal>
<goal>build-frontend</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
</plugin>
I cannot reproduce the issue using anchor or router links with 24.8.2.
The main difference I can spot is that in my case the vaadin-navigate event payload has always "historyState":null whereas you have "historyState":"".
Ok, I could reproduce, but only manually changing the browser history state in the browser console or adding a call like UI.getCurrent().getPage().getHistory().replaceState(Json.create(""), ""); on the server side.
We have indeed a UI initlistener that does below logic, because the application is loaded “portal-style” into an iframe.
event
.getSource()
.addUIInitListener(
uiInitEvent -> {
final UI ui = uiInitEvent.getUI();
try {
ui.addAfterNavigationListener(
e -> {
// using js to fetch the full URL
ui.getPage()
.executeJs("return window.top.location.pathname;")
.then(
String.class,
fullUrl -> {
// skip execution if the URL contains 'portal'
if (fullUrl != null && fullUrl.contains("portal")) {
return;
}
// needed to set the correct browser url when using via the
// portal
// as we're loaded into an iframe there
ui.getPage()
.executeJs(
"window.top.history.replaceState('', '', $0)",
BROWSER_URL_PREFIX
+ e.getLocationChangeEvent()
.getLocation()
.getPathWithQueryParameters());
});
});
} catch (Exception e) {
log.error("Error executing js to update url ", e);
}
});
@marcoc_753 thank you, this indeed fixes the issue. I’ll put this down to unorthodox browser manipulation from our side. It’s for this reason that I normally reject ui.getPage().executeJs() code in our applications, we just don’t know enough about it.