Vaadin 7 with CDI UI with custom widgetset

Hi,

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:

@WebServlet(value = "/application/main/*", asyncSupported = true, initParams = {@WebInitParam(name = "UIProvider", value = "com.vaadin.cdi.CDIUIProvider")})
@VaadinServletConfiguration(productionMode = false, ui = MainUI.class, widgetset = "p.ApplicationWidgetSet")
public static class Servlet extends VaadinServlet {
}

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.

Thanks in advance.

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…

What servlet container do you use ??

Hmmmm…

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.

Does anybody resolved that?

Try @Widgetset annotation for the UI class?

Thanks Michael, it works! :slight_smile: