You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@myfaces.apache.org by "Howard W. Smith, Jr." <sm...@gmail.com> on 2012/11/20 15:06:31 UTC

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
<rm...@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. <sm...@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
> >
>

Re: Migrating to CDI: @Asynchronous

Posted by "Howard W. Smith, Jr." <sm...@gmail.com>.
Jose, adding beans.xml to WEB-INF 'and' META-INF breaks my app; app won't
even start in TomEE, but as noted earlier/below, app can start and runs
well if beans.xml is in either folder. :)


On Wed, Nov 21, 2012 at 6:02 AM, José Luis Cetina <ma...@gmail.com>wrote:

> In my webapp i have the same issue. I need the beans.xml file in both
> folders too.
> Im using netbeans too.
> El nov 20, 2012 1:52 PM, "Howard W. Smith, Jr." <sm...@gmail.com>
> escribió:
>
> > Doh, NetBeans is probably not following the specification, because
> NetBeans
> > has squiggly line under the bean class name, and has the following as a
> > tip:
> >
> > CDI artifact is found but there is no beans.xml file.
> >
> > So, to avoid this, I need to have beans.xml in WEB-INF instead of
> META-INF.
> >
> > Per what I read in Java EE 6 tutorial (CDI) and other articles online, it
> > seems as though beans.xml is supposed to be placed in META-INF, if you
> have
> > JARs that you've developed that is referenced by the app. I could be
> saying
> > this incorrectly. :)
> >
> >
> > On Tue, Nov 20, 2012 at 1:57 PM, Howard W. Smith, Jr. <
> > smithh032772@gmail.com> wrote:
> >
> > > 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 <st...@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." <sm...@gmail.com>
> > >> >To: MyFaces Discussion <us...@myfaces.apache.org>; Mark Struberg <
> > >> struberg@yahoo.de>
> > >> >Cc: "users@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 <st...@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." <sm...@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
> > >> >>> <rm...@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. <sm...@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
> > >> >>>>  >
> > >> >>>>
> > >> >>>
> > >> >>
> > >> >
> > >> >
> > >> >
> > >>
> > >
> > >
> >
>

Re: Migrating to CDI: @Asynchronous

Posted by José Luis Cetina <ma...@gmail.com>.
In my webapp i have the same issue. I need the beans.xml file in both
folders too.
Im using netbeans too.
El nov 20, 2012 1:52 PM, "Howard W. Smith, Jr." <sm...@gmail.com>
escribió:

> Doh, NetBeans is probably not following the specification, because NetBeans
> has squiggly line under the bean class name, and has the following as a
> tip:
>
> CDI artifact is found but there is no beans.xml file.
>
> So, to avoid this, I need to have beans.xml in WEB-INF instead of META-INF.
>
> Per what I read in Java EE 6 tutorial (CDI) and other articles online, it
> seems as though beans.xml is supposed to be placed in META-INF, if you have
> JARs that you've developed that is referenced by the app. I could be saying
> this incorrectly. :)
>
>
> On Tue, Nov 20, 2012 at 1:57 PM, Howard W. Smith, Jr. <
> smithh032772@gmail.com> wrote:
>
> > 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 <st...@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." <sm...@gmail.com>
> >> >To: MyFaces Discussion <us...@myfaces.apache.org>; Mark Struberg <
> >> struberg@yahoo.de>
> >> >Cc: "users@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 <st...@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." <sm...@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
> >> >>> <rm...@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. <sm...@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
> >> >>>>  >
> >> >>>>
> >> >>>
> >> >>
> >> >
> >> >
> >> >
> >>
> >
> >
>

Re: Migrating to CDI: @Asynchronous

Posted by "Howard W. Smith, Jr." <sm...@gmail.com>.
Doh, NetBeans is probably not following the specification, because NetBeans
has squiggly line under the bean class name, and has the following as a tip:

CDI artifact is found but there is no beans.xml file.

So, to avoid this, I need to have beans.xml in WEB-INF instead of META-INF.

Per what I read in Java EE 6 tutorial (CDI) and other articles online, it
seems as though beans.xml is supposed to be placed in META-INF, if you have
JARs that you've developed that is referenced by the app. I could be saying
this incorrectly. :)


