myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Howard W. Smith, Jr." <smithh032...@gmail.com>
Subject Re: Migrating to CDI: @Asynchronous
Date Tue, 20 Nov 2012 14:59:15 GMT
I am considering @Timeout or @Schedule, but I think I want @Timeout (which
offers more control), as I didn't like how @Schedule was behaving when I
undeploy app on Glassfish, since I shutdown derby server via shutdown hook
or @predestroy (forgot how I did it).



On Tue, Nov 20, 2012 at 9:51 AM, Mark Struberg <struberg@yahoo.de> wrote:

> oh, if you are using OpenEJB/TomEE/ other EE server then you can also use
> @Timeout in an EJB instead of Quartz.
>
> LieGrue,
> strub
>
>
>
>
> ----- Original Message -----
> > From: Mark Struberg <struberg@yahoo.de>
> > To: MyFaces Discussion <users@myfaces.apache.org>; "
> users@openejb.apache.org" <users@openejb.apache.org>
> > Cc:
> > Sent: Tuesday, November 20, 2012 3:36 PM
> > Subject: Re: Migrating to CDI: @Asynchronous
> >
> > 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." <smithh032772@gmail.com>
> >>  To: users@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
> >>  <rmannibucau@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. <smithh032772@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
> >>>   >
> >>>
> >>
> >
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message