CDI problems with sub-components

Hello,

i’m fairly new with vaadin and using the starter for vaadin-cdi from the website for my first experiments. Currently i would like to structure my ui in several classes each fit for injection of services via vaadin-cdi.

I seem to have some kind of wrong thoughts regarding the approach to do that.
MainView:

/**
 * The main view contains a simple label element and a template element.
 */
@Route("")
@PWA(name = "Project Base for Vaadin Flow with CDI", shortName = "Project Base")
public class MainView extends VerticalLayout {
    /**	 */
	private static final long serialVersionUID = 1L;
	
	@Inject
    private MessageBean messageBean;

	@Inject
	private SubView subView;
	
    public MainView() {        
    }

    @PostConstruct
    public void createUI(){
    	Button button = new Button("Click me(MainView)",
                event -> Notification.show(messageBean.getMessage()));
        add(button);
        
        add(subView);
    }
}

SubView:

@VaadinSessionScoped
public class SubView extends HorizontalLayout {

	/**	 */
	private static final long serialVersionUID = 1L;
	
	@Inject
    private MessageBean messageBean;

	public SubView() {		
	}

	@PostConstruct
    public void createUI(){	 
		Button button = new Button("Click me(SubView)",
                event -> Notification.show(messageBean.getMessage()));
        add(button);
    }	
}

Error when deploying on Wildfly 10.x:

com.vaadin.cdi.DeploymentValidator$DeploymentProblem: Normal scoped Vaadin components are not supported. 'com.nebelritter.vaadin.starter.cdi.SubView' should not belong to a normal scope.
	at com.vaadin.cdi.DeploymentValidator.lambda$validateBean$2(DeploymentValidator.java:268)
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
	at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
	at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
	at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
	at com.vaadin.cdi.DeploymentValidator.validateBean(DeploymentValidator.java:269)
	at com.vaadin.cdi.DeploymentValidator.lambda$validate$0(DeploymentValidator.java:259)
	at java.lang.Iterable.forEach(Iterable.java:75)
	at com.vaadin.cdi.DeploymentValidator.validate(DeploymentValidator.java:259)
	at com.vaadin.cdi.VaadinExtension.validateDeployment(VaadinExtension.java:82)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.jboss.weld.injection.StaticMethodInjectionPoint.invoke(StaticMethodInjectionPoint.java:88)
	at org.jboss.weld.injection.MethodInvocationStrategy$SpecialParamPlusBeanManagerStrategy.invoke(MethodInvocationStrategy.java:144)
	at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:313)
	at org.jboss.weld.event.ExtensionObserverMethodImpl.sendEvent(ExtensionObserverMethodImpl.java:125)
	at org.jboss.weld.event.ObserverMethodImpl.sendEvent(ObserverMethodImpl.java:291)
	at org.jboss.weld.event.ObserverMethodImpl.notify(ObserverMethodImpl.java:269)
	at org.jboss.weld.event.ObserverNotifier.notifySyncObservers(ObserverNotifier.java:302)
	at org.jboss.weld.event.ObserverNotifier.notify(ObserverNotifier.java:291)
	at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:160)
	at org.jboss.weld.event.ObserverNotifier.fireEvent(ObserverNotifier.java:154)
	at org.jboss.weld.bootstrap.events.AbstractContainerEvent.fire(AbstractContainerEvent.java:53)
	at org.jboss.weld.bootstrap.events.AbstractDeploymentContainerEvent.fire(AbstractDeploymentContainerEvent.java:35)
	at org.jboss.weld.bootstrap.events.AfterDeploymentValidationImpl.fire(AfterDeploymentValidationImpl.java:28)
	at org.jboss.weld.bootstrap.WeldStartup.validateBeans(WeldStartup.java:449)
	at org.jboss.weld.bootstrap.WeldBootstrap.validateBeans(WeldBootstrap.java:90)
	at org.jboss.as.weld.WeldStartService.start(WeldStartService.java:96)
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1948)
	at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1881)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
"}

I cannot see where i am using the normal scope, as from what i read annotations are not normal scoped…

Can somebody tell me how i can achieve sub view with injected services, or point me to some kind of tutorial regarding this?

Wild guess, but have you tried to remove @VaadinSessionScoped from the subview?

Generally @VaadinSessionScoped for a View seems like an odd choice; you generally should not scope a Vaadin Component in a scope bigger than UI scope at maximum. @ViewScoped sounds more appropriate.

Sorry for the late answer.

I replaced @VaadinSessionScoped by @ViewScoped and deployment worked.
Injection worked too, many thanks for the solution to my problem!

Is there an overview of how ‘big’ the scopes in question are?

There’s some documentation here: https://vaadin.com/docs/v13/flow/cdi/tutorial-cdi-contexts.html

Now that I look at your code again, looks like you’re using Vaadin 10+. There you shouldn’t use @ViewScoped , but use @RouteScoped instead (as there aren’t “Views” technically in V10+). Make sure you’re using the appropriate version of the CDI add-on!