Dropping OpenEJB as we are now back to core JSF and related. I don't want to spam them ;)
1.): each container has pros and cons. And each of them needs different workarounds in edge cases :) 2.) I'm not using NetBeans, but it's basically the same scenario. In my project I opted for only using META-INF/beans.xml and completely dropping WEB-INF/beans.xml. This is perfectly fine as per the CDI spec [1]. >What is a good example or use case for using CDI events? Oh there are plenty! You just need to understand that CDI events != messages. CDI events are _always_ synchronous and only get delivered to beans in currently active contexts. E.g. if you fire a CDI event and have a public @SessionScoped class User then only the contextual instance 'User' from the current session will receive the event. You can think about CDI events as a method invocation where you do not know on which (and how many) instances you invoke it. A practical use case. In our application we have a big fat menu. The menu content is depending on the language of the user and his privileges. Since this can change on a language change or if the user logs in/out, etc most apps always re-calculate the whole MenuItem tree from the database. What we did in our application is the following: Menu is a @SessionScoped cdi bean and we do NOT re-calculate the items for every request. Instead we fire a UserSettingsChangedEvent on each language change and login/logout. In the Menu bean (and a lot other places) we @Observes UserSettingsChangedEvent and reload the menu in that case. This performs vastly better and allows us to radically cache lots of things. LieGrue, strub [1] https://issues.jboss.org/browse/CDI-218 >________________________________ > From: "Howard W. Smith, Jr." <smithh032...@gmail.com> >To: MyFaces Discussion <users@myfaces.apache.org>; Mark Struberg ><strub...@yahoo.de> >Cc: "us...@openejb.apache.org" <us...@openejb.apache.org> >Sent: Tuesday, November 20, 2012 3:56 PM >Subject: Re: Migrating to CDI: @Asynchronous > > >Mark, > > >Cool beans and agreed about @Asynchronous! Since I read about @Asynchronous on >Stackoverflow.com (a post by David Blevins), I decided to give it a try, but I >think I did read that 'asynchronous' (runnable, etc...) tasks are not all that >good in web application. > > >So, while you were writing your reply, I was already commenting out the call >to the @Asynchronous method, and I reverted to the synchronous version of the >method to update Google Calendar. After adding @Asynchronous, I added some >logic that works better than @Asynchronous, it will not do a google calendar >update on 'every' database update; I have some strategic processing in place >that brought the # of google calendar requests down by hundreds and even >thousands on a daily average. > > >You know what? I attempted to add to META-INF as well as WEB-INF (some days >ago), and I already reported (in an earlier post) that that didn't allow my >web app to start in TomEE (or Glassfish, if I was still using Glassfish when I >reported that earlier...smile). > > >In response to Eclipse...hopefully, no offense will be taken, i'm not a user >of eclipse, I've been a user of NetBeans ever since I started developing JSF >web application (since last summer, 2011), and I can be the loyal type if >something or someone treats me good. I was 'loyal' to Mojarra, but then I >heard about the Mojarra issues updating components via AJAX, so I migrated to >MyFaces Core (when I heard MyFaces Core 2.1.7+ performs better than Mojarra), >and then reading one of your posts, Mark, about OpenWebBeans performing fast, >and JIRA's and many people mentioning that CDI is better than JSF managed >beans, I decided to migrate to CDI, and determined to use any/all features >available that is offered by CDI, like events, SSE (server sent events), push >(like Atmosphere), etc... > > >Was having trouble using Atmosphere with Glassfish, so decided to give TomEE a >whirl, since you, Andy Bailey (a friend in PrimeFaces forum), and others >recommended TomEE. I like all that Glassfish 'markets' (or tries to sell) to >JSF developers, but I'm liking what I see and hear about TomEE, OpenWebBeans, >OpenEJB, etc... > > >What is a good example or use case for using CDI events? > >Thanks, >Howard > > > > >On Tue, Nov 20, 2012 at 9:36 AM, Mark Struberg <strub...@yahoo.de> wrote: > >Hi! >> >>One of my first advice is to make sure that beans.xml is really there for the >>container. >>I've seen this pretty often if someone starts the webapp directly from >>Eclipse. In that case the CDI container sometimes cannot find >>WEB-INF/beans.xml as eclipse doesn't set the classpath entries correctly. >> >>Sometimes it helps to add a META-INF/beans.xml to the webapp classpath. This >>will end up in WEB-INF/classes/META-INF/beans.xml and is perfectly fine from >>a spec perspective. >> >>There's a 30% chance that this is your problem ;) >> >>For the @Asynchronous: >> >>In general I do not really like @Asynchronous in webapps. It's really very >>seldom useful as you need to wait for the result anyway. It also doesn't get >>any Session, Request or Transaction information propagated over and it's not >>guaranteed to succeed. Think about what happens if an Exception gets hit in >>the asynchronous bean? >> >>This is really only useful in 2 cases: >>* fire and forget. If you don't take care if the job succeeds or not, then >>you might use it. >> >>* spawning off multiple jobs and waiting for all of them before returning. >> >>Still you need to take a lot of care about error handling and similar stuff. >> >> >>In our big application where we really need asynchronous tasks to be >>guaranteed to get executed we went the classic route which works on the Host >>since the 60s: we just write the job into an own 'Tasks' table and process it >>via an own Quartz job. On success, it updates the status. On error it sets >>the task to a failure status and adds information about the cause. >>That way we have a failure safe and restartable implementation. >> >>LieGrue, >>strub >> >> >> >>----- Original Message ----- >>> From: "Howard W. Smith, Jr." <smithh032...@gmail.com> >>> To: us...@openejb.apache.org; MyFaces Discussion <users@myfaces.apache.org> >>> Cc: >>> Sent: Tuesday, November 20, 2012 3:06 PM >>> Subject: Re: Migrating to CDI: @Asynchronous >>> >>> MyFaces Users, >>> >>> Please read OP (or my original email below), and then read this email, and >>> advise. >>> >>> Romain, >>> >>> Yes, I have a code snippet; please continue reading beyond/below first code >>> snippet. >>> >>> >>> Below is the code that is called by multiple beans as well as the bean >>> where this method is defined. >>> >>> /* >>> * Is it safe to start a new thread in a JSF managed bean? >>> * Look at answers by BalusC and David Blevins >>> * >>> http://stackoverflow.com/questions/6149919/is-it-safe-to-start-a-new-thread-in-a-jsf-managed-bean >>> * >>> * Java EE 6 Tutorial Chapter 27 Using Asynchronous Method Invocation >>> in Session Beans >>> * http://docs.oracle.com/javaee/6/tutorial/doc/gkkqg.html >>> */ >>> @Asynchronous >>> public Future<Date> updateGoogleCalendarPostEditAsync(Date >>> tripDateToBePlacedInQueue) { >>> >>> String log; >>> >>> Date tripDate = >>> usersController.queueDateAndOrUpdateGoogleCalendar(tripDateToBePlacedInQueue); >>> if (tripDate == null) { >>> return new AsyncResult<>(tripDate); >>> } >>> >>> performingGoogleCalendarMaintenace = true; >>> >>> try { >>> >>> if (usersController.googleCalendarHasEvents()) { >>> usersController.deleteEvents(tripDate, tripDate); >>> } >>> >>> String tripDateFrom = displayUtil.getDateFromDateTime(tripDate, >>> false); >>> String tripDateTo = displayUtil.getDateFromDateTime(tripDate, >>> false); >>> >>> List<Orders> list = getFacade().findAllConfirmed(tripDateFrom, >>> tripDateTo, true); >>> >>> if (list != null) { >>> for (Orders o : list) { >>> >>> usersController.addEventToCalendar(newGoogleCalendarEvent(o)); >>> } >>> } >>> >>> log = "pf_OrdersController.updateGoogleCalendarPostEditAsync(): >>> " + >>> new DateTime(tripDate).toString("MM/dd/yyyy") + >>> " processed successfully"; >>> } catch (Exception e) { >>> e.printStackTrace(); >>> messages.addFormErrorMsg("Error updating Google Calendar", >>> (e.getMessage() != null) ? e.getMessage() : ""); >>> log = "pf_OrdersController.updateGoogleCalendarPostEditAsync(): >>> " + >>> new DateTime(tripDate).toString("MM/dd/yyyy") + >>> " processing failed due to exception"; >>> } finally { >>> performingGoogleCalendarMaintenace = false; >>> } >>> System.out.println(log); >>> >>> // Return our result >>> return new AsyncResult<>(tripDate); >>> } >>> >>> Below, is code where the @Asynchronous method is *called within the same >>> bean*, and is not the last piece of code in the calling method. >> >>> >>> /* >>> * 1. if tripDate changed, then update Google Calendar for >>> original trip date >>> * 2. update Google Calendar for current trip date >>> */ >>> if (new >>> DateTime(current.getReportDateTime()).toString("MM/dd/yyyy").equals( >>> new >>> DateTime(tripDateBeforeEdit).toString("MM/dd/yyyy")) >>> == false) { >>> updateGoogleCalendarPostEditAsync(tripDateBeforeEdit); >>> } >>> updateGoogleCalendarPostEditAsync(current.getReportDateTime()); >>> } >>> if (invokePrepareEdit) >>> return prepareEdit(); >>> else >>> return null; >>> >>> Below, is code that is at the very end of a calling method and *called >>> within the same bean*, so there are no concerns here. >> >>> >>> /* >>> * update Google Calendar for current trip date >>> */ >>> updateGoogleCalendarPostEditAsync(current.getReportDateTime()); >>> return returnToBrowseOrView(); >>> >>> >>> Below, is code that was *added to another bean*, that will call the >>> *@Asynchronous >>> method defined on the other bean* (ordersController). >> >>> >>> public void updateGoogleCalendar() { >>> if (relatedEntityName.equals("orders")) { >>> Orders order = (Orders) relatedEntityObj; >>> >>> ordersController.updateGoogleCalendarPostEditAsync(order.getTripDateTime()); >>> } >>> } >>> >>> The method above, updateGoogleCalendar(), is called by code similar to >>> below, which is not the last code executed in calling method. >>> >>> if (relatedEntityName.equals("orders")) { >>> auditTrailDesc = "Updated ORDER: updated ORIGIN" + >>> (originTx != null && originTx.length() >>>> 0 >>> ? "(" + originTx + ")" : ""); >>> >>> auditTrailController.createFromRelatedEntity(relatedEntityName, >>> relatedEntityObj, auditTrailDesc); >>> *// update Google Calendar* >>> *updateGoogleCalendar();* >> >>> } >>> else if (relatedEntityName.equals("orderDriver")) { >>> OrderDriver od = (OrderDriver) relatedEntityObj; >>> OrderCostDetails orderCostDetails = >>> od.getOrderCostDetails(); >>> Orders order = new >>> ArrayList<>(orderCostDetails.getOrders()).get(0); >>> auditTrailDesc = "updated ORIGIN" + >>> >>> >>> >>> Thanks, >>> Howard >>> >>> >>> On Tue, Nov 20, 2012 at 2:25 AM, Romain Manni-Bucau >>> <rmannibu...@gmail.com>wrote: >>> >>>> Hi, >>>> >>>> can you share any snippet of code? >>>> >>>> *Romain Manni-Bucau* >>>> *Twitter: @rmannibucau <https://twitter.com/rmannibucau>* >>>> *Blog: **http://rmannibucau.wordpress.com/*< >>>> http://rmannibucau.wordpress.com/> >>>> *LinkedIn: **http://fr.linkedin.com/in/rmannibucau* >>>> *Github: https://github.com/rmannibucau* >>>> >>>> >>>> >>>> >>>> 2012/11/20 Howard W. Smith, Jr. <smithh032...@gmail.com> >>>> >>>> > Prior to migrating from JSF managed to CDI (and currently in >>> production), >>>> > my web app is using @Asynchronous on @SessionScoped bean to push data >>> to >>>> > and keep Google Calendar updated with specific data from the database. >>>> > >>>> > Honestly, I don't think I coded it correctly. What I mean by that, >>> I >>>> don't >>>> > think I'm handling or capturing the return value of @Asynchronous >>>> methods, >>>> > and honestly, I don't know where execution is ending after some or >>> most >>>> of >>>> > the calls to @Asynchronous methods. >>>> > >>>> > Currently, in production, the @Asynchronous method calls seem to be >>>> working >>>> > fine (production = MyFaces Core 2.1.9, JSF managed beans, Glassfish >>>> > 3.1.2.2). Now that I'm migrating to TomEE/CDI, it seems as though >>>> > @Asynchronous is breaking my app; of course, I don't mind >>> accepting >>>> > responsibility and calling it a developer error. @Asynchronous seems >>> to >>>> > result with the following error: >>>> > >>>> > Target Unreachable, identifier resolved to null >>>> > >>>> > I've read the following: >>>> > >>>> > >>>> > >>>> >>> http://www.andrejkoelewijn.com/wp/2010/03/05/jee-cdi-tip-target-unreachable-identifier-resolved-to-null/ >>>> > >>>> > >>>> > >>>> >>> http://stackoverflow.com/questions/4845041/target-unreachable-identifier-resolved-to-null >>>> > >>>> > but I have an empty beans.xml in WEB-INF and I have no JARs of my own >>> (so >>>> > no need to add beans.xml to META-INF, and please note, a lot of the >>> xhtml >>>> > pages in the app are working as designed. Also, I read something about >>>> > cyclic references (below) >>>> > >>>> > "injection points in one bean deployment archive cannot be >>> satisfied by a >>>> > bean in a separate bean archive, even when they are from libraries in >>> the >>>> > same module (web >>>> > archive)"< >>>> > >>>> >>> http://java.net/jira/browse/GLASSFISH-15721?focusedCommentId=301147&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_301147 >>>> > > >>>> > >>>> > but I'm sure that is not the cause of the error that I'm >>> experiencing. >>>> > >>>> > So, would you all recommend me to consider CDI Events instead of >>>> > @Asynchronous, both, or should I just fix @Asynchronous to work in the >>>> CDI >>>> > app? >>>> > >>>> > Thanks, >>>> > Howard >>>> > >>>> >>> >> > > >