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 <strub...@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 <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 > >>> > > >>> > >> > > >