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