Originally I implemented CDI Utils for servlets merely because I didn’t see as much benefits in it for smaller applications such as portlets.
But that doesn’t mean it couldn’t work in such an environment. Making it tick might be as simple as implementing the CdiApplicationPortlet just like the existing CdiApplicationServlet or it might require some further tweaking. I would guess that beans cannot be directly injected to portlets so at least it’d require executing a JNDI-lookup for the BeanManager and doing the necessary injections to CdiApplicationPortlet “manually”.
The best bet might be to run Liferay bundled with a Java EE 6 compatible server such as JBoss AS or GlassFish.
I try to use CDI Utils to inject UI components and EJBs. Everything works fine including the MVP pattern, but at some point it seem that objects are no longer injected. Is there good way to figure out why an injection doesn’t take place.
For example currently I have the following issue:
Create the application
View is injected (MVP, actions can trigger the view change; all views are injected and views are using EJBs)
One view opens a subwindow - subwindow is also injected
The window shows a wizard using the Wizard AddOn - the wizard is also injected
The wizard should add several steps, but the steps are always null (@Inject - @EJB etc. instances are always null)
intresting Addon for using CDI in a VaadinApplikation.
Was wondering if there are any Plans to also Support the Vaadin Touchkit?
I personly do think it would be nice to be able to use CDI also for a Mobile-UI so I could Inject the Same Beans as I would use for a Desktop Version.
Window scope is to support single application instance over multiple browser tabs (it is discussed somewhere up in this thread if I’m not mistaken) .
Application scope would be the same instances over multiple browser tabs ( not advised for gui components ) .
Usually you should be using Window scope for all gui related components like views, and other view components and Application scope for application state that is independent from the gui…
If you look at Tomi’s demo application you will see the TextBundle implementatin org.vaadin.virkki.cdiutils.addressbook.util.Lang is Application scoped since you want only one instance of it for the Application instance, but most ( if not all the Components ) default to Window Scope .
Hi Marc
At least for the Vaadin 6 version this might be tricky as both Cdi Utils and TouchKit require a custom servlet. The new Cdi Utils 2 (for Vaadin 7) no longer requires its own servlet so at least in theory you could combine them. I haven’t tried it out myself though.
Hi,
i have started to use CDIUtils addon for my project and it seems interesting.
The only problem i have “stumbled” upon is when i need to change the locale of the Vaadin application.
As far as i know one way to change the locale dynamically is to recreate my widgets (i use some buttons and labels in my layout).
Specifically i create the different layouts in separate classes like the following :
@VaadinScoped
public class MyView extends VerticalLayout
{
@EJB
SomeService myService;
Button aButton = new Button();
....
public LoginView()
{
builtLayout();
}
public void builtLayout()
{
addComponent(aButton);
....
}
}
which I inject in the Vaadin Application using
@Inject
Instance<MyView> myView;
Since all the “views” (layouts) have been injected and created how is it possible to recreate them when the user changes the locale?
I use Vaadin 6.8.x
P.S. Ok this question might be not 100% related to the CDIUtils addon so I apologize in advance.
Hi Filip and the rest of you interested in this issue.
I18n is actually pretty easy to implement for Vaadin Components using CDI so I decided to include this feature in the newest CDI Utils release.
If you’ve used the @Preconfigured “captionKey” and “labelValueKey” features to get texts for your Components, then all you need to do to update the component captions/label values to a new language is to fire a localization event inside your app. This will not re-initialize your views but only update the visible texts.
You can find an example of this in the
CDI Utils Address Book project . Check it out and see what you think.
I am also experiencing the problem that Karsten mentions (EJB injection results in null references in some cases)
I am not using the MVP pattern provided by CDI i just have the following
@VaadinScoped
public class MyView extends VerticalLayout
{
@EJB
SomeService myService;
Button aButton = new Button();
....
public MyView()
{
myService.doStuff(); /* REFERENCE IS NULL in CONSTRUCTOR */
builtLayout();
}
public void builtLayout()
{
addComponent(aButton);
....
}
}
In my case I used the MVP patttern so I also annotate the WizardsStep with @AbstractPresenter.ViewInterface(TransferView.class) for additional processing…
Your code looks ok to me aside that you shouldn’t need to inject the Application in a servlet by yourself since CdiApplicationServlet does it for you. Just pass your application class to the servlet as an init parameter as you would do in any Vaadin app.
I am giving CDI_Utils a try. It works fine with one UI, but I would like to have more than one UI. I have a bit of sample code. Any suggestions for how to get this to work?
Here’s the first UI – it works fine by itself.
public class CdiutilstestUI extends UI
{
public static final String UI_NAME = "com.example.cdiutilstest.CdiutilstestUI";
@WebServlet(urlPatterns = "/*", initParams = {
@WebInitParam(name = VaadinSession.UI_PARAMETER, value = UI_NAME),
@WebInitParam(name = Constants.SERVLET_PARAMETER_UI_PROVIDER, value = CdiUIProvider.PROVIDER_NAME) })
public static class CDITestMainServlet extends VaadinServlet
{
}
@Override
protected void init(VaadinRequest request)
{
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
Button button = new Button("Click Me -- MAIN");
button.addClickListener(new Button.ClickListener()
{
public void buttonClick(ClickEvent event)
{
layout.addComponent(new Label("Thank you for clicking -- MAIN"));
}
});
layout.addComponent(button);
}
}
And now when I add this one it fails.
public class OneUI extends UI
{
public static final String UI_NAME = "com.example.cdiutilstest.one.OneUI";
@WebServlet(urlPatterns = {"one/*", "VAADIN/*"}, initParams = {
@WebInitParam(name = VaadinSession.UI_PARAMETER, value = UI_NAME),
@WebInitParam(name = Constants.SERVLET_PARAMETER_UI_PROVIDER, value = CdiUIProvider.PROVIDER_NAME) })
public static class CDITestOneServlet extends VaadinServlet
{
}
@Override
protected void init(VaadinRequest request)
{
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
Button button = new Button("Click Me -- ONE");
button.addClickListener(new Button.ClickListener()
{
public void buttonClick(ClickEvent event)
{
layout.addComponent(new Label("Thank you for clicking -- ONE"));
}
});
layout.addComponent(button);
}
}
I’m using CDI-Utils to get my stateless EJB’s in my Vaadin 7 web application thanks to the @UIScoped and @EJB annotations, and it’s working perfectly… util there is an exception in an EJB…
As soon as the exception is raised, it seems the stateless EJB reference is no more valid, and I get this exception :
16:40:48,770 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web]
.[default-host]
.
[/applirecrut-web].[Vaadin Application Servlet]
] (http-localhost/127.0.0.1:8080-1) JBWEB000236: Servlet.service() for servlet Vaadin Application Servlet threw exception: javax.ejb.NoSuchEJBException: JBAS014300: Impossible de trouver EJB ayant pour id {[84, -7, 71, -127, -91, 43, 74, 93, -117, 34, -25, 43, 58, 41, -107, 107]
}
at org.jboss.as.ejb3.component.stateful.StatefulComponentInstanceInterceptor.processInvocation(StatefulComponentInstanceInterceptor.java:63) [jboss-as-ejb3-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final-redhat-2.jar:1.1.1.Final-redhat-2]
at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:248) [jboss-as-ejb3-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:315) [jboss-as-ejb3-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:214) [jboss-as-ejb3-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final-redhat-2.jar:1.1.1.Final-redhat-2]
at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) [jboss-as-ejb3-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final-redhat-2.jar:1.1.1.Final-redhat-2]
at org.jboss.as.ejb3.security.AuthorizationInterceptor.processInvocation(AuthorizationInterceptor.java:122) [jboss-as-ejb3-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final-redhat-2.jar:1.1.1.Final-redhat-2]
at org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:76) [jboss-as-ejb3-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final-redhat-2.jar:1.1.1.Final-redhat-2]
at org.jboss.as.ejb3.component.interceptors.ShutDownInterceptorFactory$1.processInvocation(ShutDownInterceptorFactory.java:64) [jboss-as-ejb3-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final-redhat-2.jar:1.1.1.Final-redhat-2]
at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:59) [jboss-as-ejb3-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final-redhat-2.jar:1.1.1.Final-redhat-2]
at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50) [jboss-as-ee-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final-redhat-2.jar:1.1.1.Final-redhat-2]
at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:55) [jboss-as-ejb3-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final-redhat-2.jar:1.1.1.Final-redhat-2]
at org.jboss.as.ee.component.TCCLInterceptor.processInvocation(TCCLInterceptor.java:45) [jboss-as-ee-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final-redhat-2.jar:1.1.1.Final-redhat-2]
at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) [jboss-invocation-1.1.1.Final-redhat-2.jar:1.1.1.Final-redhat-2]
at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:165) [jboss-as-ee-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.as.ee.component.ViewDescription$1.processInvocation(ViewDescription.java:182) [jboss-as-ee-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final-redhat-2.jar:1.1.1.Final-redhat-2]
at org.jboss.as.ejb3.component.stateful.StatefulComponentIdInterceptor.processInvocation(StatefulComponentIdInterceptor.java:52) [jboss-as-ejb3-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final-redhat-2.jar:1.1.1.Final-redhat-2]
at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61) [jboss-invocation-1.1.1.Final-redhat-2.jar:1.1.1.Final-redhat-2]
at org.jboss.as.ee.component.ProxyInvocationHandler.invoke(ProxyInvocationHandler.java:72) [jboss-as-ee-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at be.aubay.applirecrut.services.CvIndexer$$$view9.getContentOfCVFromCandidate(Unknown Source) [applirecrut-ejb.jar:]
at be.aubay.applirecrut.web.utils.CvFileDownloader.handleConnectorRequest(CvFileDownloader.java:37) [classes:]
at com.vaadin.server.ConnectorResourceHandler.handleRequest(ConnectorResourceHandler.java:71) [vaadin-server-7.0.7.jar:7.0.7]
at com.vaadin.server.AbstractCommunicationManager.handleOtherRequest(AbstractCommunicationManager.java:2344) [vaadin-server-7.0.7.jar:7.0.7]
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:330) [vaadin-server-7.0.7.jar:7.0.7]
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:201) [vaadin-server-7.0.7.jar:7.0.7]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:847) [jboss-servlet-api_3.0_spec-1.0.2.Final-redhat-1.jar:1.0.2.Final-redhat-1]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:295) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:214) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:149) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:481) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]
at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.as.jpa.interceptor.WebNonTxEmCloserValve.invoke(WebNonTxEmCloserValve.java:50) [jboss-as-jpa-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.jboss.as.web.security.SecurityContextAssociationValve.invoke(SecurityContextAssociationValve.java:169) [jboss-as-web-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:145) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:97) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:102) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:336) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:856) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:653) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:920) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]
at java.lang.Thread.run(Thread.java:724) [rt.jar:1.7.0_25]
… where the reason means “Impossible to find an EJB with id …”.
I find very strange the fact that the stateless EJB is killed when there is a runtime exception while executing a method, as its state is not supposed to change during execution, no matter it is sucessful or not…
How can I avoid such a behavior? I was expected to get the exception back to my Vaadin code, and still be able to execute some methods on that EJB afterwards…
I think I found where the error was coming from: I was throwing some custom runtime exceptions, which were transformed to an EJB exception.
By annotating them with
@ApplicationException(rollback=true)
, they’re no more transformed, and the EJB is still alive and kicking after the error!
Seems like there is an issue when combining 7.1.x (with push enable) and cdi-utils.
Basically the MenuBar that tries to fire the even extends ViewComponent , it is injected into the view when the fireViewEvent(…) is invoked it gives the following error.
SEVERE: java.lang.IllegalStateException: Singleton not set for org.apache.felix.framework.BundleWiringImpl@4df10112
at org.glassfish.weld.ACLSingletonProvider$ACLSingleton.get(ACLSingletonProvider.java:110)
at org.jboss.weld.Container.instance(Container.java:54)
at org.jboss.weld.util.Beans.mergeInQualifiers(Beans.java:820)
at org.jboss.weld.bean.builtin.FacadeInjectionPoint.<init>(FacadeInjectionPoint.java:26)
at org.jboss.weld.event.EventImpl.selectEvent(EventImpl.java:86)
at org.jboss.weld.event.EventImpl.select(EventImpl.java:73)
at org.vaadin.virkki.cdiutils.mvp.ViewComponent.fireViewEvent(ViewComponent.java:40)
at com.adept.aims.viewdisplay.staff.StaffMenuBar.access$300(StaffMenuBar.java:40)
at com.adept.aims.viewdisplay.staff.StaffMenuBar$ViewMenuCommand.menuSelected(StaffMenuBar.java:226)
at com.vaadin.ui.MenuBar.changeVariables(MenuBar.java:186)
at com.vaadin.server.communication.ServerRpcHandler.changeVariables(ServerRpcHandler.java:403)
at com.vaadin.server.communication.ServerRpcHandler.handleBurst(ServerRpcHandler.java:228)
at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:111)
at com.vaadin.server.communication.PushHandler$2.run(PushHandler.java:158)
at com.vaadin.server.communication.PushHandler.callWithUi(PushHandler.java:289)
at com.vaadin.server.communication.PushHandler.onRequest(PushHandler.java:308)
at org.atmosphere.cpr.AsynchronousProcessor.action(AsynchronousProcessor.java:259)
at org.atmosphere.cpr.AsynchronousProcessor.suspended(AsynchronousProcessor.java:166)
at org.atmosphere.container.GlassFishWebSocketSupport.service(GlassFishWebSocketSupport.java:80)
at org.atmosphere.cpr.AtmosphereFramework.doCometSupport(AtmosphereFramework.java:1448)
at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:219)
at org.atmosphere.websocket.DefaultWebSocketProcessor$2.run(DefaultWebSocketProcessor.java:183)
at org.atmosphere.util.VoidExecutorService.execute(VoidExecutorService.java:101)
at org.atmosphere.websocket.DefaultWebSocketProcessor.dispatch(DefaultWebSocketProcessor.java:178)
at org.atmosphere.websocket.DefaultWebSocketProcessor.invokeWebSocketProtocol(DefaultWebSocketProcessor.java:167)
at org.atmosphere.container.GlassFishWebSocketHandler.onMessage(GlassFishWebSocketHandler.java:137)
at com.sun.grizzly.websockets.DefaultWebSocket.onMessage(DefaultWebSocket.java:164)
at com.sun.grizzly.websockets.frametypes.TextFrameType.respond(TextFrameType.java:75)
at com.sun.grizzly.websockets.DataFrame.respond(DataFrame.java:102)
at com.sun.grizzly.websockets.ProtocolHandler.readFrame(ProtocolHandler.java:151)
at com.sun.grizzly.websockets.WebSocketSelectionKeyAttachment.run(WebSocketSelectionKeyAttachment.java:88)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:722)
Solution is to disable Push
cdi-util (2.1.1 and 2.2.0 )
Server Glassfish 3.1.2.2
Weld upgraded to org.jboss.weld.osgi-bundle:1.1.14.Final - did not change behaviour
grizzly-websockets-1.9.50-fix.jar applied to get vaadin-push working.
I’ve decided to discontinue CDI Utils as such.
The custom CDI scope part is nowadays provided by Vaadin under a complementary license so there’s no longer need for a third party implementation.
The remaining utilities are separated as their own projects, namely:
CDI Properties and
CDI MVP
If you liked CDI Utils, please vote up the new add-ons as well