[prev in list] [next in list] [prev in thread] [next in thread] 

List:       myfaces-user
Subject:    Re: Migrating to CDI: @Asynchronous
From:       "Howard W. Smith, Jr." <smithh032772 () gmail ! com>
Date:       2012-11-21 11:06:51
Message-ID: CAGV1rDK7ErLFqzdEdm0cj9kgTZoEDK26R4MkF0Ad+CwFj-L5UQ () mail ! gmail ! com
[Download RAW message or body]


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 <maxtorzito@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." <smithh032772@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 <struberg@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." <smithh032772@gmail.com>
> > > > > To: MyFaces Discussion <users@myfaces.apache.org>; Mark Struberg <
> > > > struberg@yahoo.de>
> > > > > Cc: "users@openejb.apache.org" <users@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 <struberg@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." <smithh032772@gmail.com>
> > > > > > > To: users@openejb.apache.org; MyFaces Discussion <
> > > > users@myfaces.apache.org>
> > > > > > > Cc:
> > > > > > > Sent: Tuesday, November 20, 2012 3:06 PM
> > > > > > > Subject: Re: Migrating to CDI: @Asynchronous
> > > > > > > 
> > > > > > > MyFaces Users,
> > > > > > > 
> > > > > > > Please read OP (or my original email below), and then read this
> > > > email, and
> > > > > > > advise.
> > > > > > > 
> > > > > > > Romain,
> > > > > > > 
> > > > > > > Yes, I have a code snippet; please continue reading beyond/below
> > > > first code
> > > > > > > snippet.
> > > > > > > 
> > > > > > > 
> > > > > > > Below is the code that is called by multiple beans as well as the
> > bean
> > > > > > > where this method is defined.
> > > > > > > 
> > > > > > > /*
> > > > > > > * Is it safe to start a new thread in a JSF managed bean?
> > > > > > > * Look at answers by BalusC and David Blevins
> > > > > > > *
> > > > > > > 
> > > > 
> > 
> http://stackoverflow.com/questions/6149919/is-it-safe-to-start-a-new-thread-in-a-jsf-managed-bean
> 
> > > > > > > *
> > > > > > > * Java EE 6 Tutorial Chapter 27 Using Asynchronous Method
> > > > Invocation
> > > > > > > in Session Beans
> > > > > > > * http://docs.oracle.com/javaee/6/tutorial/doc/gkkqg.html
> > > > > > > */
> > > > > > > @Asynchronous
> > > > > > > public Future<Date> updateGoogleCalendarPostEditAsync(Date
> > > > > > > tripDateToBePlacedInQueue) {
> > > > > > > 
> > > > > > > String log;
> > > > > > > 
> > > > > > > Date tripDate =
> > > > > > > 
> > > > 
> > 
> usersController.queueDateAndOrUpdateGoogleCalendar(tripDateToBePlacedInQueue);
> > > > > > > if (tripDate == null) {
> > > > > > > return new AsyncResult<>(tripDate);
> > > > > > > }
> > > > > > > 
> > > > > > > performingGoogleCalendarMaintenace = true;
> > > > > > > 
> > > > > > > try {
> > > > > > > 
> > > > > > > if (usersController.googleCalendarHasEvents()) {
> > > > > > > usersController.deleteEvents(tripDate, tripDate);
> > > > > > > }
> > > > > > > 
> > > > > > > String tripDateFrom =
> > > > displayUtil.getDateFromDateTime(tripDate,
> > > > > > > false);
> > > > > > > String tripDateTo =
> > > > displayUtil.getDateFromDateTime(tripDate,
> > > > > > > false);
> > > > > > > 
> > > > > > > List<Orders> list =
> > > > getFacade().findAllConfirmed(tripDateFrom,
> > > > > > > tripDateTo, true);
> > > > > > > 
> > > > > > > if (list != null) {
> > > > > > > for (Orders o : list) {
> > > > > > > 
> > > > > > > usersController.addEventToCalendar(newGoogleCalendarEvent(o));
> > > > > > > }
> > > > > > > }
> > > > > > > 
> > > > > > > log =
> > > > "pf_OrdersController.updateGoogleCalendarPostEditAsync():
> > > > > > > " +
> > > > > > > new DateTime(tripDate).toString("MM/dd/yyyy") +
> > > > > > > " processed successfully";
> > > > > > > } catch (Exception e) {
> > > > > > > e.printStackTrace();
> > > > > > > messages.addFormErrorMsg("Error updating Google
> > Calendar",
> > > > > > > (e.getMessage() != null) ? e.getMessage() : "");
> > > > > > > log =
> > > > "pf_OrdersController.updateGoogleCalendarPostEditAsync():
> > > > > > > " +
> > > > > > > new DateTime(tripDate).toString("MM/dd/yyyy") +
> > > > > > > " processing failed due to exception";
> > > > > > > } finally {
> > > > > > > performingGoogleCalendarMaintenace = false;
> > > > > > > }
> > > > > > > System.out.println(log);
> > > > > > > 
> > > > > > > // Return our result
> > > > > > > return new AsyncResult<>(tripDate);
> > > > > > > }
> > > > > > > 
> > > > > > > Below, is code where the @Asynchronous method is *called within
> the
> > > > same
> > > > > > > bean*, and is not the last piece of code in the calling method.
> > > > > > 
> > > > > > > 
> > > > > > > /*
> > > > > > > * 1. if tripDate changed, then update Google Calendar
> > for
> > > > > > > original trip date
> > > > > > > * 2. update Google Calendar for current trip date
> > > > > > > */
> > > > > > > if (new
> > > > > > > 
> DateTime(current.getReportDateTime()).toString("MM/dd/yyyy").equals(
> > > > > > > new
> > > > > > > DateTime(tripDateBeforeEdit).toString("MM/dd/yyyy"))
> > > > > > > == false) {
> > > > > > > 
> > updateGoogleCalendarPostEditAsync(tripDateBeforeEdit);
> > > > > > > }
> > > > > > > 
> > > > updateGoogleCalendarPostEditAsync(current.getReportDateTime());
> > > > > > > }
> > > > > > > if (invokePrepareEdit)
> > > > > > > return prepareEdit();
> > > > > > > else
> > > > > > > return null;
> > > > > > > 
> > > > > > > Below, is code that is at the very end of a calling method and
> > *called
> > > > > > > within the same bean*, so there are no concerns here.
> > > > > > 
> > > > > > > 
> > > > > > > /*
> > > > > > > * update Google Calendar for current trip date
> > > > > > > */
> > > > > > > 
> > > > updateGoogleCalendarPostEditAsync(current.getReportDateTime());
> > > > > > > return returnToBrowseOrView();
> > > > > > > 
> > > > > > > 
> > > > > > > Below, is code that was *added to another bean*, that will call
> the
> > > > > > > *@Asynchronous
> > > > > > > method defined on the other bean* (ordersController).
> > > > > > 
> > > > > > > 
> > > > > > > public void updateGoogleCalendar() {
> > > > > > > if (relatedEntityName.equals("orders")) {
> > > > > > > Orders order = (Orders) relatedEntityObj;
> > > > > > > 
> > > > > > > 
> > > > 
> > 
> ordersController.updateGoogleCalendarPostEditAsync(order.getTripDateTime());
> > > > > > > }
> > > > > > > }
> > > > > > > 
> > > > > > > The method above, updateGoogleCalendar(), is called by code
> similar
> > to
> > > > > > > below, which is not the last code executed in calling method.
> > > > > > > 
> > > > > > > if (relatedEntityName.equals("orders")) {
> > > > > > > auditTrailDesc = "Updated ORDER: updated ORIGIN" +
> > > > > > > (originTx != null &&
> > > > originTx.length()
> > > > > > > > 0
> > > > > > > ? "(" + originTx + ")" : "");
> > > > > > > 
> > > > > > > auditTrailController.createFromRelatedEntity(relatedEntityName,
> > > > > > > relatedEntityObj, auditTrailDesc);
> > > > > > > *// update Google Calendar*
> > > > > > > *updateGoogleCalendar();*
> > > > > > 
> > > > > > > }
> > > > > > > else if (relatedEntityName.equals("orderDriver")) {
> > > > > > > OrderDriver od = (OrderDriver) relatedEntityObj;
> > > > > > > OrderCostDetails orderCostDetails =
> > > > > > > od.getOrderCostDetails();
> > > > > > > Orders order = new
> > > > > > > ArrayList<>(orderCostDetails.getOrders()).get(0);
> > > > > > > auditTrailDesc = "updated ORIGIN" +
> > > > > > > 
> > > > > > > 
> > > > > > > 
> > > > > > > Thanks,
> > > > > > > Howard
> > > > > > > 
> > > > > > > 
> > > > > > > On Tue, Nov 20, 2012 at 2:25 AM, Romain Manni-Bucau
> > > > > > > <rmannibucau@gmail.com>wrote:
> > > > > > > 
> > > > > > > > Hi,
> > > > > > > > 
> > > > > > > > can you share any snippet of code?
> > > > > > > > 
> > > > > > > > *Romain Manni-Bucau*
> > > > > > > > *Twitter: @rmannibucau <https://twitter.com/rmannibucau>*
> > > > > > > > *Blog: **http://rmannibucau.wordpress.com/*<
> > > > > > > > http://rmannibucau.wordpress.com/>
> > > > > > > > *LinkedIn: **http://fr.linkedin.com/in/rmannibucau*
> > > > > > > > *Github: https://github.com/rmannibucau*
> > > > > > > > 
> > > > > > > > 
> > > > > > > > 
> > > > > > > > 
> > > > > > > > 2012/11/20 Howard W. Smith, Jr. <smithh032772@gmail.com>
> > > > > > > > 
> > > > > > > > > Prior to migrating from JSF managed to CDI (and currently in
> > > > > > > production),
> > > > > > > > > my web app is using @Asynchronous on @SessionScoped bean to
> push
> > > > data
> > > > > > > to
> > > > > > > > > and keep Google Calendar updated with specific data from the
> > > > database.
> > > > > > > > > 
> > > > > > > > > Honestly, I don't think I coded it correctly. What I mean by
> > that,
> > > > > > > I
> > > > > > > > don't
> > > > > > > > > think I'm handling or capturing the return value of
> > @Asynchronous
> > > > > > > > methods,
> > > > > > > > > and honestly, I don't know where execution is ending after
> some
> > or
> > > > > > > most
> > > > > > > > of
> > > > > > > > > the calls to @Asynchronous methods.
> > > > > > > > > 
> > > > > > > > > Currently, in production, the @Asynchronous method calls seem
> to
> > > > be
> > > > > > > > working
> > > > > > > > > fine (production = MyFaces Core 2.1.9, JSF managed beans,
> > > > Glassfish
> > > > > > > > > 3.1.2.2). Now that I'm migrating to TomEE/CDI, it seems as
> > though
> > > > > > > > > @Asynchronous is breaking my app; of course, I don't mind
> > > > > > > accepting
> > > > > > > > > responsibility and calling it a developer error. @Asynchronous
> > > > seems
> > > > > > > to
> > > > > > > > > result with the following error:
> > > > > > > > > 
> > > > > > > > > Target Unreachable, identifier resolved to null
> > > > > > > > > 
> > > > > > > > > I've read the following:
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > 
> > > > > > > 
> > > > 
> > 
> http://www.andrejkoelewijn.com/wp/2010/03/05/jee-cdi-tip-target-unreachable-identifier-resolved-to-null/
> 
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > 
> > > > > > > > 
> > > > > > > 
> > > > 
> > 
> http://stackoverflow.com/questions/4845041/target-unreachable-identifier-resolved-to-null
> 
> > > > > > > > > 
> > > > > > > > > but I have an empty beans.xml in WEB-INF and I have no JARs of
> > my
> > > > own
> > > > > > > (so
> > > > > > > > > no need to add beans.xml to META-INF, and please note, a lot
> of
> > > > the
> > > > > > > xhtml
> > > > > > > > > pages in the app are working as designed. Also, I read
> something
> > > > about
> > > > > > > > > cyclic references (below)
> > > > > > > > > 
> > > > > > > > > "injection points in one bean deployment archive cannot be
> > > > > > > satisfied by a
> > > > > > > > > bean in a separate bean archive, even when they are from
> > > > libraries in
> > > > > > > the
> > > > > > > > > same module (web
> > > > > > > > > archive)"<
> > > > > > > > > 
> > > > > > > > 
> > > > > > > 
> > > > 
> > 
> http://java.net/jira/browse/GLASSFISH-15721?focusedCommentId=301147&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#action_301147
> 
> > > > > > > > > > 
> > > > > > > > > 
> > > > > > > > > but I'm sure that is not the cause of the error that I'm
> > > > > > > experiencing.
> > > > > > > > > 
> > > > > > > > > So, would you all recommend me to consider CDI Events instead
> of
> > > > > > > > > @Asynchronous, both, or should I just fix @Asynchronous to
> work
> > > > in the
> > > > > > > > CDI
> > > > > > > > > app?
> > > > > > > > > 
> > > > > > > > > Thanks,
> > > > > > > > > Howard
> > > > > > > > > 
> > > > > > > > 
> > > > > > > 
> > > > > > 
> > > > > 
> > > > > 
> > > > > 
> > > > 
> > > 
> > > 
> > 
> 



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic