1

I have one UI class:

@SpringUI(path="order")
@Title("order")
@EnableJpaRepositories(basePackages="order")
@EntityScan(basePackages="order")
public class OrderGUI extends UI {
     Navigator navigator;
     navigator = new Navigator(this, this);
     navigator.addView("getOrderNumber", GetOrderNumber.class); //also tried navigator.addView("getOrderNumber", new GetOrderNumber());

then when I try to navigate to getOrderNumber after button click:

navigator.navigateTo("getOrderNumber");

I get an error:

java.lang.IllegalArgumentException: Trying to navigate to an unknown state '' and an error view provider not present

My view where I try to go is:

@SpringView
@Title("Order number")
public class GetOrderNumber extends VerticalLayout implements View {

why does it try to go to '' when I added view 'getOrderNumber'?

@Edit Stacktrace:

java.lang.IllegalArgumentException: Trying to navigate to an unknown state '' and an error view provider not present
    at com.vaadin.navigator.Navigator.navigateTo(Navigator.java:661) ~[vaadin-server-8.3.1.jar:8.3.1]
    at com.vaadin.ui.UI.doInit(UI.java:776) ~[vaadin-server-8.3.1.jar:8.3.1]
    at com.vaadin.server.communication.UIInitHandler.getBrowserDetailsUI(UIInitHandler.java:224) [vaadin-server-8.3.1.jar:8.3.1]
    at com.vaadin.server.communication.UIInitHandler.synchronizedHandleRequest(UIInitHandler.java:76) [vaadin-server-8.3.1.jar:8.3.1]
    at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40) [vaadin-server-8.3.1.jar:8.3.1]
    at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1601) [vaadin-server-8.3.1.jar:8.3.1]
    at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:445) [vaadin-server-8.3.1.jar:8.3.1]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:728) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:470) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:356) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:316) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:141) [spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177) [spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:52) [spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991) [spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925) [spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:974) [spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:877) [spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:851) [spring-webmvc-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:109) [spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) [spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) [spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-5.0.5.RELEASE.jar:5.0.5.RELEASE]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:496) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:790) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) [na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) [na:na]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.29.jar:8.5.29]
    at java.base/java.lang.Thread.run(Thread.java:844) [na:na]

@Edit A new class which is artificial HomePage:

package order;

import com.vaadin.navigator.View;
import com.vaadin.spring.annotation.SpringView;
import com.vaadin.ui.*;
import org.springframework.stereotype.Component;

@SpringView(name="")
@Component
public class HomePage extends VerticalLayout implements View {

    public HomePage()
    {
        getUI().getNavigator().navigateTo("order");
    }
}

but now it is throwing the error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homePage' defined in file [/home/mwalko/IdeaProjects/pyszne/target/classes/order/HomePage.class]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [order.HomePage]: Constructor threw exception; nested exception is java.lang.NullPointerException
Michu93
  • 5,058
  • 7
  • 47
  • 80

1 Answers1

2

When does this happens? By default, the view navigator uses the URL fragment part after the ! character to obtain the View name to display. So, in order to display the GetOrderNumber view, you should use an URL like this (supposing your application is deployed in the root context at localhost using the 8080 port):

http://localhost:8080/order/#!get-order-number

If you do not specify an explicit view name using the name attribute (for example @SpringView(name="myname")), the view name is derived from the View class name, using a "-" character at camel style word breaks.

Probably your navigation error occurs if you call the "base" url, for example:

http://localhost:8080/order

In this case, the view navigator tries to display a view with an empty name, because the view name is missing in the URL fragment part.

Furthermore, if you use the @SpringView annotations you should also use the Vaadin SpringNavigator to consistently handle the view lifecycle and navigation, instead of the default Navigator one.

Regarding the empty view name problem, in the Open Source project I manage, the Holon Platform, we introduced a @DefaultView annotation for the Spring View Navigator to face this annoying problem, in order to declare the View to be displayed when the view name is not provided.

You can check this example on GitHub on how to use the @DefaultView annotation in a Vaadin application configured using Spring Boot.

UPDATE:

The default Navigator implementation uses the Navigator.UriFragmentManager class to handle the View display logic, so it react to any URL fragment change just after the Navigator is bound to an UI (so including the first servlet call to show the UI).

I think you have two main ways to get around this behavior:

1. Provide a View mapped to an empty name, using "" as View name, to act as a "home page" View

2. Provide your own implementation of the com.vaadin.navigator.NavigationStateManager interface, avoiding to fire a view display event for empty URL fragments, and provide it to your Navigator instance using the Navigator(UI ui, NavigationStateManager stateManager, ViewDisplay display) constructor. So, in your code, you should construct the Navigator like this:

navigator = new Navigator(this, myNavigationStateManager, new SingleComponentContainerViewDisplay(this));

Furthermore, if you want a complete and consistent integration with Spring, you should use the SpringNavigator implementation. See http://vaadin.github.io/spring-tutorial/

Riccardo Righi
  • 226
  • 1
  • 6
  • This error occurs when I go to `@SpringUI(path="order")` - type `http://localhost:8080/order` in urlbar , it's throwed once and then everything is okey. Then when I navigateTo any `@SpringView` navigator works without any errors. – Michu93 Apr 26 '18 at 09:38
  • Hi @Michu93, if your UI is mapped to the `order` path, calling `http://localhost:8080/order` does not specify any view name (it is the root UI path), for this reason the Navigator tries to display a View with an empty name, which is not available and the error is thrown. You can either call directly your View using `http://localhost:8080/order#!get-order-number` or calling `Navigator.setState("get-order-number")` or `Navigator.navigateTo(...)` in your `UI.init()` method. See https://stackoverflow.com/questions/33059365/spring-boot-vaadin-set-default-view-in-vaadin-navigator#38849611 – Riccardo Righi Apr 27 '18 at 10:44
  • This is the reason we introduced the `@DefaultView` annotation in https://holon-platform.com, to easily solve this annoying issue – Riccardo Righi Apr 27 '18 at 10:46
  • you found the bug :D when I added `stateManager.setState("order");` then error have changed to `java.lang.IllegalArgumentException: Trying to navigate to an unknown state 'order' and an error view provider not present`. So that's it. Unfortunatelly in my application OrderGUI is `@SpringUI` so can't implement `View`. Should the first class be just Navigator which redirect to started site? Riccardo I strongly belive that holon-platform is really good but I am not familiar even with Vaadin yet so I don't want to change. – Michu93 Apr 27 '18 at 11:22
  • @Michu93 I understand your point, I edited my answer trying to suggest you some workarounds! – Riccardo Righi Apr 29 '18 at 19:40
  • It's a vicious circle. I created HomePage with `@SpringView(name="")` then Vaadin forced me to `@Override Component getViewComponent()`. What should it return? Can I somehow make Component from View? If I just could go somehow to `@SpringUI(path="order")` that would be fine – Michu93 May 12 '18 at 13:34
  • Some progress - I have extended VerticalLayout which let me ommit `@Override getViewComponent()` but `getUI().getNavigator().navigateTo("order");` is throwing `org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homePage': Invocation of init method failed; nested exception is java.lang.NullPointerException.` – Michu93 May 12 '18 at 14:11
  • Can you provide the code and the stack trace? This way I willingly try to help you – Riccardo Righi May 15 '18 at 07:35
  • question edited. I am not sure if it's not better to change this Vaadin's Navigator to SpringNavigator. – Michu93 May 18 '18 at 19:54