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
>>>>  >
>>>>
>>>
>>
>
>
>

Reply via email to