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