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