JeremP
JeremP

Reputation: 47

Vaadin Spring Boot - There was an exception while trying to navigate to '' - NoSuchBeanDefinitionException

I'm using Vaadin and Spring Boot to build webapp used as registration form.

I'm getting an issue when deploying the webapp inside a Tomcat (but never when lauching directly from Intellij IDE).

The Stacktrace is :

2021-06-04 09:27:13.289 ERROR  [reportException] com.vaadin.flow.router.InternalServerError:97 : There was an exception while trying to navigate to ''
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.project.widget.ui.views.register.RegisterView': Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.project.widget.backend.services.OktaService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=OktaService)}
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:229) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1354) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1204) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:564) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:314) ~[spring-beans-5.3.5.jar:5.3.5]
    at com.vaadin.flow.spring.SpringInstantiator.getOrCreate(SpringInstantiator.java:117) ~[vaadin-spring-12.3.3.jar:?]
    at com.vaadin.flow.di.Instantiator.createRouteTarget(Instantiator.java:160) ~[flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.lambda$getRouteTarget$1(AbstractNavigationStateRenderer.java:137) ~[flow-server-2.5.3.jar:2.5.3]
    at java.util.Optional.orElseGet(Optional.java:267) ~[?:1.8.0_292]
    at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.getRouteTarget(AbstractNavigationStateRenderer.java:136) ~[flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.sendBeforeEnterEventAndPopulateChain(AbstractNavigationStateRenderer.java:525) ~[flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.createChainIfEmptyAndExecuteBeforeEnterNavigation(AbstractNavigationStateRenderer.java:505) ~[flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.router.internal.AbstractNavigationStateRenderer.handle(AbstractNavigationStateRenderer.java:222) ~[flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.router.Router.handleNavigation(Router.java:249) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.router.Router.navigate(Router.java:220) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.router.Router.navigate(Router.java:186) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.router.Router.initializeUI(Router.java:93) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.server.BootstrapHandler.initializeUIWithRouter(BootstrapHandler.java:1532) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.server.BootstrapHandler.createAndInitUI(BootstrapHandler.java:1525) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.server.BootstrapHandler.synchronizedHandleRequest(BootstrapHandler.java:475) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1547) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:247) [flow-server-2.5.3.jar:2.5.3]
    at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:111) [vaadin-spring-12.3.3.jar:?]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) [servlet-api.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:710) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:457) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:352) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312) [catalina.jar:9.0.46]
    at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:141) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:52) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006) [spring-webmvc-5.3.5.jar:5.3.5]
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898) [spring-webmvc-5.3.5.jar:5.3.5]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:626) [servlet-api.jar:4.0.FR]
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883) [spring-webmvc-5.3.5.jar:5.3.5]
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733) [servlet-api.jar:4.0.FR]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [catalina.jar:9.0.46]
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) [tomcat-websocket.jar:9.0.46]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [catalina.jar:9.0.46]
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) [spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.5.jar:5.3.5]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [catalina.jar:9.0.46]
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) [spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.5.jar:5.3.5]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [catalina.jar:9.0.46]
    at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:126) [spring-boot-2.4.4.jar:2.4.4]
    at org.springframework.boot.web.servlet.support.ErrorPageFilter.access$000(ErrorPageFilter.java:64) [spring-boot-2.4.4.jar:2.4.4]
    at org.springframework.boot.web.servlet.support.ErrorPageFilter$1.doFilterInternal(ErrorPageFilter.java:101) [spring-boot-2.4.4.jar:2.4.4]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.5.jar:5.3.5]
    at org.springframework.boot.web.servlet.support.ErrorPageFilter.doFilter(ErrorPageFilter.java:119) [spring-boot-2.4.4.jar:2.4.4]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [catalina.jar:9.0.46]
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) [spring-web-5.3.5.jar:5.3.5]
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119) [spring-web-5.3.5.jar:5.3.5]
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189) [catalina.jar:9.0.46]
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162) [catalina.jar:9.0.46]
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202) [catalina.jar:9.0.46]
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97) [catalina.jar:9.0.46]
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) [catalina.jar:9.0.46]
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143) [catalina.jar:9.0.46]
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [catalina.jar:9.0.46]
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687) [catalina.jar:9.0.46]
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78) [catalina.jar:9.0.46]
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) [catalina.jar:9.0.46]
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) [tomcat-coyote.jar:9.0.46]
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-coyote.jar:9.0.46]
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) [tomcat-coyote.jar:9.0.46]
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) [tomcat-coyote.jar:9.0.46]
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-coyote.jar:9.0.46]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_292]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_292]
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-util.jar:9.0.46]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_292]
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.project.widget.backend.services.OktaService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value=OktaService)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1790) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1346) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887) ~[spring-beans-5.3.5.jar:5.3.5]
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791) ~[spring-beans-5.3.5.jar:5.3.5]
    ... 83 more

