well in embedded mode the javaagent on the JVM (and no other solution) should be fine. That said I saw surprises on java 8 even with this and sometimes you can just enhance at build time - was not on eclipselinks so maybe this doesnt apply.
What can happen is you dont reuse javaagent classes cause eclipselink is in a lower classloader, maybe try to force the classloader to skip eclipselink classes when using the javaagent Romain Manni-Bucau @rmannibucau http://www.tomitribe.com http://rmannibucau.wordpress.com https://github.com/rmannibucau 2015-02-03 21:01 GMT+01:00 Randy Tidd <[email protected]>: > Romain, > > Thanks again for the help. However one more follow-up question... > > I am using EclipseLink. As I'm sure you know (but for the benefit of other > readers), EclipseLink needs either dynamic or static "weaving" of entity > classes to be supported in order to provide lazy loading of some > relationships. We deploy to Glassfish which evidently supports dynamic > weaving automatically and we rely on lazy loading for good performance. I > want to replicate this behavior as closely as possible in my unit tests, > which use embedded TomEE. > > How can I configure embedded TomEE / OpenEJB to provide dynamic weaving? I > tried adding the eclipselink jar as the javaagent in the unit test > configuration and then adding these properties: > > props.put("eclipselink.weaving", "dynamic"); > props.put("eclipselink.weaving.lazy", "true"); > props.put("eclipselink.weaving.internal", "true"); > > container = EJBContainer.createEJBContainer(props); > > When I run it I can see in the log messages that it is using weaving: > > [EL Finest]: > ServerSession(66487094)--Thread(Thread[main,5,main])--property=eclipselink.weaving.changetracking; > default value=true > [EL Finest]: > ServerSession(66487094)--Thread(Thread[main,5,main])--property=eclipselink.weaving.lazy; > value=true > [EL Finest]: > ServerSession(66487094)--Thread(Thread[main,5,main])--property=eclipselink.weaving.eager; > default value=false > [EL Finest]: > ServerSession(66487094)--Thread(Thread[main,5,main])--property=eclipselink.weaving.fetchgroups; > default value=true > [EL Finest]: > ServerSession(66487094)--Thread(Thread[main,5,main])--property=eclipselink.weaving.internal; > value=true > > and > > [EL Finer]: ServerSession(66487094)--Thread(Thread[main,5,main])--Class > [com.xxx.RequestForClassPublic] registered to be processed by weaver. > > But on the first query, I get this error: > > SEVERE: EjbTransactionUtil.handleSystemException: > com.xxx.AbstractModifiableEntity.<init>(Lorg/eclipse/persistence/internal/descriptors/PersistenceObject;)V > java.lang.NoSuchMethodError: > com.xxx.AbstractModifiableEntity.<init>(Lorg/eclipse/persistence/internal/descriptors/PersistenceObject;)V > at com.xxx.RequestForClassPublic.<init>(RequestForClassPublic.java) > at > com.xxx.RequestForClassPublic._persistence_new(RequestForClassPublic.java) > at > org.eclipse.persistence.internal.descriptors.PersistenceObjectInstantiationPolicy.buildNewInstance(PersistenceObjectInstantiationPolicy.java:30) > at > org.eclipse.persistence.descriptors.ClassDescriptor.selfValidationAfterInitialization(ClassDescriptor.java:3870) > at > org.eclipse.persistence.descriptors.ClassDescriptor.validateAfterInitialization(ClassDescriptor.java:5688) > at > org.eclipse.persistence.descriptors.ClassDescriptor.postInitialize(ClassDescriptor.java:3547) > at > org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:526) > at > org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:476) > at > org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:435) > at > org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:676) > at > org.eclipse.persistence.internal.sessions.DatabaseSessionImpl.login(DatabaseSessionImpl.java:634) > at > org.eclipse.persistence.internal.jpa.EntityManagerFactoryDelegate.createEntityManagerImpl(EntityManagerFactoryDelegate.java:284) > at > org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManagerImpl(EntityManagerFactoryImpl.java:294) > at > org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:279) > at > org.apache.openejb.assembler.classic.ReloadableEntityManagerFactory.createEntityManager(ReloadableEntityManagerFactory.java:162) > at > org.apache.openejb.persistence.JtaEntityManagerRegistry.getEntityManager(JtaEntityManagerRegistry.java:119) > at > org.apache.openejb.persistence.JtaEntityManager.getEntityManager(JtaEntityManager.java:96) > at > org.apache.openejb.persistence.JtaEntityManager.proxyIfNoTx(JtaEntityManager.java:326) > at > org.apache.openejb.persistence.JtaEntityManager.createQuery(JtaEntityManager.java:280) > > Our entity classes such as RequestForClassPublic inherit from an abstract > superclass AbstractModifiableEntity. It seems that EclipseLink can't find the > default constructor, which is there in both classes, and works when weaving > is not enabled. > > I realize that this might be more of an EclipseLink question than a TomEE > question but I'd appreciate any info. > > Thanks, > Randy > > On Jan 28, 2015, at 6:41 PM, Romain Manni-Bucau wrote: > >> Both would work. >> >> arquillian-tomee-remote or arquillian-tomee-embedded artifact are our >> arquillian integrations. >> >> Without you need some custome code glue, not sure it is the best to go >> while tomee 2 is not released. >> Le 29 janv. 2015 00:32, "Randy Tidd" <[email protected]> a écrit : >> >>> Romain, >>> >>> Thank you for your reply this was helpful. Switching from "openejb-core" >>> to "tomee-embedded" has fixed the problem of the missing javaee >>> implementations, I am now able to mock the FacesContext and other JSF >>> resources for the unit tests, and the glassfish-embeded package was not >>> needed. >>> >>> I wonder if I can ask a follow up question. I would like to inject my JSF >>> beans and EJB's into my unit test class, so they will all be managed by >>> TomEE. Trying this: >>> >>> @ManagedBean >>> @ViewScoped >>> public abstract class FooBean ... >>> >>> ... >>> >>> @Inject >>> FooBean fooBean; >>> >>> I get: >>> >>> Caused by: javax.enterprise.inject.UnsatisfiedResolutionException: Api >>> type [...FooBean] is not found with the qualifiers >>> Qualifiers: [@javax.enterprise.inject.Default()] >>> >>> I see toolkits like Arquillian which are intended to support this, I am >>> looking for information on if or how this works with TomEE or if TomEE can >>> handle this without Arquillian, again any info appreciated. >>> >>> Randy >>> >>> On Jan 28, 2015, at 10:24 AM, Romain Manni-Bucau wrote: >>> >>>> Hi >>>> >>>> Several points (without any order) >>>> 1) javax:javaee-api:6.0 is broken don't use it for any run >>>> (org.apache.openejb:javaee-api + myfaces-api can replace it) >>>> 2) before InvalidApplicationException the error is logged and that's >>>> what will help you to solve the issue, this exception is just here to >>>> make the deployment failing >>>> 3) openejb 2 will be able to run jsf in embedded mode (we use it for cdi >>> tck) >>>> 4) tomee 1.x can already do it using tomee-embedded instead of openejb >>>> 5) don't know that much your solution but maybe you just miss >>>> myfaces-api, myfaces-impl, tomcat-jasper, tomcat-jasper-el, >>>> openejb-jstl dependencies. (check here adapting your versions >>>> >>> https://git-wip-us.apache.org/repos/asf?p=tomee.git;a=blob;f=tck/cdi-embedded/pom.xml;h=d33af5dc0cef62b93f3e46a41d4c776befd50ed8;hb=21ad55b9f9e07c638ab53a6abc5451c680c29ba7 >>> ) >>>> >>>> Hope it gives you few pointers >>>> >>>> >>>> Romain Manni-Bucau >>>> @rmannibucau >>>> http://www.tomitribe.com >>>> http://rmannibucau.wordpress.com >>>> https://github.com/rmannibucau >>>> >>>> >>>> 2015-01-28 16:17 GMT+01:00 Randy Tidd <[email protected]>: >>>>> I set up some "unit" tests (really integration tests) using embedded >>> OpenEJB with this: >>>>> >>>>> <dependency> >>>>> <groupId>org.apache.openejb</groupId> >>>>> <artifactId>openejb-core</artifactId> >>>>> <version>4.7.1</version> >>>>> <scope>test</scope> >>>>> </dependency> >>>>> >>>>> I am able to call my EJB methods which use JPA and this works great. >>>>> >>>>> My app is J2EE deployed to Glassfish and I would like to expand the >>> unit testing to the JSF managed bean classes. I am able to invoke methods >>> on those beans with the same setup. However, those beans reference >>> FacesContext with calls like this: >>>>> >>>>> Principal principal = >>> FacesContext.getCurrentInstance().getExternalContext().getUserPrincipal(); >>>>> >>>>> This blows up with an exception because FacesContext is not available >>> in embedded OpenEJB. >>>>> >>>>> The FacesContext can be mocked with something like Mockito, but this >>> code does not run without a javaee implementation on the classpath, as >>> described here: >>>>> >>>>> >>> https://developer.jboss.org/wiki/WhatsTheCauseOfThisExceptionJavalangClassFormatErrorAbsentCode >>>>> >>>>> Essentially, including a Maven dependency like this: >>>>> >>>>> <dependency> >>>>> <groupId>javax</groupId> >>>>> <artifactId>javaee-api</artifactId> >>>>> <version>6.0</version> >>>>> <scope>provided</scope> >>>>> </dependency> >>>>> >>>>> Provides only the API's for the javaee classes which allows the code to >>> compile, but does not provide an implementation, so it can't run. When the >>> code runs inside a container like Glassfish, the implementation is there. >>> But when running as a unit test, there is no such implementation unless it >>> is explicitly added. >>>>> >>>>> I tried adding this: >>>>> >>>>> <dependency> >>>>> <groupId>org.glassfish.main.extras</groupId> >>>>> <artifactId>glassfish-embedded-all</artifactId> >>>>> <version>3.1.2.2</version> >>>>> <scope>test</scope> >>>>> </dependency> >>>>> >>>>> My understanding is that this is supposed to provide Glassfish classes >>> at runtime with test scope which is intended to address this problem. >>> However, when I run this with OpenEJB, I get this: >>>>> >>>>> org.apache.openejb.OpenEjbContainer$InvalidApplicationException: >>> org.apache.openejb.config.ValidationFailedException: Module failed >>> validation. AppModule(name=) >>>>> at >>> org.apache.openejb.OpenEjbContainer$Provider.createEJBContainer(OpenEjbContainer.java:320) >>>>> at >>> javax.ejb.embeddable.EJBContainer.createEJBContainer(EJBContainer.java:56) >>>>> at >>> com.aoi.aoiweb.ejb.RegistrarEjbTest.initialize(RegistrarEjbTest.java:71) >>>>> 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.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) >>>>> at >>> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) >>>>> at >>> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) >>>>> at >>> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24) >>>>> at >>> org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) >>>>> at org.junit.runners.ParentRunner.run(ParentRunner.java:309) >>>>> at >>> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) >>>>> at >>> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) >>>>> at >>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) >>>>> at >>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) >>>>> at >>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) >>>>> at >>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) >>>>> Caused by: org.apache.openejb.config.ValidationFailedException: Module >>> failed validation. AppModule(name=) >>>>> at >>> org.apache.openejb.config.ReportValidationResults.deploy(ReportValidationResults.java:88) >>>>> at >>> org.apache.openejb.config.AppInfoBuilder.build(AppInfoBuilder.java:309) >>>>> at >>> org.apache.openejb.config.ConfigurationFactory.configureApplication(ConfigurationFactory.java:965) >>>>> at >>> org.apache.openejb.OpenEjbContainer$Provider.createEJBContainer(OpenEjbContainer.java:314) >>>>> ... 18 more >>>>> >>>>> I suspect that the glassfish-embedded-all dependency is conflicting >>> with OpenEJB since they both attempt to provide the same classes and would >>> each be configured differently. >>>>> >>>>> So what I think I'm looking for is an "embedded TomEE" or a way to add >>> javaee implementation classes, or minimally FacesContext, to an embedded >>> OpenEJB. I have been searching around the docs and web sites and have not >>> found much to help, thanks in advance for any info. >>>>> >>>>> Randy >>>>> >>>>> >>>>> >>> >>> >
