CDI, NullPointerException when an injected component marked as detached

Hi,

I’ve started to convert my application to use the Vaadin CDI feature. But soon after the first attempts I encountered this problem of NPE when a component marked as @NormalViewScoped injected inside a view marked as @CDIView gets detached. I’ve also attached a simplified sample to reproduce the error. In few words, MyUI class marked as @CDIUI(“”)

@Theme("mytheme")
@CDIUI("")
public class MyUI extends UI {

    @Inject
    private CDIViewProvider viewProvider;
    
    @Override
    protected void init(VaadinRequest vaadinRequest) {
        final VerticalLayout layout = new VerticalLayout();
        
        layout.setMargin(true);
        layout.setSpacing(true);
        
        setContent(layout);
        
        if (getNavigator() == null) {
            Navigator navigator = new Navigator(this, layout);
            navigator.addProvider(viewProvider);
            
        }
        
    }

    @WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
    @VaadinServletConfiguration(ui = MyUI.class, productionMode = false)
    public static class MyUIServlet extends VaadinCDIServlet {
    }
}

I have two views: DefView and ViewOne marked with @CDIView . DefView is the one loaded at the start from the navigator because it is marked as @CDIView(“”)

@CDIView("")
public class DefView extends VerticalLayout implements View {

    @Inject
    private InjectComp comp;
    
    @Override
    public void enter(ViewChangeEvent event) {
        Button button = new Button("Click Me");
        button.addClickListener( e -> {
           getUI().getNavigator().navigateTo("view-one");
        });
        removeAllComponents();
        addComponents(comp, button);
        
    }

}
@CDIView(value="view-one")
public class ViewOne extends VerticalLayout implements View{

    @Override
    public void enter(ViewChangeEvent event) {
         Button button = new Button("Click Me");
            button.addClickListener( e -> {
               getUI().getNavigator().navigateTo("view-tow");
            });
          
        removeAllComponents();   
        addComponent(button);
    }

}

And the InjectComp is as below:

[code]
@NormalViewScoped
public class InjectComp extends VerticalLayout {

@PostConstruct
private void init(){
    addComponent(new Label("GOGOGOGO"));
}

}
[/code]So when I click the button on DefView in order to navigate to the ViewOne, I get the NullPointerException as below:

12:43:10,788 SEVERE [com.vaadin.server.DefaultErrorHandler]
 (default task-56) : java.lang.NullPointerException
    at com.vaadin.server.AbstractClientConnector.detach(AbstractClientConnector.java:646)
    at com.vaadin.ui.AbstractComponent.detach(AbstractComponent.java:694)
    at com.vaadin.server.AbstractClientConnector.detach(AbstractClientConnector.java:641)
    at com.vaadin.ui.AbstractComponent.detach(AbstractComponent.java:694)
    at us.icitap.cc.test_vaadin_cdi.InjectComp$Proxy$_$$_WeldClientProxy.detach(Unknown Source)
    at com.vaadin.server.AbstractClientConnector.detach(AbstractClientConnector.java:641)
    at com.vaadin.ui.AbstractComponent.detach(AbstractComponent.java:694)
    at com.vaadin.ui.AbstractComponent.setParent(AbstractComponent.java:576)
    at com.vaadin.ui.AbstractComponentContainer.removeComponent(AbstractComponentContainer.java:229)
    at com.vaadin.ui.AbstractOrderedLayout.removeComponent(AbstractOrderedLayout.java:178)
    at com.vaadin.ui.AbstractComponentContainer.removeAllComponents(AbstractComponentContainer.java:75)
    at com.vaadin.navigator.Navigator$ComponentContainerViewDisplay.showView(Navigator.java:195)
    at com.vaadin.navigator.Navigator.navigateTo(Navigator.java:616)
    at com.vaadin.navigator.Navigator.navigateTo(Navigator.java:580)
    at us.icitap.cc.test_vaadin_cdi.DefView.lambda$enter$530fc82c$1(DefView.java:21)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.__invoke(DelegatingMethodAccessorImpl.java:43)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:510)
    at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:200)
    at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:163)
    at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1015)
    at com.vaadin.ui.Button.fireClick(Button.java:377)
    at com.vaadin.ui.Button$1.click(Button.java:54)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.__invoke(DelegatingMethodAccessorImpl.java:43)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:158)
    at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:119)
    at com.vaadin.server.communication.ServerRpcHandler.handleInvocation(ServerRpcHandler.java:435)
    at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:407)
    at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:273)
    at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:90)
    at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
    at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1422)
    at com.vaadin.cdi.server.VaadinCDIServletService.handleRequest(VaadinCDIServletService.java:92)
    at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:379)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:129)
    at io.undertow.websockets.jsr.JsrWebSocketFilter.doFilter(JsrWebSocketFilter.java:129)
    at io.undertow.servlet.core.ManagedFilter.doFilter(ManagedFilter.java:60)
    at io.undertow.servlet.handlers.FilterHandler$FilterChainImpl.doFilter(FilterHandler.java:131)
    at io.undertow.servlet.handlers.FilterHandler.handleRequest(FilterHandler.java:84)
    at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
    at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
    at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
    at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
    at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
    at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
    at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
    at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
    at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
    at io.undertow.servlet.handlers.ServletInitialHandler.jrHandle(ServletInitialHandler.java)
    at org.zeroturnaround.javarebel.integration.servlet.undertow.cbp.ServletInitialHandlerCBP.handleRequest(ServletInitialHandlerCBP.java:98)
    at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:284)
    at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:263)
    at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
    at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:174)
    at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
    at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:793)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

And base on my investigation so far this is all because of the injected component InjectComp that is marked as @NormalViewScoped. Somehow, because of using a proxy for the contextual instance, the ui is already null when the detached method on AbstractClientConnector.class gets called resulting in a NPE.

I know that using @NormalViewScoped with Vaadin components is discouraged, but the @ViewScoped does not work at all and if I will not be able to use this @NormalViewScoped for the vaadin components then the benifits of the CDI into vaadin are so limited only on the EJB and simple classes that still have to be inserted to the vaadin components through constructors or methods.

Is there any workaround on this or what I’m doing wrong here so I can correct it and still do the job using the benifits of Vaadin CDI.

Thank you so much.

Klau

I’m not able to upload the .rar file of the sample project. It is just a zip file of the source code from the Eclipse project.