My project is basically composed of 2 views and 1 backend service class used to interact with a remote API called "Oktaservice".

Here is the code of my main view causing the issue when reaching the root page :

RegisterView

@PWA(name = "Project", shortName = "Project", enableInstallPrompt = false)
@Route(value = "")
@PageTitle("Project")
@CssImport("./views/widget-view.css")
public class RegisterView extends Div {

    private final LanguageSettings languageSettings = new LanguageSettings();
    private final ResourceBundle bundle = ResourceBundle.getBundle(WidgetCaptions.class.getName(),
            languageSettings.getCurrentLanguage());

    private final OktaService oktaService;

    private final EmailField email = new EmailField();
    private final PasswordField password = new PasswordField();
    private final PasswordField confirmPassword = new PasswordField();
    private final GenderField gender;
    private final TextField firstName = new TextField();
    private final TextField lastName = new TextField();
    private final TextField company = new TextField();
    private final TextField street = new TextField();
    private final TextField zipCode = new TextField();
    private final TextField city = new TextField();
    private final CountryField country;
    private final TextField state = new TextField();
    private final Checkbox privacy_checkbox = new Checkbox();
    private final Checkbox conditions_checkbox = new Checkbox();

public RegisterView(@Autowired @Qualifier("OktaService") OktaService oktaService) { this.oktaService = oktaService; addClassName("register-view");

        ///////////// For the country selector /////////////
        DefaultSchema schema = oktaService.getSchema();
        List<OneOfItem> items = schema.getDefinitions().getCustom().getProperties().getCountry().getOneOf();

        HashMap<String, String> countries = new HashMap<>();
        List<String> values = new ArrayList<>();
        for (OneOfItem item : items) {
            String title = item.getTitle();
            String constant = item.getJsonMemberConst();

            countries.put(title, constant);
            values.add(title);
        }
        values.remove("-");
        country = new CountryField(bundle, values);
        ///////////////////////////////////////////////////
        gender = new GenderField(bundle);

        VerticalLayout page = new VerticalLayout();
        page.setDefaultHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);
        page.addClassName("page");

        VerticalLayout signInLayout = new VerticalLayout();
        signInLayout.setHorizontalComponentAlignment(FlexComponent.Alignment.CENTER);
        signInLayout.addClassName("mainLayout");

        signInLayout.add(createTitle(), createDescription());

        HorizontalLayout error_layout = new HorizontalLayout();
        error_layout.setDefaultVerticalComponentAlignment(FlexComponent.Alignment.CENTER);
        error_layout.getStyle().set("display", "none");
        error_layout.getStyle().set("color", "#E55240");
        Icon error_icon = new Icon(VaadinIcon.INFO_CIRCLE);
        error_icon.setSize("15px");
        Span error_msg = new Span(bundle.getString("ErrorKey"));
        error_msg.getStyle().set("font-size", "14px");
        error_msg.getStyle().set("margin-left", "5px");
        error_layout.add(error_icon, error_msg);

        Button nextButton = new Button();
        nextButton.setText(bundle.getString("ContinueKey"));
        nextButton.getStyle().set("background", "#44748A");
        nextButton.getStyle().set("color", "white");
        nextButton.getStyle().set("cursor","pointer");
        nextButton.getStyle().set("margin-top", "5px");