On Tue, Nov 20, 2012 at 1:57 PM, Howard W. Smith, Jr. <
smithh032772@gmail.com> wrote:

> 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 <st...@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." <sm...@gmail.com>
>> >To: MyFaces Discussion <us...@myfaces.apache.org>; Mark Struberg <
>> struberg@yahoo.de>
>> >Cc: "users@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 <st...@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." <sm...@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
>> >>> <rm...@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. <sm...@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
>> >>>>  >
>> >>>>
>> >>>
>> >>
>> >
>> >
>> >
>>
>
>

Re: Migrating to CDI: @Asynchronous

Posted by "Howard W. Smith, Jr." <sm...@gmail.com>.
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 <st...@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." <sm...@gmail.com>
> >To: MyFaces Discussion <us...@myfaces.apache.org>; Mark Struberg <
> struberg@yahoo.de>
> >Cc: "users@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 <st...@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." <sm...@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
> >>> <rm...@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. <sm...@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
> >>>>  >
> >>>>
> >>>
> >>
> >
> >
> >
>

Re: Migrating to CDI: @Asynchronous

Posted by "Howard W. Smith, Jr." <sm...@gmail.com>.
Also, my persistence.xml has the following:

<persistence version="2.0"
             xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="mcmsPU" transaction-type="JTA">

<!--<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>-->
      <provider>org.batoo.jpa.core.BatooPersistenceProvider</provider>
      <jta-data-source>jdbc/mcms</jta-data-source>
      <exclude-unlisted-classes>false</exclude-unlisted-classes>
      <properties/>
  </persistence-unit>
</persistence>


On Tue, Nov 20, 2012 at 11:50 AM, Howard W. Smith, Jr. <
smithh032772@gmail.com> wrote:

> Thomas,
>
> I'm trying to use batoo-jpa now, but the dependencies include transaction
> JAR that may be 'ignored' by TomEE container. Everytime I start TomEE (or
> deploy to app from NetBeans 7.2), the following shows up in my server log:
>
>
> Nov 20, 2012 11:44:43 AM
> org.apache.tomee.catalina.TomEEClassLoaderEnricher validateJarFile
> WARNING: jar
> 'C:\Users\Public\NetBeansProjects\mcms\build\web\WEB-INF\lib\transaction-api-1.1.jar'
> contains offending class: javax.transaction.Transaction. It will be ignored.
>
> Also, there are so many dependencies for batoo-jpa. Still trying...
>
>
> On Tue, Nov 20, 2012 at 10:43 AM, Thomas Andraschko <
> andraschko.thomas@gmail.com> wrote:
>
>> Sorry for the off topic, but if you think that your biggest bottleneck is
>> in your data-layer, you should give batoo jpa a try ;)
>>
>> 2012/11/20 Howard W. Smith, Jr. <sm...@gmail.com>
>>
>> > Well, you and others 'sold' me onto TomEE, so here I am. If I can get
>> this
>> > migration to TomEE and CDI complete, and my endusers are happy, then
>> more
>> > than likely, I will remain TomEE (supporter and user) for life, and will
>> > not plan to return to Glassfish. :)
>> >
>> > In production, my (PrimeFaces 3.4.1) app is running so fast with
>> Glassfish
>> > 3.1.2.2 and MyFaces Core 2.1.9, and JUEL (on an old Windows Server 2003
>> > Dell server), so I hope TomEE and CDI will beat out the performance I
>> > currently have in production, and I'm positive that it will...since
>> > OpenWebBeans is fast (like you said in one of your blogs/posts). :)
>> >
>> > Since I started using TomEE, it seems as though you all recommend
>> HSQLDB;
>> > I'm currently using 'Apache' Derby and that's working great, but I saw
>> some
>> > benchmark tests that OpenJPA and HSQLDB performs much better than
>> > OpenJPA/Derby and EclipseLink/Derby. Right now, I'm using EclipseLink. I
>> > may look into migrating from Derby to HSQL when I have plenty of time
>> to do
>> > so, but I rather do more fun 'java' programming than SQL programming
>> right
>> > now. I'm sure you can understand that. I think the biggest bottleneck
>> in my
>> > app is the database and probably the machine it's running on. And trust
>> me,
>> > I've read how to tune Derby for performance and I think I did all I
>> could
>> > to tune my Derby database. :)
>> >
>> > Wow, interesting. Thanks for sharing that about CDI events. It's funny
>> that
>> > you said that CDI events != messages. :)
>> >
>> > I need to study the CDI tutorials and blogs a bit, so I can learn how to
>> > use CDI events. I really would like to use it whereever
>> > possible/applicable. :)
>> >
>> >
>> >
>> > On Tue, Nov 20, 2012 at 10:18 AM, Mark Struberg <st...@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." <sm...@gmail.com>
>> > > >To: MyFaces Discussion <us...@myfaces.apache.org>; Mark Struberg <
>> > > struberg@yahoo.de>
>> > > >Cc: "users@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 <st...@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." <sm...@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
>> > > >>> <rm...@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. <sm...@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
>> > > >>>>  >
>> > > >>>>
>> > > >>>
>> > > >>
>> > > >
>> > > >
>> > > >
>> > >
>> >
>>
>
>

