Reputation: 47
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
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