        nextButton.setWidthFull();

        signInLayout.add(createFormLayout(), conditionsCheck(), privacyCheck(), error_layout, nextButton, footerLayout());

        MainLayout mainLayout = new MainLayout(languageSettings);
        HorizontalLayout topBar = mainLayout.getTopBar();

        page.add(topBar, signInLayout);
        add(page);

        nextButton.addClickListener(e -> {
            if (checkFormValidation()) {
                CreateUser user = createUserProfile();
                if (!oktaService.createUser(user)) {
                    error_layout.getStyle().set("display", "block");
                } else {
                    UI.getCurrent().navigate(ValidationView.class);
                }
            }
        });
    }   

    /*------------------------- design functions below -------------------------------------*/

And my Service class :

@Service("OktaService")
@PropertySource(value = {"classpath:application.properties"})
public class OktaService {

    private HttpHeaders headers;
    private HttpStatus status;
    private String oktaApiUrl;
    private static final String SCHEMAS_API = "/meta/schemas/user/";

    private final Logger logger = LogManager.getLogger(OktaService.class);

    private RestClient rs;

    @Value("${okta.tenant}")
    private String oktaTenant;

    @Value("${okta.api.token}")
    private String oktaApiToken;

    @Value("${okta.custom.url}")
    private String oktaCustomUrl;

    public boolean createUser(CreateUser user) {
        rs = new RestClient(oktaTenant);
        rs.setApiToken(oktaApiToken);

        User userCreated = rs.postCreateUser(user, false);
        if (rs.getStatus() != null) {
            if (!rs.getStatus().toString().startsWith("4")) {
                logger.info("POST:CreateUser success : " + userCreated);
            } else {
                logger.error("POST:CreateUser Error creating user " + user.getProfile().getLogin());
                return false;
            }

            User userActivated = rs.postActivateUser(userCreated.getId(), true);
            if (!rs.getStatus().toString().startsWith("4")) {
                logger.info("POST:ActivateUser + sendEmail success : " + userCreated);
            } else {
                logger.error("POST:CreateUser Error creating user " + user.getProfile().getLogin());
                return false;
            }
        } else {
            return false;
        }
        return true;
    }

    public DefaultSchema getSchema() {
        RestTemplate rest = new RestTemplate();
        this.headers = new HttpHeaders();

        oktaApiUrl = "https://" + oktaTenant + "/api/v1";

        headers.add("Content-Type", "application/json");
        headers.add("Accept", "*/*");
        headers.add("Authorization", "SSWS " + oktaApiToken);

        String url = oktaApiUrl + SCHEMAS_API + "default";
        HttpEntity<String> requestEntity = new HttpEntity<String>("", headers);
        ResponseEntity<DefaultSchema> responseEntity;

        try {
            responseEntity = rest.exchange(url, HttpMethod.GET, requestEntity, DefaultSchema.class);
            this.setStatus(responseEntity.getStatusCode());
            return responseEntity.getBody();
        } catch (HttpClientErrorException e) {
            logger.error(e.getStatusCode());
            return null;
        }
    }

    public String getOktaCustomUrl() {
        return oktaCustomUrl;
    }


    public void setStatus(HttpStatus status) {
        this.status = status;
    }

With some research on this error I added the annotation @Autowired and @Qualifier to OktaService construction but did not change anything.

Thank you !

Upvotes: 0

Views: 1701

Answers (1)

Leif &#197;strand
Leif &#197;strand

Reputation: 8001

One potential problem could be with your Java package structure. Spring Boot does by default only look for annotated within the Java package (and it's children) that contains the Application class.

If your OktaService is in a location of your package structure, then it won't be found by default. As an example, if you have Application in com.example.myapp.ui and OktaService in com.example.myapp.service, then it won't work. If this is the case, then you can either change your package structure or set the scanBasePackages property in @SpringBootApplication to define a location that covers the entire application.

Upvotes: 3

Related Questions