Re: Migrating to CDI: @Asynchronous

Posted by "Howard W. Smith, Jr." <sm...@gmail.com>.
Thomas,

I'm trying to use batoo-jpa now, but the dependencies include transaction
JAR that may be 'ignored' by TomEE container. Everytime I start TomEE (or
deploy to app from NetBeans 7.2), the following shows up in my server log:


Nov 20, 2012 11:44:43 AM org.apache.tomee.catalina.TomEEClassLoaderEnricher
validateJarFile
WARNING: jar
'C:\Users\Public\NetBeansProjects\mcms\build\web\WEB-INF\lib\transaction-api-1.1.jar'
contains offending class: javax.transaction.Transaction. It will be ignored.

Also, there are so many dependencies for batoo-jpa. Still trying...


On Tue, Nov 20, 2012 at 10:43 AM, Thomas Andraschko <
andraschko.thomas@gmail.com> wrote:

> Sorry for the off topic, but if you think that your biggest bottleneck is
> in your data-layer, you should give batoo jpa a try ;)
>
> 2012/11/20 Howard W. Smith, Jr. <sm...@gmail.com>
>
> > Well, you and others 'sold' me onto TomEE, so here I am. If I can get
> this
> > migration to TomEE and CDI complete, and my endusers are happy, then more
> > than likely, I will remain TomEE (supporter and user) for life, and will
> > not plan to return to Glassfish. :)
> >
> > In production, my (PrimeFaces 3.4.1) app is running so fast with
> Glassfish
> > 3.1.2.2 and MyFaces Core 2.1.9, and JUEL (on an old Windows Server 2003
> > Dell server), so I hope TomEE and CDI will beat out the performance I
> > currently have in production, and I'm positive that it will...since
> > OpenWebBeans is fast (like you said in one of your blogs/posts). :)
> >
> > Since I started using TomEE, it seems as though you all recommend HSQLDB;
> > I'm currently using 'Apache' Derby and that's working great, but I saw
> some
> > benchmark tests that OpenJPA and HSQLDB performs much better than
> > OpenJPA/Derby and EclipseLink/Derby. Right now, I'm using EclipseLink. I
> > may look into migrating from Derby to HSQL when I have plenty of time to
> do
> > so, but I rather do more fun 'java' programming than SQL programming
> right
> > now. I'm sure you can understand that. I think the biggest bottleneck in
> my
> > app is the database and probably the machine it's running on. And trust
> me,
> > I've read how to tune Derby for performance and I think I did all I could
> > to tune my Derby database. :)
> >
> > Wow, interesting. Thanks for sharing that about CDI events. It's funny
> that
> > you said that CDI events != messages. :)
> >
> > I need to study the CDI tutorials and blogs a bit, so I can learn how to
> > use CDI events. I really would like to use it whereever
> > possible/applicable. :)
> >
> >
> >
> > On Tue, Nov 20, 2012 at 10:18 AM, Mark Struberg <st...@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." <sm...@gmail.com>
> > > >To: MyFaces Discussion <us...@myfaces.apache.org>; Mark Struberg <
> > > struberg@yahoo.de>
> > > >Cc: "users@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 <st...@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." <sm...@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
> > > >>> <rm...@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. <sm...@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
> > > >>>>  >
> > > >>>>
> > > >>>
> > > >>
> > > >
> > > >
> > > >
> > >
> >
>

