tomee-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Randy Tidd <randy...@tidd.cc>
Subject Re: "Unit" testing with OpenEJB / TomEE and JSF, need FacesContext
Date Tue, 03 Feb 2015 20:01:42 GMT
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" <randy_fi@tidd.cc> 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 <randy_fi@tidd.cc>:
>>>> 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
>>>> 
>>>> 
>>>> 
>> 
>> 


Mime
View raw message