Re: Problems with load time enhancement and Spring's TomcatInstrumentableClassLoader
Thank you Harald, for adding some real good perspectives. > enhancement is a major nuisance in OpenJPA. It is, by user-(un)friendliness. It is not, by the value it adds to runtime. That enhancement is not user-friendly is our fault to get the ergonomics right. The internal process that really enhances the bytecodes is pretty solid. > I'm spending valuable time explaining to my team why this is needed, You may have known/told these but let me reiterate few strengths of build-time enhancement. Firstly, enhancement adds real value to runtime. Even if there are niggles/wrinkles or outright pain in enhancing, once that pain is gone, when the code finally runs in a production box -- the application runs faster. a) performance -- there is no proxying, no virtual point arithmetic, no extra overhead on the application objects -- which could be accessed trillion times in a process lifetime b) memory footprint -- no double copy of data c) if remote client can afford/allow OpenJPA runtime, a better merge() operation > Why should users have to learn about extra build steps when they could do > without? Given everything a persistent object goes through in its life, to mange it with transaction warranty and that too transparently from the user application -- a managed agent *must* be present -- it could be subclassing, it could be proxying, it could be source code generation, it could be bytecode enhancement. Bytecode enhancement is the most powerful and most performant. The other vendors who had taken strong position in the past against byte-code enhancement, had later used the same technique in one way or other. So the question to ask is: are we OK with suffering a development hiccup to build a better application? My experience tells me that a little effort to integrate build-time enhancement in this age of massive automatic build environments goes a long way. > The most manifest problem with build-time enhancment is that it makes > your entity JAR depend on OpenJPA. This is a no-go when you use (parts > of) your entity model with different JPA providers. This could be a hairy problem, but often solvable via configuration. Tell us more about the scope and isolation via classloaders and the domain itself via persistent units, then we can have a more concrete discussion. Thank you again for bringing some real good points. - Pinaki Poddar Chair, Apache OpenJPA Project -- View this message in context: http://openjpa.208410.n2.nabble.com/Problems-with-load-time-enhancement-and-Spring-s-TomcatInstrumentableClassLoader-tp6554347p6588167.html Sent from the OpenJPA Users mailing list archive at Nabble.com.
Re: Problems with load time enhancement and Spring's TomcatInstrumentableClassLoader
One minor factual quibble with the below. Hibernate does require build time enhancement in some situations. For example, if you have an entity with a Blob as a field, you have to use their javaassist based byte code enhancement to allow that Blob to be lazily loaded. On Fri, 2011-07-15 at 19:32 +0200, Harald Wellmann wrote: > Everyone I know who's moved from Hibernate to OpenJPA agrees that > enhancement is a major nuisance in OpenJPA. > > I'm spending valuable time explaining to my team why this is needed, > which of all the warning messages can be ignored and which are real > problems, and why we didn't simply stick with Hibernate (answer: because > Hibernate sucks on persistent maps). > > Enhancement is a violation of the KISS principle. Hibernate just works > out of the box, and you don't have to worry about enhancement or weaving > at all. > > I really think the onus is on OpenJPA: Why should users have to learn > about extra build steps when they could do without? > > The most manifest problem with build-time enhancment is that it makes > your entity JAR depend on OpenJPA. This is a no-go when you use (parts > of) your entity model with different JPA providers. > > > > > > Can you please elaborate why you did not prefer *build-time enhancement*? > > > > build-time enhancement is > > a) a simple post-compilation step > > Yes, but it makes your classes depend on OpenJPA. > > > b) easily integrable to any automated Ant/Maven based build environment > > This does not cover IDEs like Eclipse + Maven + m2e + WTP where any > postprocessing of class files just breaks the toolchain. > > > c) saves a ton of trouble > > Funny - enhancement is really the one major _source_ of trouble I've had > with OpenJPA since I started using it a year ago, and I'd really love to > see it disappear. > > > > > But it is not as popular as we would like it to be. > > I am just trying to understand why. > > > > Because it forces you to worry about things you don't want to know about. > > Deployment time enhancement at least works on Glassfish 3.1 or on OSGi > with Equinox 3.7 with Aries 0.4-SNAPSHOT, but then you still have to > worry about enhancement for out-of-container tests. > > And my project uses Spring and Tomcat (which are not so easy to get rid > of) where load time enhancement just doesn't work at all for some > reason, at least not with our fairly complex entity model. > > Best regards, > > Harald > > > >
Re: Problems with load time enhancement and Spring's TomcatInstrumentableClassLoader
Everyone I know who's moved from Hibernate to OpenJPA agrees that enhancement is a major nuisance in OpenJPA. I'm spending valuable time explaining to my team why this is needed, which of all the warning messages can be ignored and which are real problems, and why we didn't simply stick with Hibernate (answer: because Hibernate sucks on persistent maps). Enhancement is a violation of the KISS principle. Hibernate just works out of the box, and you don't have to worry about enhancement or weaving at all. I really think the onus is on OpenJPA: Why should users have to learn about extra build steps when they could do without? The most manifest problem with build-time enhancment is that it makes your entity JAR depend on OpenJPA. This is a no-go when you use (parts of) your entity model with different JPA providers. Can you please elaborate why you did not prefer *build-time enhancement*? build-time enhancement is a) a simple post-compilation step Yes, but it makes your classes depend on OpenJPA. b) easily integrable to any automated Ant/Maven based build environment This does not cover IDEs like Eclipse + Maven + m2e + WTP where any postprocessing of class files just breaks the toolchain. c) saves a ton of trouble Funny - enhancement is really the one major _source_ of trouble I've had with OpenJPA since I started using it a year ago, and I'd really love to see it disappear. But it is not as popular as we would like it to be. I am just trying to understand why. Because it forces you to worry about things you don't want to know about. Deployment time enhancement at least works on Glassfish 3.1 or on OSGi with Equinox 3.7 with Aries 0.4-SNAPSHOT, but then you still have to worry about enhancement for out-of-container tests. And my project uses Spring and Tomcat (which are not so easy to get rid of) where load time enhancement just doesn't work at all for some reason, at least not with our fairly complex entity model. Best regards, Harald
Re: Problems with load time enhancement and Spring's TomcatInstrumentableClassLoader
Hi Andrew, Your decision to opt for build-time enhancement is the right choice. The wrinkles around the mechanics of bytecode enhancement process is the responsibility of OpenJPA team. And we perhaps havn't done a good job of it from a usability point of view. Moreover, we have introduced several alternatives that can bypass bytecode enhancement at build time. However, these mechanics often carry forward edge errors that manifest as runtime errors and are difficult to track. Here are few suggestions. Please add our perspectives a) emphasize the import of bytecode enhancement at build time in our document. The XML b) make the mechanics more accessible -- they exist but are hard to find c) block or at least inhibit other modes such that the developer can do the right thing and not get tangled in a weave at runtime. - Pinaki Poddar Chair, Apache OpenJPA Project -- View this message in context: http://openjpa.208410.n2.nabble.com/Problems-with-load-time-enhancement-and-Spring-s-TomcatInstrumentableClassLoader-tp6554347p6577479.html Sent from the OpenJPA Users mailing list archive at Nabble.com.
Re: Problems with load time enhancement and Spring's TomcatInstrumentableClassLoader
Pinaki, The culprit in my case was maven/m2eclipse which by default executes the maven builder on every change. This wasn't an issue at all related to openjpa other then it was a required step within the build. While that default behavior can, and should, be modified. My experience was that it added confusion for developers who previously didn't have to know about byte code enhancement or even a maven build. -Andy On Tue, 2011-07-12 at 17:56 -0700, Pinaki Poddar wrote: > > even then that introduced a minute or two of build time in eclipse > How are you invoking build-time enhancement in Eclipse? > > > which without hackery insists on a full project build. > Who insists on a full project build on minor changes? > > - > Pinaki Poddar > Chair, Apache OpenJPA Project > -- > View this message in context: > http://openjpa.208410.n2.nabble.com/Problems-with-load-time-enhancement-and-Spring-s-TomcatInstrumentableClassLoader-tp6554347p6577376.html > Sent from the OpenJPA Users mailing list archive at Nabble.com.
Re: Problems with load time enhancement and Spring's TomcatInstrumentableClassLoader
> even then that introduced a minute or two of build time in eclipse How are you invoking build-time enhancement in Eclipse? > which without hackery insists on a full project build. Who insists on a full project build on minor changes? - Pinaki Poddar Chair, Apache OpenJPA Project -- View this message in context: http://openjpa.208410.n2.nabble.com/Problems-with-load-time-enhancement-and-Spring-s-TomcatInstrumentableClassLoader-tp6554347p6577376.html Sent from the OpenJPA Users mailing list archive at Nabble.com.
Re: Problems with load time enhancement and Spring's TomcatInstrumentableClassLoader
Just to answer from my own perspective. The spring docs imply that both solutions are worst case equal and guide the naive user towards the weaver. I found out with experimentation that build time was the way to go. But even then that introduced a minute or two of build time in eclipse for minor changes which without hackery insists on a full project build.Which is expensive across many builds per day across multiple developers. Which compared to hibernate is silly. Pinaki Poddar wrote: Hi, Following is from Rick's Spring reference [1] [1] http://static.springsource.org/spring/docs/2.0.x/reference/orm.html#orm-jpa-setup-lcemfb > When is load time weaving required? > > Not all JPA providers impose the need of a JVM agent (Hibernate being an > example). If your provider does not require an agent or you have other > alternatives (for example applying enhancements at build time through a > custom compiler or an ant task) the load time weaver *should not* be used. > Can you please elaborate why you did not prefer *build-time enhancement*? build-time enhancement is a) a simple post-compilation step b) easily integrable to any automated Ant/Maven based build environment c) saves a ton of trouble But it is not as popular as we would like it to be. I am just trying to understand why. - Pinaki -- View this message in context: http://openjpa.208410.n2.nabble.com/Problems-with-load-time-enhancement-and-Spring-s-TomcatInstrumentableClassLoader-tp6554347p6559761.html Sent from the OpenJPA Users mailing list archive at Nabble.com.
Re: Problems with load time enhancement and Spring's TomcatInstrumentableClassLoader
Hi, Following is from Rick's Spring reference [1] [1] http://static.springsource.org/spring/docs/2.0.x/reference/orm.html#orm-jpa-setup-lcemfb > When is load time weaving required? > > Not all JPA providers impose the need of a JVM agent (Hibernate being an > example). If your provider does not require an agent or you have other > alternatives (for example applying enhancements at build time through a > custom compiler or an ant task) the load time weaver *should not* be used. > Can you please elaborate why you did not prefer *build-time enhancement*? build-time enhancement is a) a simple post-compilation step b) easily integrable to any automated Ant/Maven based build environment c) saves a ton of trouble But it is not as popular as we would like it to be. I am just trying to understand why. - Pinaki -- View this message in context: http://openjpa.208410.n2.nabble.com/Problems-with-load-time-enhancement-and-Spring-s-TomcatInstrumentableClassLoader-tp6554347p6559761.html Sent from the OpenJPA Users mailing list archive at Nabble.com.
Re: Problems with load time enhancement and Spring's TomcatInstrumentableClassLoader
Yes, I read that more than once and double checked my configuration. I also posted in the Spring forum a while ago, with no replies so far. It would be helpful to have some background on the requirements for load time enhancement from the OpenJPA side. How does it normally work in a Java EE container? Does OpenJPA make any assumptions on which classloader is used for - OpenJPA itself - javax.persistence.* classes Should it be the container classloader or the application classloader? If I knew what OpenJPA expects, it would be easier to find out if and where the Spring/Tomcat environment is different and then address the issue to the resposible party - I spent a whole day on this issue and I'm really stuck at this point... Regards, Harald Original-Nachricht > Datum: Wed, 6 Jul 2011 08:46:22 -0500 > Von: Rick Curtis > An: users@openjpa.apache.org > Betreff: Re: Problems with load time enhancement and Spring\'s > TomcatInstrumentableClassLoader > Harold - > > Please take a read through the spring doc[1] to see if they address your > problem. > > [1] > http://static.springsource.org/spring/docs/2.0.x/reference/orm.html#orm-jpa-setup-lcemfb -- Empfehlen Sie GMX DSL Ihren Freunden und Bekannten und wir belohnen Sie mit bis zu 50,- Euro! https://freundschaftswerbung.gmx.de
Re: Problems with load time enhancement and Spring's TomcatInstrumentableClassLoader
Harold - Please take a read through the spring doc[1] to see if they address your problem. [1] http://static.springsource.org/spring/docs/2.0.x/reference/orm.html#orm-jpa-setup-lcemfb On Wed, Jul 6, 2011 at 8:25 AM, Harald Wellmann wrote: > I'm trying to use OpenJPA 2.1.0 with Spring 3.0.5 and Tomcat 6.0.32 and a > JPA 2.0 persistence unit configured by annotations. > > At first, the enhancer did not recognize any of my classes, which looks > like the same problem as described in > https://issues.apache.org/jira/browse/OPENJPA-1891. > > Then I moved the Geronimo JPA JAR from my WAR to Tomcat's lib folder as > described in this issue (but this feels wrong somehow). > > After that, the enhancer starts to do some work but then fails with an > exception which I don't really understand. > > It may be related to an inheritance chain in my entity model > > A -> B -> C > > where A is an Entity and B and C are MappedSuperclasses. > > Some trace output > > 8796 foo TRACE [main] openjpa.Enhance - Enhancing type "class com.A" > loaded by WebappClassLoader > context: /foo-web > delegate: false > repositories: >/WEB-INF/classes/ > --> Parent Classloader: > org.apache.catalina.loader.StandardClassLoader@a210b5b > . > 8808 foo TRACE [main] openjpa.Enhance - Enhancement for "com/A" > completed. Class size: [669/3.516] > 8809 foo TRACE [main] openjpa.Enhance - "com/B" requires runtime > enhancement: true > 209144 foo TRACE [main] openjpa.Enhance - Enhancing type "class com/B" > loaded by WebappClassLoader > context: /foo-web > delegate: false > repositories: >/WEB-INF/classes/ > --> Parent Classloader: > org.apache.catalina.loader.StandardClassLoader@a210b5b > . > 209170 foo TRACE [main] openjpa.Enhance - Enhancement for "com/B" > completed. Class size: [1.204/5.336] > 209008 foo WARN [main] openjpa.MetaData - The class "com.A" listed in > the openjpa.MetaDataFactory configuration property could not be loaded by > org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader > WebappClassLoader > context: /foo-web > delegate: false > repositories: >/WEB-INF/classes/ > --> Parent Classloader: > org.apache.catalina.loader.StandardClassLoader@a210b5b > ; ignoring. > 209008 foo TRACE [main] openjpa.MetaData - java.lang.NoSuchMethodError: > com.C.pcGetManagedFieldCount()I > java.lang.NoSuchMethodError: com.C.pcGetManagedFieldCount()I >at com.B.(B.java) >at java.lang.Class.forName0(Native Method) >at java.lang.Class.forName(Class.java:247) >at > org.apache.openjpa.meta.MetaDataRepository.classForName(MetaDataRepository.java:1552) >at > org.apache.openjpa.meta.MetaDataRepository.loadPersistentTypesInternal(MetaDataRepository.java:1528) >at > org.apache.openjpa.meta.MetaDataRepository.loadPersistentTypes(MetaDataRepository.java:1506) >at > org.apache.openjpa.kernel.AbstractBrokerFactory.loadPersistentTypes(AbstractBrokerFactory.java:283) >at > org.apache.openjpa.kernel.AbstractBrokerFactory.initializeBroker(AbstractBrokerFactory.java:239) >at > org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:213) >at > org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:156) >at > org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:227) >at > org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:154) >at > org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:60) >at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >at > sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) >at > sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) >at java.lang.reflect.Method.invoke(Method.java:597) >at > org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.invokeProxyMethod(AbstractEntityManagerFactoryBean.java:423) >at > org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(AbstractEntityManagerFactoryBean.java:485) >at $Proxy12.createEntityManager(Unknown Source) > > The missing method appears to be one added by the enhancer, but com.C has > not been enhanced yet. > > I was able to deploy the same unenhanced persistence unit on Glassfish > without problems, so there must be a problem on the interface between > OpenJPA, Spring and Tomcat. > > Any ideas anyone...? > > Thanks, > Harald > > - *Rick Curtis*