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