Mark, I confirmed and 'opted' to do the same as what you mentioned below, and web app is working fine. I 'moved' beans.xml from WEB-INF to META-INF, and app is running well, and running same as when beans.xml was in WEB-INF. I'll keep beans.xml in META-INF as per your recommendation.
*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].* Please note, (temporarily) commenting out @Asynchronous method calls in my app most likely resolved the issue in OP. Thanks, Howard On Tue, Nov 20, 2012 at 10:18 AM, Mark Struberg <strub...@yahoo.de> wrote: > 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 > >>>> > > >>>> > >>> > >> > > > > > > >