Re: Migrating to CDI: @Asynchronous

Posted by Thomas Andraschko <an...@gmail.com>.
Sorry for the off topic, but if you think that your biggest bottleneck is
in your data-layer, you should give batoo jpa a try ;)

2012/11/20 Howard W. Smith, Jr. <sm...@gmail.com>

> Well, you and others 'sold' me onto TomEE, so here I am. If I can get this
> migration to TomEE and CDI complete, and my endusers are happy, then more
> than likely, I will remain TomEE (supporter and user) for life, and will
> not plan to return to Glassfish. :)
>
> In production, my (PrimeFaces 3.4.1) app is running so fast with Glassfish
> 3.1.2.2 and MyFaces Core 2.1.9, and JUEL (on an old Windows Server 2003
> Dell server), so I hope TomEE and CDI will beat out the performance I
> currently have in production, and I'm positive that it will...since
> OpenWebBeans is fast (like you said in one of your blogs/posts). :)
>
> Since I started using TomEE, it seems as though you all recommend HSQLDB;
> I'm currently using 'Apache' Derby and that's working great, but I saw some
> benchmark tests that OpenJPA and HSQLDB performs much better than
> OpenJPA/Derby and EclipseLink/Derby. Right now, I'm using EclipseLink. I
> may look into migrating from Derby to HSQL when I have plenty of time to do
> so, but I rather do more fun 'java' programming than SQL programming right
> now. I'm sure you can understand that. I think the biggest bottleneck in my
> app is the database and probably the machine it's running on. And trust me,
> I've read how to tune Derby for performance and I think I did all I could
> to tune my Derby database. :)
>
> Wow, interesting. Thanks for sharing that about CDI events. It's funny that
> you said that CDI events != messages. :)
>
> I need to study the CDI tutorials and blogs a bit, so I can learn how to
> use CDI events. I really would like to use it whereever
> possible/applicable. :)
>
>
>
> On Tue, Nov 20, 2012 at 10:18 AM, Mark Struberg <st...@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." <sm...@gmail.com>
> > >To: MyFaces Discussion <us...@myfaces.apache.org>; Mark Struberg <
> > struberg@yahoo.de>
> > >Cc: "users@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 <st...@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." <sm...@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
> > >>> <rm...@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. <sm...@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
> > >>>>  >
> > >>>>
> > >>>
> > >>
> > >
> > >
> > >
> >
>

Re: Migrating to CDI: @Asynchronous

Posted by "Howard W. Smith, Jr." <sm...@gmail.com>.
Well, you and others 'sold' me onto TomEE, so here I am. If I can get this
migration to TomEE and CDI complete, and my endusers are happy, then more
than likely, I will remain TomEE (supporter and user) for life, and will
not plan to return to Glassfish. :)

In production, my (PrimeFaces 3.4.1) app is running so fast with Glassfish
3.1.2.2 and MyFaces Core 2.1.9, and JUEL (on an old Windows Server 2003
Dell server), so I hope TomEE and CDI will beat out the performance I
currently have in production, and I'm positive that it will...since
OpenWebBeans is fast (like you said in one of your blogs/posts). :)

Since I started using TomEE, it seems as though you all recommend HSQLDB;
I'm currently using 'Apache' Derby and that's working great, but I saw some
benchmark tests that OpenJPA and HSQLDB performs much better than
OpenJPA/Derby and EclipseLink/Derby. Right now, I'm using EclipseLink. I
may look into migrating from Derby to HSQL when I have plenty of time to do
so, but I rather do more fun 'java' programming than SQL programming right
now. I'm sure you can understand that. I think the biggest bottleneck in my
app is the database and probably the machine it's running on. And trust me,
I've read how to tune Derby for performance and I think I did all I could
to tune my Derby database. :)

Wow, interesting. Thanks for sharing that about CDI events. It's funny that
you said that CDI events != messages. :)

