We’ve been using VAADIN CDI for a few months now, it’s great, amazing feature.
The problem started when we’ve tried to use a custom add-on.
I don’t know why VAADIN couldn’t inspect our classpath checking for custom widgetset and use it instead of the default vaadin widgetset.
Anyways here’s what we have:
RootUi running with VAADIN CDI at @UrlMappings(“/application/*”)
LoginUI running with VAADIN CDI with name “login” so it will be reached through /application/login.
MainUI running with VAADIN CDI with name “main” so it will be reached through /application/main.
The MainUI needs to use a custom WidgetSet (ApplicationWidgetSet) so we’ve inserted the follow code after UI class definition:
Unfortunately that doesn’t work as VAADIN CDI won’t boot up 'cause a VaadinServlet was already defined.
We’ve tried to change the path for WebServlet (like /main/) but VAADI CDI doesn’t work too.
Question:
How to make VAADIN CDI to work with multiple UI’s and one of the UIs using a custom widgetset?
Thanks in advance.
You might have even more problems with multiple UI’s.
I could not use a View between multiple UI’s , still need to dig deep in the CDIViewProvider to see why it does not honour the UIScoped qualifier, will log a ticket or submit a patch when I get time to dig around…
I did manage to start multiple UI’s though, But I think the main problem is that your URL mappings is ambiguous …
LoginUI 's /application/login will also match RootUi /application/* , not sure what the servlet spec says about situations like that…
@SuppressWarnings("serial")
@CDIUI(value = "/admin")
public class AdminUI extends AbstractCommonUI {
private static final Logger LOGGER = Logger.getLogger(AdminUI.class.getName());
@WebServlet(urlPatterns = {"/admin", "/admin/*"}, initParams = {
@WebInitParam(name = VaadinSession.UI_PARAMETER, value = Props.ADMIN_UI_NAME),
@WebInitParam(name = Constants.SERVLET_PARAMETER_UI_PROVIDER, value = "com.vaadin.cdi.CDIUIProvider"),
@WebInitParam(name = Constants.SERVLET_PARAMETER_PRODUCTION_MODE, value = "true")})
@ServletSecurity(
@HttpConstraint(rolesAllowed = {"ADMIN"}))
@DeclareRoles({"ADMIN"})
@RolesAllowed({"ADMIN"})
public static class AdminUIServlet extends VaadinServlet {
}
@Inject
private AdminViewImpl adminView;
@Inject
private CDIViewProvider viewProvider;
@Override
protected void init(final VaadinRequest request) {
LOGGER.log(Level.INFO, "InfoUI.init({0})", request);
final Navigator navigator = new Navigator(this, adminView);
navigator.addProvider(viewProvider);
setContent(adminView);
setSizeFull();
adminView.openView();
}
}
@SuppressWarnings("serial")
@CDIUI("/info")
public class InfoUI extends AbstractCommonUI {
private static final Logger LOGGER = Logger.getLogger(InfoUI.class.getName());
@Inject
private MainViewImpl mainView;
@Inject
private CDIViewProvider viewProvider;
@WebServlet( asyncSupported = true, urlPatterns = {"/info", "/info/*", "/VAADIN/*"}, initParams = {
@WebInitParam(name = VaadinSession.UI_PARAMETER, value = Props.INFO_UI_NAME),
@WebInitParam(name = Constants.SERVLET_PARAMETER_UI_PROVIDER, value = "com.vaadin.cdi.CDIUIProvider"),
@WebInitParam(name = Constants.SERVLET_PARAMETER_PRODUCTION_MODE, value = "true"),
@WebInitParam(name = Constants.SERVLET_PARAMETER_PUSH_MODE, value = "true")
})
public static class InfoUIApplicationServlet extends VaadinServlet {
}
@Override
protected void init(final VaadinRequest request) {
LOGGER.log(Level.INFO, "InfoUI.init({0})", request);
final Navigator navigator = new Navigator(this, mainView);
navigator.addProvider(viewProvider);
setLocale(Lang.EN_US);
setContent(mainView);
setSizeFull();
mainView.openView();
}
}
Actually the VAADIN CDI is already working, the problem is when I try to add a custom widgetset.
Now I have the follow:
@URLMapping("/application/*")
@CDIUI
public class RootUI extends UI {
}
@CDIUI(value = "login")
public class LoginUI extends AppUI {
}
@CDIUI(value = "main")
public class MainUI extends AppUI {
}
I’ve read the source code and sharing /application/ I can get both UI’s working under the same root path (application).
Everything works successfully but when I try to add Custom WidgetSet (using a servlet like you did with widgetset parameter), CDI stops working.
I get the follow messages in my server.log:
UIScopedContext registered|#]
Initializing web context for path |#]
Discovering Vaadin UIs…|#]
2 beans inheriting from UI discovered!|#]
Available Vaadin UIs for CDI deployment [manager, /acesso]
|#]
Vaadin related servlet is defined in deployment descriptor, automated deployment of VaadinCDIServlet is now disabled|#]
Done deploying Vaadin UIs|#]
It seems to me that as I have a custom servlet (extending VaadinServlet for each UI), VAADIN CDI won’t listen to /application/ anymore so I kind have to set uiProvider for the servlets but that doesn’t work either, I get NullPointer in every @Inject I have.
I dont see anything wrong in those logs BTW.
I also get :
Vaadin related servlet is defined in deployment descriptor, automated deployment of VaadinCDIServlet is now disabled|#]
It simply tells you that its using the deployment descriptors from your annotations and not the default VaadinCDIServlet , ie it is going to use your servlets (at least that is what I assume without checking the vaadin-cdi code ).
Does all the injections fail or only some injected values ?
It might be your application server’s implementation that have a issue with some of the add-on jars…
I would suggest to set your servlet containers logging a bit more verbose for the CDI related classes…
Some old issue but i am having exactly the same problem:
As long as i do not use CDI, the custom widgets are loaded perfectly as defined in
@VaadinServletConfiguration(productionMode = false, ui = OfertertestUI.class, widgetset="com.example.ofertertest.widgetset.OfertertestWidgetset")
When I add CDI support @CDIUI(“”) and remove @WebServlet definition, my custom widgetset is not loaded and can not be found.