I need to study the CDI tutorials and blogs a bit, so I can learn how to
use CDI events. I really would like to use it whereever
possible/applicable. :)



On Tue, Nov 20, 2012 at 10:18 AM, Mark Struberg <st...@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." <sm...@gmail.com>
> >To: MyFaces Discussion <us...@myfaces.apache.org>; Mark Struberg <
> struberg@yahoo.de>
> >Cc: "users@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 <st...@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." <sm...@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
> >>> <rm...@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. <sm...@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
> >>>>  >
> >>>>
> >>>
> >>
> >
> >
> >
>

Re: Migrating to CDI: @Asynchronous

Posted by Mark Struberg <st...@yahoo.de>.
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." <sm...@gmail.com>
>To: MyFaces Discussion <us...@myfaces.apache.org>; Mark Struberg <st...@yahoo.de> 
>Cc: "users@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 <st...@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." <sm...@gmail.com>
>>> To: users@openejb.apache.org; MyFaces Discussion <us...@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
>>> <rm...@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. <sm...@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
>>>>  >
>>>>
>>>
>>
>
>
>

Re: Migrating to CDI: @Asynchronous

Posted by "Howard W. Smith, Jr." <sm...@gmail.com>.
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 <st...@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." <sm...@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
> > <rm...@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. <sm...@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
> >>  >
> >>
> >
>

Re: Migrating to CDI: @Asynchronous

Posted by "Howard W. Smith, Jr." <sm...@gmail.com>.
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 <st...@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 <st...@yahoo.de>
> > To: MyFaces Discussion <us...@myfaces.apache.org>; "
> users@openejb.apache.org" <us...@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." <sm...@gmail.com>
> >>  To: users@openejb.apache.org; MyFaces Discussion
> > <us...@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
> >>  <rm...@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. <sm...@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
> >>>   >
> >>>
> >>
> >
>

Re: Migrating to CDI: @Asynchronous

Posted by "Howard W. Smith, Jr." <sm...@gmail.com>.
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 <st...@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 <st...@yahoo.de>
> > To: MyFaces Discussion <us...@myfaces.apache.org>; "
> users@openejb.apache.org" <us...@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." <sm...@gmail.com>
> >>  To: users@openejb.apache.org; MyFaces Discussion
> > <us...@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
> >>  <rm...@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. <sm...@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
> >>>   >
> >>>
> >>
> >
>

Re: Migrating to CDI: @Asynchronous

Posted by Mark Struberg <st...@yahoo.de>.
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 <st...@yahoo.de>
> To: MyFaces Discussion <us...@myfaces.apache.org>; "users@openejb.apache.org" <us...@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." <sm...@gmail.com>
>>  To: users@openejb.apache.org; MyFaces Discussion 
> <us...@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
>>  <rm...@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. <sm...@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
>>>   >
>>> 
>> 
> 

Re: Migrating to CDI: @Asynchronous

Posted by "Howard W. Smith, Jr." <sm...@gmail.com>.
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 <st...@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." <sm...@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
> > <rm...@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. <sm...@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
> >>  >
> >>
> >
>

Re: Migrating to CDI: @Asynchronous

Posted by Mark Struberg <st...@yahoo.de>.
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 <st...@yahoo.de>
> To: MyFaces Discussion <us...@myfaces.apache.org>; "users@openejb.apache.org" <us...@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." <sm...@gmail.com>
>>  To: users@openejb.apache.org; MyFaces Discussion 
> <us...@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
>>  <rm...@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. <sm...@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
>>>   >
>>> 
>> 
> 

Re: Migrating to CDI: @Asynchronous

Posted by Mark Struberg <st...@yahoo.de>.
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." <sm...@gmail.com>
> To: users@openejb.apache.org; MyFaces Discussion <us...@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
> <rm...@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. <sm...@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
>>  >
>> 
> 

Re: Migrating to CDI: @Asynchronous

Posted by Mark Struberg <st...@yahoo.de>.
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." <sm...@gmail.com>
> To: users@openejb.apache.org; MyFaces Discussion <us...@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
> <rm...@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. <sm...@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
>>  >
>> 
>